From: Jean-Paul Pelteret Date: Fri, 3 Nov 2017 13:08:31 +0000 (+0100) Subject: Implement type traits and helper classes for Adol-C numbers X-Git-Tag: v9.0.0-rc1~769^2~3 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=837471ecf82a15e052b925cd99a8b89e395e5120;p=dealii.git Implement type traits and helper classes for Adol-C numbers --- diff --git a/include/deal.II/differentiation/ad.h b/include/deal.II/differentiation/ad.h index 482fbb5ccf..3e7b5f9c62 100644 --- a/include/deal.II/differentiation/ad.h +++ b/include/deal.II/differentiation/ad.h @@ -23,6 +23,9 @@ #include #include +#include +#include + DEAL_II_NAMESPACE_OPEN /** diff --git a/include/deal.II/differentiation/ad/adolc_number_types.h b/include/deal.II/differentiation/ad/adolc_number_types.h new file mode 100644 index 0000000000..8dc56effeb --- /dev/null +++ b/include/deal.II/differentiation/ad/adolc_number_types.h @@ -0,0 +1,477 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2016 - 2017 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE at +// the top level of the deal.II distribution. +// +// --------------------------------------------------------------------- + +#ifndef dealii_differentiation_ad_adolc_number_types_h +#define dealii_differentiation_ad_adolc_number_types_h + +#include + +#ifdef DEAL_II_WITH_ADOLC + +DEAL_II_DISABLE_EXTRA_DIAGNOSTICS +#include +#include // Taped double math functions + +#include // Taped double +#include // Tapeless double +DEAL_II_ENABLE_EXTRA_DIAGNOSTICS + +#include +#include + +#include +#include + +#include +#include + +DEAL_II_NAMESPACE_OPEN + + +namespace Differentiation +{ + namespace AD + { + /** + * A struct to indicate whether a given @p NumberType is an + * Adol-C number or not. By default, numbers are not considered to + * have the necessary characteristics to fulfill this condition. + * + * @author Jean-Paul Pelteret, 2017 + */ + template + struct is_adolc_number; + } +} + + +/* --------------------------- inline and template functions and specializations ------------------------- */ + + +#ifndef DOXYGEN + + +namespace Differentiation +{ + namespace AD + { + + namespace internal + { + + /** + * A specialization for the information struct for taped Adol-C + * numbers. + */ + template + struct ADNumberInfoFromEnum::value>::type + > + { + static const bool is_taped = true; + typedef adouble real_type; + typedef double derivative_type; + static const unsigned int n_supported_derivative_levels + = std::numeric_limits::max(); + }; + + + /** + * A specialization for the information struct for tapeless Adol-C + * numbers. + */ + template + struct ADNumberInfoFromEnum::value>::type + > + { + static const bool is_taped = false; + typedef adtl::adouble real_type; + typedef double derivative_type; + static const unsigned int n_supported_derivative_levels = 1; + }; + + + template + struct Marking::type_code == NumberTypes::adolc_taped && + ADNumberTraits::is_real_valued + >::type + > + { + typedef typename ADNumberTraits::scalar_type scalar_type; + + /* + * Initialize the state of an independent variable. + */ + static void + independent_variable(const scalar_type &in, + const unsigned int , + const unsigned int , + ADNumberType &out) + { + out <<= in; + } + + /* + * Initialize the state of a dependent variable. + * + * @note The second argument must be writable, so we + * simply pass a copy instead of a non-constant reference. + */ + static void + dependent_variable(ADNumberType &out, + ADNumberType func) + { + // Store the value only (strip it of all sensitivities) + out = ADNumberTraits::get_scalar_value(func); + // Mark as a dependent variable + scalar_type tmp; + func >>= tmp; + } + }; + + template + struct Marking::type_code == NumberTypes::adolc_tapeless && + ADNumberTraits::is_real_valued + >::type> + { + typedef typename ADNumberTraits::scalar_type scalar_type; + + /* + * Initialize the state of an independent variable. + */ + static void + independent_variable(const scalar_type &in, + const unsigned int index, + const unsigned int , + ADNumberType &out) + { + // It is important that the tapeless variables have their values set + // before defining their directional derivative index + out = in; + + // Violating this condition when will result in an Adol-C internal + // error. We could rather always throw here in order to provide a + // less cryptic message. + AssertThrow(index < adtl::getNumDir(), + ExcMessage("The index number of the independent variable being " + "marked is greater than the number of independent " + "variables that have been declared.")); + out.setADValue(index, 1 /*seed value for first derivative*/); + } + + /* + * Initialize the state of a dependent variable. + */ + static void + dependent_variable(ADNumberType &out, + const ADNumberType &func) + { + // Simply transfer value with sensitivities + out = 0.0; + out = func; + } + }; + + + /** + * A struct to help extract certain information associated with + * taped Adol-C auto-differentiable numbers. + * + * @author Jean-Paul Pelteret, 2017 + */ + template<> + struct ExtractData + { + /** + * Extract the real value. + */ + static double + value (const adouble &x) + { + return x.getValue(); + } + + + /** + * Extract the number of directional derivatives. + * + * This information is not available for taped numbers, and this + * function exists for aesthetic/compatibility reasons only. + */ + static unsigned int + n_directional_derivatives (const adouble &) + { + return 0; + } + + + /** + * Extract the directional derivative in the specified @p direction. + * + * It is in fact not possible to perform this operation in this manner, + * for taped numbers, and this function exists for + * aesthetic/compatibility reasons only. + */ + static double + directional_derivative (const adouble &, + const unsigned int) + { + AssertThrow(false, + ExcMessage("The derivative values for taped Adol-C numbers must be" + "computed through the ::gradient function.")); + return 0.0; + } + }; + + + /** + * A struct to help extract certain information associated with + * tapeless Adol-C auto-differentiable numbers. + * + * @author Jean-Paul Pelteret, 2017 + */ + template<> + struct ExtractData + { + /** + * Extract the floating point value. + */ + static double + value (const adtl::adouble &x) + { + return x.getValue(); + } + + + /** + * Extract the number of directional derivatives. + */ + static unsigned int + n_directional_derivatives (const adtl::adouble &) + { + // This is a global function call... + return adtl::getNumDir(); + } + + + /** + * Extract the directional derivative in the specified @p direction. + */ + static double + directional_derivative (const adtl::adouble &x, + const unsigned int direction) + { + Assert(direction < n_directional_derivatives(x), + ExcMessage("Requested directional derivative is greater than the number " + "registered by Adol-C.")); + return x.getADValue(direction); + } + }; + + } // namespace internal + + + + /** + * Specialization of the general AdolCWrappers::ADNumberTraits class that + * provides relevant information for auto-differentiable numbers. + * This specialization is for the case where @p ADNumberType is an + * taped Adol-C (real) double. + * + * @note In this case the number traits are the same as those for a taped double. + * + * @author Jean-Paul Pelteret, 2017 + */ + template + struct ADNumberTraits::value + >::type> + : NumberTraits + { + static_assert( + std::is_same::value, + "Incorrect template type selected for taped ad_type"); + static_assert( + is_taped == true, + "Incorrect setting for taping"); + }; + + + + /** + * Specialization of the general ADNumberTraits class that + * provides relevant information for auto-differentiable numbers. + * This specialization is for the case where @p ADNumberType is an + * taped Adol-C complex double. + * + * @note In this case the number traits are the same as those for a taped complex + * double. + * + * @author Jean-Paul Pelteret, 2017 + */ + template + struct ADNumberTraits >::value + >::type> + : NumberTraits, NumberTypes::adolc_taped> + { + static_assert( + std::is_same >::value, + "Incorrect template type selected for taped ad_type"); + static_assert( + is_taped == true, + "Incorrect setting for taping"); + }; + + + + /** + * Specialization of the general ADNumberTraits class that + * provides relevant information for auto-differentiable numbers. + * This specialization is for the case where @p ADNumberType is an + * tapeless Adol-C (real) double. + * + * @note In this case the number traits are the same as those for a tapeless double. + * + * @author Jean-Paul Pelteret, 2017 + */ + template + struct ADNumberTraits::value + >::type> + : NumberTraits + { + static_assert( + std::is_same::value, + "Incorrect template type selected for tapeless ad_type"); + static_assert( + is_tapeless == true, + "Incorrect setting for taping"); + }; + + + + /** + * Specialization of the general ADNumberTraits class that + * provides relevant information for auto-differentiable numbers. + * This specialization is for the case where @p ADNumberType is an + * tapeless Adol-C complex double. + * + * @note In this case the number traits are the same as those for a tapeless + * complex double. + * + * @author Jean-Paul Pelteret, 2017 + */ + template + struct ADNumberTraits >::value + >::type> + : NumberTraits, NumberTypes::adolc_tapeless> + { + static_assert( + std::is_same >::value, + "Incorrect template type selected for tapeless ad_type"); + static_assert( + is_tapeless == true, + "Incorrect setting for taping"); + }; + + + + /** + * Specialization of the NumberTraits struct for + * the (otherwise disabled) taped Adol-C number type. + */ + template<> + struct NumberTraits + : NumberTraits::scalar_type,NumberTypes::adolc_taped> + {}; + + + /** + * Specialization of the NumberTraits struct for + * the (otherwise disabled) taped Adol-C complex number type. + */ + template<> + struct NumberTraits,NumberTypes::adolc_taped> + : NumberTraits >::scalar_type,NumberTypes::adolc_taped> + {}; + + + /** + * Specialization of the NumberTraits struct for + * the (otherwise disabled) tapeless Adol-C number type. + */ + template<> + struct NumberTraits + : NumberTraits::scalar_type,NumberTypes::adolc_tapeless> + {}; + + + /** + * Specialization of the NumberTraits struct for + * the (otherwise disabled) tapeless Adol-C complex number type. + */ + template<> + struct NumberTraits,NumberTypes::adolc_tapeless> + : NumberTraits >::scalar_type,NumberTypes::adolc_tapeless> + {}; + + + + /** + * A struct to indicate whether a given @p NumberType is an + * Adol-C number or not. By default, numbers are not considered to + * have the necessary characteristics to fulfill this condition. + */ + template + struct is_adolc_number + : std::false_type + {}; + + + + /** + * Specialization of the struct for the case when the input template + * parameter is a (real or complex; taped or tapeless) Adol-C number. + */ + template + struct is_adolc_number::type>::type_code == NumberTypes::adolc_taped || + ADNumberTraits::type>::type_code == NumberTypes::adolc_tapeless + >::type> + : std::true_type + {}; + + } // namespace AD +} // namespace Differentiation + + +#endif // DOXYGEN + + +DEAL_II_NAMESPACE_CLOSE + + +#endif // DEAL_II_WITH_ADOLC + +#endif diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index f789a8597f..14c2e42fd1 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -49,6 +49,7 @@ ADD_SUBDIRECTORY(matrix_free) ADD_SUBDIRECTORY(meshworker) ADD_SUBDIRECTORY(opencascade) ADD_SUBDIRECTORY(particles) +ADD_SUBDIRECTORY(differentiation) ADD_SUBDIRECTORY(physics) ADD_SUBDIRECTORY(optimization/rol) ADD_SUBDIRECTORY(non_matching) diff --git a/source/differentiation/CMakeLists.txt b/source/differentiation/CMakeLists.txt new file mode 100644 index 0000000000..77bb11c734 --- /dev/null +++ b/source/differentiation/CMakeLists.txt @@ -0,0 +1,16 @@ +## --------------------------------------------------------------------- +## +## Copyright (C) 2017 by the deal.II authors +## +## This file is part of the deal.II library. +## +## The deal.II library is free software; you can use it, redistribute +## it, and/or modify it under the terms of the GNU Lesser General +## Public License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## The full text of the license can be found in the file LICENSE at +## the top level of the deal.II distribution. +## +## --------------------------------------------------------------------- + +ADD_SUBDIRECTORY(ad) diff --git a/source/differentiation/ad/CMakeLists.txt b/source/differentiation/ad/CMakeLists.txt new file mode 100644 index 0000000000..d445d49661 --- /dev/null +++ b/source/differentiation/ad/CMakeLists.txt @@ -0,0 +1,31 @@ +## --------------------------------------------------------------------- +## +## Copyright (C) 2017 by the deal.II authors +## +## This file is part of the deal.II library. +## +## The deal.II library is free software; you can use it, redistribute +## it, and/or modify it under the terms of the GNU Lesser General +## Public License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## The full text of the license can be found in the file LICENSE at +## the top level of the deal.II distribution. +## +## --------------------------------------------------------------------- + +INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) + +SET(_src + adolc_number_types.cc + ) + +SET(_inst + adolc_number_types.inst.in + ) + +FILE(GLOB _header + ${CMAKE_SOURCE_DIR}/include/deal.II/differentiation/ad/*.h + ) + +DEAL_II_ADD_LIBRARY(obj_differentiation_ad OBJECT ${_src} ${_header} ${_inst}) +EXPAND_INSTANTIATIONS(obj_differentiation_ad "${_inst}") diff --git a/source/differentiation/ad/adolc_number_types.cc b/source/differentiation/ad/adolc_number_types.cc new file mode 100644 index 0000000000..073e421082 --- /dev/null +++ b/source/differentiation/ad/adolc_number_types.cc @@ -0,0 +1,31 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2017 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE at +// the top level of the deal.II distribution. +// +// --------------------------------------------------------------------- + + +#include + +#ifdef DEAL_II_WITH_ADOLC + +#include + +DEAL_II_NAMESPACE_OPEN + +/*---------------------- Explicit Instantiations ----------------------*/ + +#include "adolc_number_types.inst" + +DEAL_II_NAMESPACE_CLOSE + +#endif diff --git a/source/differentiation/ad/adolc_number_types.inst.in b/source/differentiation/ad/adolc_number_types.inst.in new file mode 100644 index 0000000000..1f5795394d --- /dev/null +++ b/source/differentiation/ad/adolc_number_types.inst.in @@ -0,0 +1,51 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2017 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE at +// the top level of the deal.II distribution. +// +// --------------------------------------------------------------------- + +for (Number : DIFFERENTIABLE_ADOLC_REAL_SCALARS) +{ + namespace Differentiation + \{ + namespace AD + \{ + template struct ADNumberTraits; + \} + \} +} + + +for (Number : REAL_SCALARS) +{ + namespace Differentiation + \{ + namespace AD + \{ + template struct NumberTraits; + template struct NumberTraits; + \} + \} +} + + +for (Number : COMPLEX_SCALARS) +{ + namespace Differentiation + \{ + namespace AD + \{ + template struct NumberTraits; + template struct NumberTraits; + \} + \} +}