15#if defined(DEAL_II_WITH_ADOLC) || defined(DEAL_II_TRILINOS_WITH_SACADO)
20# include <type_traits>
28#if defined(DEAL_II_WITH_ADOLC) || defined(DEAL_II_TRILINOS_WITH_SACADO)
39 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
57 "Floating point/arithmetic numbers have no derivatives."));
61 "The AD number type does not support the calculation of any derivatives."));
81 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
93 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
105 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
108 const unsigned int index,
121 "Cannot change the value of an independent variable "
122 "of the tapeless variety while this class is not set "
123 "in recording operations."));
134 "Trying to set the value of a non-existent independent variable."));
142 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
145 const unsigned int index,
157 "Need to extract sensitivities in the order they're created."));
166 "The marking of independent variables is only valid "
167 "during recording."));
180 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
187 ExcMessage(
"Not all values of sensitivities have been recorded!"));
204 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
217 "The initialization of non-sensitive independent variables is "
218 "only valid outside of recording operations."));
229 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
241 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
250 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
262 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
271 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
283 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
296 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
309 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
314 const std::ios_base::fmtflags stream_flags(stream.flags());
316 stream.setf(std::ios_base::boolalpha);
320 stream << std::flush;
325 stream <<
"Registered independent variables: " <<
'\n';
331 stream <<
"Independent variable values: " <<
'\n';
334 stream <<
"Registered marked independent variables: " <<
'\n';
341 stream <<
"Dependent variable values: " <<
'\n';
347 stream <<
"Registered dependent variables: " <<
'\n';
354 stream.flags(stream_flags);
359 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
362 std::ostream &stream)
const
373 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
377 std::ostream &stream)
const
385 this->
taped_driver.print_tape_stats(tape_index, stream);
390 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
395 const bool clear_registered_tapes)
397 const unsigned int new_n_independent_variables =
400 this->n_independent_variables());
401 const unsigned int new_n_dependent_variables =
404 this->n_dependent_variables());
433 new_n_independent_variables,
436 std::vector<bool>(new_n_independent_variables,
false);
438 std::vector<bool>(new_n_independent_variables,
false);
440 std::vector<ad_type>(new_n_dependent_variables,
443 std::vector<bool>(new_n_dependent_variables,
false);
448 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
452 const bool ensure_persistent_setting)
461 if (ensure_persistent_setting ==
true)
474 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
484 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
497 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
510 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
522 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
526 const bool read_mode)
533 ExcMessage(
"Tape index exceeds maximum allowable value"));
540 if (read_mode ==
true)
547 ExcMessage(
"Not all dependent variables have been set!"));
559 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
578 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
582 const bool overwrite_tape,
583 const bool keep_independent_values)
586 const bool read_mode =
false;
590 if (overwrite_tape !=
true)
605 keep_independent_values);
616 "Tape recording is unexpectedly still enabled."));
625 Assert(ADNumberTraits<ad_type>::is_tapeless ==
true,
630 tapeless_driver.allow_dependent_variable_marking();
635 activate_tape(tape_index, read_mode);
638 return is_recording();
643 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
646 const bool write_tapes_to_file)
652 ExcMessage(
"Not all values of sensitivities have been recorded!"));
679 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
682 const unsigned int index,
688 "This dependent variable has already been registered."));
696 "Must be recording when registering dependent variables."));
702 registered_marked_dependent_variables[index] =
true;
711 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
721 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
724 const std::vector<scalar_type> &dof_values)
730 Assert(dof_values.size() == this->n_independent_variables(),
732 "Vector size does not match number of independent variables"));
733 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
736 ExcMessage(
"Independent variable value already registered."));
738 set_dof_values(dof_values);
743 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
760 this->n_independent_variables(),
762 this->n_independent_variables()));
769 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
772 const std::vector<scalar_type> &values)
780 Assert(values.size() == this->n_independent_variables(),
782 "Vector size does not match number of independent variables"));
783 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
794 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
802 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
814 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
819 this->
taped_driver.keep_independent_values() ==
false) ||
824 this->n_independent_variables(),
826 "Not all values of sensitivities have been registered or subsequently set!"));
830 ExcMessage(
"Not all dependent variables have been registered."));
835 "The EnergyFunctional class expects there to be only one dependent variable."));
844 "Cannot compute value while tape is being recorded."));
846 this->n_independent_variables(),
848 this->n_independent_variables()));
858 this->n_independent_variables(),
860 this->n_independent_variables()));
868 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
874 this->
taped_driver.keep_independent_values() ==
false) ||
879 this->n_independent_variables(),
881 "Not all values of sensitivities have been registered or subsequently set!"));
885 ExcMessage(
"Not all dependent variables have been registered."));
890 "The EnergyFunctional class expects there to be only one dependent variable."));
895 if (gradient.size() != this->n_independent_variables())
896 gradient.reinit(this->n_independent_variables(),
906 "Cannot compute gradient while tape is being recorded."));
908 this->n_independent_variables(),
910 this->n_independent_variables()));
920 Assert(this->independent_variables.size() ==
921 this->n_independent_variables(),
923 this->n_independent_variables()));
925 this->tapeless_driver.gradient(this->independent_variables,
926 this->dependent_variables,
933 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
940 "Cannot computed function Hessian: AD number type does "
941 "not support the calculation of second order derivatives."));
948 this->n_independent_variables(),
950 "Not all values of sensitivities have been registered or subsequently set!"));
952 Assert(this->n_registered_dependent_variables() ==
953 this->n_dependent_variables(),
954 ExcMessage(
"Not all dependent variables have been registered."));
957 this->n_dependent_variables() == 1,
959 "The EnergyFunctional class expects there to be only one dependent variable."));
964 if (hessian.m() != this->n_independent_variables() ||
965 hessian.n() != this->n_independent_variables())
966 hessian.reinit({this->n_independent_variables(),
967 this->n_independent_variables()},
970 if (ADNumberTraits<ad_type>::is_taped ==
true)
972 Assert(this->active_tape_index() !=
975 Assert(this->is_recording() ==
false,
977 "Cannot compute hessian while tape is being recorded."));
978 Assert(this->independent_variable_values.size() ==
979 this->n_independent_variables(),
981 this->n_independent_variables()));
991 Assert(this->independent_variables.size() ==
992 this->n_independent_variables(),
994 this->n_independent_variables()));
996 this->tapeless_driver.hessian(this->independent_variables,
997 this->dependent_variables,
1007 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1017 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1024 "Vector size does not match number of dependent variables"));
1032 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1038 this->
taped_driver.keep_independent_values() ==
false) ||
1043 this->n_independent_variables(),
1045 "Not all values of sensitivities have been registered or subsequently set!"));
1049 ExcMessage(
"Not all dependent variables have been registered."));
1054 if (values.size() != this->n_dependent_variables())
1065 "Cannot compute values while tape is being recorded."));
1067 this->n_independent_variables(),
1069 this->n_independent_variables()));
1086 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1092 this->
taped_driver.keep_independent_values() ==
false) ||
1097 this->n_independent_variables(),
1099 "Not all values of sensitivities have been registered or subsequently set!"));
1103 ExcMessage(
"Not all dependent variables have been registered."));
1108 if (jacobian.
m() != this->n_dependent_variables() ||
1109 jacobian.
n() != this->n_independent_variables())
1111 this->n_independent_variables()},
1121 "Cannot compute hessian while tape is being recorded."));
1123 this->n_independent_variables(),
1125 this->n_independent_variables()));
1137 this->n_independent_variables(),
1139 this->n_independent_variables()));
1155 typename ScalarType>
1168 typename ScalarType>
1173 const bool clear_registered_tapes)
1177 clear_registered_tapes);
1179 const unsigned int new_n_independent_variables =
1182 this->n_independent_variables());
1184 std::vector<bool>(new_n_independent_variables,
false);
1191 typename ScalarType>
1205 typename ScalarType>
1219 typename ScalarType>
1228 Assert(values.size() == this->n_independent_variables(),
1230 "Vector size does not match number of independent variables"));
1231 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
1234 ExcMessage(
"Independent variable value already registered."));
1243 typename ScalarType>
1246 ScalarType>::ad_type> &
1262 this->n_independent_variables(),
1264 this->n_independent_variables()));
1273 typename ScalarType>
1277 const bool symmetric_component,
1285 "Trying to set the symmetry flag of a non-existent independent variable."));
1295 typename ScalarType>
1306 Assert(values.size() == this->n_independent_variables(),
1308 "Vector size does not match number of independent variables"));
1309 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
1322 typename ScalarType>
1334 typename ScalarType>
1348 typename ScalarType>
1353 this->
taped_driver.keep_independent_values() ==
false) ||
1358 this->n_independent_variables(),
1360 "Not all values of sensitivities have been registered or subsequently set!"));
1364 ExcMessage(
"Not all dependent variables have been registered."));
1369 "The ScalarFunction class expects there to be only one dependent variable."));
1378 "Cannot compute values while tape is being recorded."));
1380 this->n_independent_variables(),
1382 this->n_independent_variables()));
1398 typename ScalarType>
1404 this->
taped_driver.keep_independent_values() ==
false) ||
1409 this->n_independent_variables(),
1411 "Not all values of sensitivities have been registered or subsequently set!"));
1415 ExcMessage(
"Not all dependent variables have been registered."));
1420 "The ScalarFunction class expects there to be only one dependent variable."));
1425 if (gradient.size() != this->n_independent_variables())
1426 gradient.reinit(this->n_independent_variables(),
1436 "Cannot compute gradient while tape is being recorded."));
1438 this->n_independent_variables(),
1440 this->n_independent_variables()));
1451 this->n_independent_variables(),
1453 this->n_independent_variables()));
1461 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
1472 typename ScalarType>
1479 "Cannot computed function Hessian: AD number type does "
1480 "not support the calculation of second order derivatives."));
1483 this->
taped_driver.keep_independent_values() ==
false))
1487 this->n_independent_variables(),
1489 "Not all values of sensitivities have been registered or subsequently set!"));
1493 ExcMessage(
"Not all dependent variables have been registered."));
1498 "The ScalarFunction class expects there to be only one dependent variable."));
1503 if (hessian.m() != this->n_independent_variables() ||
1504 hessian.n() != this->n_independent_variables())
1505 hessian.reinit({this->n_independent_variables(),
1506 this->n_independent_variables()},
1516 "Cannot compute Hessian while tape is being recorded."));
1518 this->n_independent_variables(),
1520 this->n_independent_variables()));
1531 this->n_independent_variables(),
1533 this->n_independent_variables()));
1541 for (
unsigned int i = 0; i < this->n_independent_variables(); ++i)
1542 for (
unsigned int j = 0; j < i + 1; ++j)
1547 hessian[i][j] *= 0.25;
1549 hessian[j][i] *= 0.25;
1556 hessian[i][j] *= 0.5;
1558 hessian[j][i] *= 0.5;
1567 typename ScalarType>
1586 const std::vector<unsigned int> row_index_set(
1588 const std::vector<unsigned int> col_index_set(
1595 hessian[row_index_set[0]][col_index_set[0]]);
1604 typename ScalarType>
1624 const std::vector<unsigned int> row_index_set(
1626 const std::vector<unsigned int> col_index_set(
1629 for (
unsigned int r = 0; r < row_index_set.size(); ++r)
1630 for (
unsigned int c = 0; c < col_index_set.size(); ++c)
1633 out, r, c, hessian[row_index_set[r]][col_index_set[c]]);
1647 typename ScalarType>
1660 typename ScalarType>
1665 Assert(funcs.size() == this->n_dependent_variables(),
1667 "Vector size does not match number of dependent variables"));
1677 typename ScalarType>
1683 this->
taped_driver.keep_independent_values() ==
false) ||
1688 this->n_independent_variables(),
1690 "Not all values of sensitivities have been registered or subsequently set!"));
1694 ExcMessage(
"Not all dependent variables have been registered."));
1699 if (values.size() != this->n_dependent_variables())
1710 "Cannot compute values while tape is being recorded."));
1712 this->n_independent_variables(),
1714 this->n_independent_variables()));
1733 typename ScalarType>
1739 this->
taped_driver.keep_independent_values() ==
false) ||
1744 this->n_independent_variables(),
1746 "Not all values of sensitivities have been registered or subsequently set!"));
1750 ExcMessage(
"Not all dependent variables have been registered."));
1755 if (jacobian.
m() != this->n_dependent_variables() ||
1756 jacobian.
n() != this->n_independent_variables())
1758 this->n_independent_variables()},
1768 "Cannot compute Jacobian while tape is being recorded."));
1770 this->n_independent_variables(),
1772 this->n_independent_variables()));
1784 this->n_independent_variables(),
1786 this->n_independent_variables()));
1793 for (
unsigned int j = 0; j < this->n_independent_variables(); ++j)
1800 jacobian[i][j] *= 0.5;
1808 typename ScalarType>
1828 const std::vector<unsigned int> row_index_set(
1830 const std::vector<unsigned int> col_index_set(
1837 jacobian[row_index_set[0]][col_index_set[0]]);
1846 typename ScalarType>
1866 const std::vector<unsigned int> row_index_set(
1868 const std::vector<unsigned int> col_index_set(
1871 for (
unsigned int r = 0; r < row_index_set.size(); ++r)
1872 for (
unsigned int c = 0; c < col_index_set.size(); ++c)
1875 out, r, c, jacobian[row_index_set[r]][col_index_set[c]]);
1887# include "differentiation/ad/ad_helpers.inst"
1889# ifdef DEAL_II_WITH_ADOLC
1890# include "differentiation/ad/ad_helpers.inst1"
1892# ifdef DEAL_II_TRILINOS_WITH_SACADO
1893# include "differentiation/ad/ad_helpers.inst2"
const std::vector< ad_type > & get_sensitive_dof_values() const
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)
void compute_residual(Vector< scalar_type > &residual) const override
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
virtual void compute_linearization(FullMatrix< scalar_type > &linearization) const override
scalar_type compute_energy() const
typename HelperBase< ADNumberTypeCode, ScalarType >::ad_type ad_type
unsigned int n_registered_dependent_variables() const
TapedDrivers< ad_type, scalar_type > taped_driver
void stop_recording_operations(const bool write_tapes_to_file=false)
std::vector< bool > registered_marked_independent_variables
std::vector< bool > registered_independent_variable_values
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)
std::vector< scalar_type > independent_variable_values
void reset_registered_independent_variables()
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
std::vector< bool > registered_marked_dependent_variables
void reset_registered_dependent_variables(const bool flag=false)
typename AD::NumberTraits< ScalarType, ADNumberTypeCode >::scalar_type scalar_type
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)
unsigned int n_registered_independent_variables() const
void print(std::ostream &stream) const
void set_sensitivity_value(const unsigned int index, const scalar_type &value)
bool active_tape_requires_retaping() const
std::vector< ad_type > independent_variables
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)
TapelessDrivers< ad_type, scalar_type > tapeless_driver
bool recorded_tape_requires_retaping(const typename Types< ad_type >::tape_index tape_index) const
typename AD::NumberTraits< ScalarType, ADNumberTypeCode >::ad_type ad_type
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)
void finalize_sensitive_independent_variables() const
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)
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
void set_independent_variables(const std::vector< scalar_type > &values)
std::vector< bool > symmetric_independent_variables
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)
void register_dependent_variable(const ad_type &func)
ScalarFunction(const unsigned int n_independent_variables)
void compute_gradient(Vector< scalar_type > &gradient) const
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
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)
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
void compute_jacobian(FullMatrix< scalar_type > &jacobian) const
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)
const bool IsBlockVector< VectorType >::value
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)
constexpr unsigned int invalid_unsigned_int
static const Types< ADNumberType >::tape_index max_tape_index
static const Types< ADNumberType >::tape_index invalid_tape_index
static void initialize_global_environment(const unsigned int n_independent_variables)
unsigned int tape_buffer_sizes
static constexpr const T & value(const T &t)