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>
84 for (
typename std::vector<bool>::iterator it =
93 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
98 for (
typename std::vector<bool>::iterator it =
107 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
110 const unsigned int index,
123 "Cannot change the value of an independent variable " 124 "of the tapeless variety while this class is not set" 125 "in recording operations."));
136 "Trying to set the value of a non-existent independent variable."));
144 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
147 const unsigned int index,
159 "Need to extract sensitivities in the order they're created."));
168 "The marking of independent variables is only valid " 169 "during recording."));
182 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
189 ExcMessage(
"Not all values of sensitivities have been recorded!"));
206 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
219 "The initialization of non-sensitive independent variables is " 220 "only valid outside of recording operations."));
231 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
243 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
252 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
264 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
273 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
285 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
298 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
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);
322 stream << std::flush;
327 stream <<
"Registered independent variables: " 334 stream <<
"Independent variable values: " 338 stream <<
"Registered marked independent variables: " 346 stream <<
"Dependent variable values: " 353 stream <<
"Registered dependent variables: " 361 stream.flags(stream_flags);
366 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
369 std::ostream &stream)
const 380 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
384 std::ostream & stream)
const 397 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
402 const bool clear_registered_tapes)
404 const unsigned int new_n_independent_variables =
405 (n_independent_variables != ::numbers::invalid_unsigned_int ?
408 const unsigned int new_n_dependent_variables =
409 (n_dependent_variables != ::numbers::invalid_unsigned_int ?
440 new_n_independent_variables,
443 std::vector<bool>(new_n_independent_variables,
false);
445 std::vector<bool>(new_n_independent_variables,
false);
447 std::vector<ad_type>(new_n_dependent_variables,
450 std::vector<bool>(new_n_dependent_variables,
false);
455 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
459 const bool ensure_persistent_setting)
466 n_independent_variables);
468 if (ensure_persistent_setting ==
true)
481 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
491 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
504 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
517 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
529 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
533 const bool read_mode)
540 ExcMessage(
"Tape index exceeds maximum allowable value"));
547 if (read_mode ==
true)
554 ExcMessage(
"Not all dependent variables have been set!"));
566 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
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)
612 keep_independent_values);
623 "Tape recording is unexpectedly still enabled."));
650 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
653 const bool write_tapes_to_file)
659 ExcMessage(
"Not all values of sensitivities have been recorded!"));
672 ExcMessage(
"Not all dependent variables have been set!"));
686 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
689 const unsigned int index,
695 "This dependent variable has already been registered."));
703 "Must be recording when registering dependent variables."));
718 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
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)
739 "Vector size does not match number of independent variables"));
743 ExcMessage(
"Independent variable value already registered."));
750 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
776 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
779 const std::vector<scalar_type> &values)
789 "Vector size does not match number of independent variables"));
801 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
804 :
CellLevelBase<ADNumberTypeCode, ScalarType>(n_independent_variables, 1)
809 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
821 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
833 "Not all values of sensitivities have been registered or subsequently set!"));
837 ExcMessage(
"Not all dependent variables have been registered."));
842 "The EnergyFunctional class expects there to be only one dependent variable."));
851 "Cannot compute value while tape is being recorded."));
875 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
878 Vector<scalar_type> &gradient)
const 888 "Not all values of sensitivities have been registered or subsequently set!"));
892 ExcMessage(
"Not all dependent variables have been registered."));
897 "The EnergyFunctional class expects there to be only one dependent variable."));
903 gradient.reinit(this->n_independent_variables(),
913 "Cannot compute gradient while tape is being recorded."));
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."));
957 "Not all values of sensitivities have been registered or subsequently set!"));
961 ExcMessage(
"Not all dependent variables have been registered."));
966 "The EnergyFunctional class expects there to be only one dependent variable."));
973 hessian.
reinit({this->n_independent_variables(),
974 this->n_independent_variables()},
984 "Cannot compute hessian while tape is being recorded."));
1014 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1018 :
CellLevelBase<ADNumberTypeCode, ScalarType>(n_independent_variables,
1019 n_dependent_variables)
1024 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1031 "Vector size does not match number of dependent variables"));
1039 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1042 Vector<scalar_type> &values)
const 1052 "Not all values of sensitivities have been registered or subsequently set!"));
1056 ExcMessage(
"Not all dependent variables have been registered."));
1062 values.reinit(this->n_dependent_variables(),
1072 "Cannot compute values while tape is being recorded."));
1093 template <enum AD::NumberTypes ADNumberTypeCode,
typename ScalarType>
1106 "Not all values of sensitivities have been registered or subsequently set!"));
1110 ExcMessage(
"Not all dependent variables have been registered."));
1117 jacobian.
reinit({this->n_dependent_variables(),
1118 this->n_independent_variables()},
1128 "Cannot compute hessian while tape is being recorded."));
1162 typename ScalarType>
1166 :
HelperBase<ADNumberTypeCode, ScalarType>(n_independent_variables,
1167 n_dependent_variables)
1168 , symmetric_independent_variables(n_independent_variables, false)
1175 typename ScalarType>
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 ?
1191 std::vector<bool>(new_n_independent_variables,
false);
1198 typename ScalarType>
1212 typename ScalarType>
1226 typename ScalarType>
1237 "Vector size does not match number of independent variables"));
1241 ExcMessage(
"Independent variable value already registered."));
1250 typename ScalarType>
1280 typename ScalarType>
1284 const bool symmetric_component,
1292 "Trying to set the symmetry flag of a non-existent independent variable."));
1302 typename ScalarType>
1315 "Vector size does not match number of independent variables"));
1329 typename ScalarType>
1333 n_independent_variables,
1341 typename ScalarType>
1355 typename ScalarType>
1367 "Not all values of sensitivities have been registered or subsequently set!"));
1371 ExcMessage(
"Not all dependent variables have been registered."));
1376 "The ScalarFunction class expects there to be only one dependent variable."));
1385 "Cannot compute values while tape is being recorded."));
1405 typename ScalarType>
1408 Vector<scalar_type> &gradient)
const 1418 "Not all values of sensitivities have been registered or subsequently set!"));
1422 ExcMessage(
"Not all dependent variables have been registered."));
1427 "The ScalarFunction class expects there to be only one dependent variable."));
1433 gradient.reinit(this->n_independent_variables(),
1443 "Cannot compute gradient while tape is being recorded."));
1479 typename ScalarType>
1486 "Cannot computed function Hessian: AD number type does" 1487 "not support the calculation of second order derivatives."));
1496 "Not all values of sensitivities have been registered or subsequently set!"));
1500 ExcMessage(
"Not all dependent variables have been registered."));
1505 "The ScalarFunction class expects there to be only one dependent variable."));
1512 hessian.
reinit({this->n_independent_variables(),
1513 this->n_independent_variables()},
1523 "Cannot compute Hessian while tape is being recorded."));
1549 for (
unsigned int j = 0; j < i + 1; j++)
1554 hessian[i][j] *= 0.25;
1556 hessian[j][i] *= 0.25;
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>
1659 n_independent_variables,
1660 n_dependent_variables)
1667 typename ScalarType>
1674 "Vector size does not match number of dependent variables"));
1684 typename ScalarType>
1687 Vector<scalar_type> &values)
const 1697 "Not all values of sensitivities have been registered or subsequently set!"));
1701 ExcMessage(
"Not all dependent variables have been registered."));
1707 values.reinit(this->n_dependent_variables(),
1717 "Cannot compute values while tape is being recorded."));
1740 typename ScalarType>
1753 "Not all values of sensitivities have been registered or subsequently set!"));
1757 ExcMessage(
"Not all dependent variables have been registered."));
1764 jacobian.
reinit({this->n_dependent_variables(),
1765 this->n_independent_variables()},
1775 "Cannot compute Jacobian while tape is being recorded."));
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) void values(const typename Types< ADNumberType >::tape_index active_tape_index, const unsigned int n_dependent_variables, const std::vector< ScalarType > &independent_variables, Vector< ScalarType > &values) const
TapedDrivers< ad_type, scalar_type > taped_driver
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)
void values(const std::vector< ADNumberType > &dependent_variables, Vector< ScalarType > &values) const
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)
Types< ADNumberType >::tape_index active_tape_index() const
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)
ScalarType value(const typename Types< ADNumberType >::tape_index active_tape_index, const std::vector< ScalarType > &independent_variables) const
void jacobian(const std::vector< ADNumberType > &independent_variables, const std::vector< ADNumberType > &dependent_variables, FullMatrix< ScalarType > &jacobian) const
const std::vector< ad_type > & get_sensitive_dof_values() const
unsigned int tape_buffer_sizes
void activate_tape(const typename Types< ADNumberType >::tape_index tape_index)
void register_dependent_variable(const ad_type &func)
void stop_recording_operations(const bool write_tapes_to_file=false)
bool is_dependent_variable_marking_allowed() const
void compute_gradient(Vector< scalar_type > &gradient) const
void jacobian(const typename Types< ADNumberType >::tape_index active_tape_index, const unsigned int n_dependent_variables, const std::vector< ScalarType > &independent_variables, FullMatrix< ScalarType > &jacobian) const
static void configure_tapeless_mode(const unsigned int n_independent_variables, const bool ensure_persistent_setting=true)
std::vector< scalar_type > independent_variable_values
Types< ad_type >::tape_index active_tape_index() const
std::vector< bool > symmetric_independent_variables
void set_sensitivity_value(const unsigned int index, const bool symmetric_component, const scalar_type &value)
typename HelperBase< ADNumberTypeCode, ScalarType >::ad_type ad_type
std::vector< bool > registered_marked_independent_variables
void hessian(const typename Types< ADNumberType >::tape_index active_tape_index, const std::vector< ScalarType > &independent_variables, FullMatrix< ScalarType > &hessian) const
bool keep_independent_values() const
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)
bool requires_retaping(const typename Types< ADNumberType >::tape_index tape_index) const
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)
void reset_registered_independent_variables()
std::vector< bool > registered_marked_dependent_variables
ScalarFunction(const unsigned int n_independent_variables)
scalar_type compute_value() const
void print_tape_stats(const typename Types< ADNumberType >::tape_index tape_index, std::ostream &stream) const
void start_taping(const typename Types< ADNumberType >::tape_index tape_index, const bool keep_independent_values)
ScalarType value(const std::vector< ADNumberType > &dependent_variables) const
unsigned int n_registered_dependent_variables() const
bool is_recording() 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 set_tape_buffer_sizes(const typename Types< ADNumberType >::tape_buffer_sizes obufsize=64 *1024 *1024, const typename Types< ADNumberType >::tape_buffer_sizes lbufsize=64 *1024 *1024, const typename Types< ADNumberType >::tape_buffer_sizes vbufsize=64 *1024 *1024, const typename Types< ADNumberType >::tape_buffer_sizes tbufsize=64 *1024 *1024)
void print(std::ostream &stream) const
void print(std::ostream &stream) const
void finalize_sensitive_independent_variables() const
virtual void compute_linearization(FullMatrix< scalar_type > &linearization) const override
void gradient(const typename Types< ADNumberType >::tape_index active_tape_index, const std::vector< ScalarType > &independent_variables, Vector< ScalarType > &gradient) const
bool is_symmetric_independent_variable(const unsigned int index) const
typename HelperBase< ADNumberTypeCode, ScalarType >::scalar_type scalar_type
bool is_registered_tape(const typename Types< ADNumberType >::tape_index tape_index) const
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 reset(const bool clear_registered_tapes)
void register_dependent_variables(const std::vector< ad_type > &funcs)
std::vector< bool > registered_independent_variable_values
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 prevent_dependent_variable_marking()
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
TapelessDrivers< ad_type, scalar_type > tapeless_driver
bool is_registered_tape(const typename Types< ad_type >::tape_index tape_index) const
std::vector< ad_type > independent_variables
std::size_t n_dependent_variables() const
void gradient(const std::vector< ADNumberType > &independent_variables, const std::vector< ADNumberType > &dependent_variables, Vector< ScalarType > &gradient) const
void activate_recorded_tape(const typename Types< ad_type >::tape_index tape_index)
void stop_taping(const typename Types< ADNumberType >::tape_index active_tape_index, const bool write_tapes_to_file)
void hessian(const std::vector< ADNumberType > &independent_variables, const std::vector< ADNumberType > &dependent_variables, FullMatrix< ScalarType > &hessian) const
bool last_action_requires_retaping() const
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)
void allow_dependent_variable_marking()
unsigned int n_registered_independent_variables() const
void remove_tape(const typename Types< ADNumberType >::tape_index tape_index)
static ::ExceptionBase & ExcInternalError()
void activate_tape(const typename Types< ad_type >::tape_index tape_index, const bool read_mode)