#include <deal.II/base/array_view.h>
#include <deal.II/base/memory_consumption.h>
#include <deal.II/base/multithread_info.h>
+#include <deal.II/base/numbers.h>
#include <deal.II/base/quadrature.h>
#include <deal.II/base/signaling_nan.h>
+#include <deal.II/differentiation/ad.h>
#include <deal.II/lac/vector.h>
#include <deal.II/lac/block_vector.h>
#include <deal.II/lac/la_vector.h>
#include <memory>
#include <type_traits>
-#include <deal.II/differentiation/ad/adolc_product_types.h>
-#include <deal.II/differentiation/ad/sacado_product_types.h>
#include <boost/container/small_vector.hpp>
if (shape_function_data[shape_function].is_nonzero_shape_function_component)
{
const Number &value = dof_values[shape_function];
- if (value == dealii::internal::NumberType<typename std::decay<Number>::type>::value(0.0))
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number>::value)
+ if (value == dealii::internal::NumberType<Number>::value(0.0) )
+ continue;
const double *shape_value_ptr =
&shape_values(shape_function_data[shape_function].row_index, 0);
if (shape_function_data[shape_function].is_nonzero_shape_function_component)
{
const Number &value = dof_values[shape_function];
- if (value == dealii::internal::NumberType<typename std::decay<Number>::type>::value(0.0))
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number>::value)
+ if (value == dealii::internal::NumberType<Number>::value(0.0) )
+ continue;
const dealii::Tensor<order,spacedim> *shape_derivative_ptr =
&shape_derivatives[shape_function_data[shape_function].row_index][0];
if (shape_function_data[shape_function].is_nonzero_shape_function_component)
{
const Number &value = dof_values[shape_function];
- if (value == dealii::internal::NumberType<typename std::decay<Number>::type>::value(0.0))
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number>::value)
+ if (value == dealii::internal::NumberType<Number>::value(0.0))
+ continue;
const dealii::Tensor<2,spacedim> *shape_hessian_ptr =
&shape_hessians[shape_function_data[shape_function].row_index][0];
continue;
const Number &value = dof_values[shape_function];
- if (value == dealii::internal::NumberType<typename std::decay<Number>::type>::value(0.0))
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number>::value)
+ if (value == dealii::internal::NumberType<Number>::value(0.0))
+ continue;
if (snc != -1)
{
continue;
const Number &value = dof_values[shape_function];
- if (value == dealii::internal::NumberType<typename std::decay<Number>::type>::value(0.0))
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number>::value)
+ if (value == dealii::internal::NumberType<Number>::value(0.0))
+ continue;
if (snc != -1)
{
continue;
const Number &value = dof_values[shape_function];
- if (value == dealii::internal::NumberType<typename std::decay<Number>::type>::value(0.0))
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number>::value)
+ if (value == dealii::internal::NumberType<Number>::value(0.0))
+ continue;
if (snc != -1)
{
continue;
const Number &value = dof_values[shape_function];
- if (value == dealii::internal::NumberType<typename std::decay<Number>::type>::value(0.0))
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number>::value)
+ if (value == dealii::internal::NumberType<Number>::value(0.0))
+ continue;
if (snc != -1)
{
const Number &value = dof_values[shape_function];
- if (value == dealii::internal::NumberType<typename std::decay<Number>::type>::value(0.0))
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number>::value)
+ if (value == dealii::internal::NumberType<Number>::value(0.0))
+ continue;
if (snc != -1)
{
const Number &value = dof_values[shape_function];
- if (value == dealii::internal::NumberType<typename std::decay<Number>::type>::value(0.0))
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number>::value)
+ if (value == dealii::internal::NumberType<Number>::value(0.0))
+ continue;
if (snc != -1)
{
continue;
const Number &value = dof_values[shape_function];
- if (value == dealii::internal::NumberType<typename std::decay<Number>::type>::value(0.0))
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number>::value)
+ if (value == dealii::internal::NumberType<Number>::value(0.0))
+ continue;
if (snc != -1)
{
continue;
const Number &value = dof_values[shape_function];
- if (value == dealii::internal::NumberType<typename std::decay<Number>::type>::value(0.0))
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number>::value)
+ if (value == dealii::internal::NumberType<Number>::value(0.0))
+ continue;
if (snc != -1)
{
continue;
const Number &value = dof_values[shape_function];
- if (value == dealii::internal::NumberType<typename std::decay<Number>::type>::value(0.0))
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number>::value)
+ if (value == dealii::internal::NumberType<Number>::value(0.0))
+ continue;
if (snc != -1)
{
continue;
const Number &value = dof_values[shape_function];
- if (value == dealii::internal::NumberType<typename std::decay<Number>::type>::value(0.0))
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number>::value)
+ if (value == dealii::internal::NumberType<Number>::value(0.0))
+ continue;
if (snc != -1)
{
continue;
const Number &value = dof_values[shape_function];
- if (value == dealii::internal::NumberType<typename std::decay<Number>::type>::value(0.0))
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number>::value)
+ if (value == dealii::internal::NumberType<Number>::value(0.0))
+ continue;
if (snc != -1)
{
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
const Number2 value = dof_values_ptr[shape_func];
- if (value == Number2())
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number2>::value)
+ if (value == dealii::internal::NumberType<Number2>::value(0.0))
+ continue;
const double *shape_value_ptr = &shape_values(shape_func, 0);
for (unsigned int point=0; point<n_quadrature_points; ++point)
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
const Number &value = dof_values_ptr[shape_func+mc*dofs_per_cell];
- if (value == dealii::internal::NumberType<typename std::decay<Number>::type>::value(0.0))
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number>::value)
+ if (value == dealii::internal::NumberType<Number>::value(0.0))
+ continue;
if (fe.is_primitive(shape_func))
{
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
const Number &value = dof_values_ptr[shape_func];
- if (value == dealii::internal::NumberType<typename std::decay<Number>::type>::value(0.0))
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number>::value)
+ if (value == dealii::internal::NumberType<Number>::value(0.0))
+ continue;
const Tensor<order,spacedim> *shape_derivative_ptr
= &shape_derivatives[shape_func][0];
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
const Number &value = dof_values_ptr[shape_func+mc*dofs_per_cell];
- if (value == dealii::internal::NumberType<typename std::decay<Number>::type>::value(0.0))
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number>::value)
+ if (value == dealii::internal::NumberType<Number>::value(0.0))
+ continue;
if (fe.is_primitive(shape_func))
{
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
const Number2 value = dof_values_ptr[shape_func];
- if (value == Number2())
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number2>::value)
+ if (value == dealii::internal::NumberType<Number2>::value(0.0))
+ continue;
const Tensor<2,spacedim> *shape_hessian_ptr
= &shape_hessians[shape_func][0];
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
const Number &value = dof_values_ptr[shape_func+mc*dofs_per_cell];
- if (value == dealii::internal::NumberType<typename std::decay<Number>::type>::value(0.0))
- continue;
+ // For auto-differentiable numbers, the fact that a DoF value is zero
+ // does not imply that its derivatives are zero as well. So we
+ // can't filter by value for these number types.
+ if (!Differentiation::AD::is_ad_number<Number>::value)
+ if (value == dealii::internal::NumberType<Number>::value(0.0))
+ continue;
if (fe.is_primitive(shape_func))
{