From: Jean-Paul Pelteret Date: Thu, 16 Nov 2017 07:56:03 +0000 (+0100) Subject: Add support for AD calculations to FEValues functions X-Git-Tag: v9.0.0-rc1~765^2~2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f88cf361ae00c922d71d5c6183cc276012b3f939;p=dealii.git Add support for AD calculations to FEValues functions When using AD to automatically compute the linearisation of a residual, one cannot a-priori assume no sensitivity with respect to zero-valued degrees-of-freedom. This commit ensures that this calculation shortcut is not taken for AD numbers. --- diff --git a/source/fe/fe_values.cc b/source/fe/fe_values.cc index fa06d3ab46..f141538cf5 100644 --- a/source/fe/fe_values.cc +++ b/source/fe/fe_values.cc @@ -16,8 +16,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -40,8 +42,6 @@ #include #include -#include -#include #include @@ -480,8 +480,12 @@ namespace FEValuesViews if (shape_function_data[shape_function].is_nonzero_shape_function_component) { const Number &value = dof_values[shape_function]; - if (value == dealii::internal::NumberType::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::value) + if (value == dealii::internal::NumberType::value(0.0) ) + continue; const double *shape_value_ptr = &shape_values(shape_function_data[shape_function].row_index, 0); @@ -514,8 +518,12 @@ namespace FEValuesViews if (shape_function_data[shape_function].is_nonzero_shape_function_component) { const Number &value = dof_values[shape_function]; - if (value == dealii::internal::NumberType::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::value) + if (value == dealii::internal::NumberType::value(0.0) ) + continue; const dealii::Tensor *shape_derivative_ptr = &shape_derivatives[shape_function_data[shape_function].row_index][0]; @@ -547,8 +555,12 @@ namespace FEValuesViews if (shape_function_data[shape_function].is_nonzero_shape_function_component) { const Number &value = dof_values[shape_function]; - if (value == dealii::internal::NumberType::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::value) + if (value == dealii::internal::NumberType::value(0.0)) + continue; const dealii::Tensor<2,spacedim> *shape_hessian_ptr = &shape_hessians[shape_function_data[shape_function].row_index][0]; @@ -585,8 +597,12 @@ namespace FEValuesViews continue; const Number &value = dof_values[shape_function]; - if (value == dealii::internal::NumberType::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::value) + if (value == dealii::internal::NumberType::value(0.0)) + continue; if (snc != -1) { @@ -635,8 +651,12 @@ namespace FEValuesViews continue; const Number &value = dof_values[shape_function]; - if (value == dealii::internal::NumberType::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::value) + if (value == dealii::internal::NumberType::value(0.0)) + continue; if (snc != -1) { @@ -689,8 +709,12 @@ namespace FEValuesViews continue; const Number &value = dof_values[shape_function]; - if (value == dealii::internal::NumberType::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::value) + if (value == dealii::internal::NumberType::value(0.0)) + continue; if (snc != -1) { @@ -742,8 +766,12 @@ namespace FEValuesViews continue; const Number &value = dof_values[shape_function]; - if (value == dealii::internal::NumberType::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::value) + if (value == dealii::internal::NumberType::value(0.0)) + continue; if (snc != -1) { @@ -804,8 +832,12 @@ namespace FEValuesViews const Number &value = dof_values[shape_function]; - if (value == dealii::internal::NumberType::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::value) + if (value == dealii::internal::NumberType::value(0.0)) + continue; if (snc != -1) { @@ -864,8 +896,12 @@ namespace FEValuesViews const Number &value = dof_values[shape_function]; - if (value == dealii::internal::NumberType::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::value) + if (value == dealii::internal::NumberType::value(0.0)) + continue; if (snc != -1) { @@ -986,8 +1022,12 @@ namespace FEValuesViews continue; const Number &value = dof_values[shape_function]; - if (value == dealii::internal::NumberType::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::value) + if (value == dealii::internal::NumberType::value(0.0)) + continue; if (snc != -1) { @@ -1040,8 +1080,12 @@ namespace FEValuesViews continue; const Number &value = dof_values[shape_function]; - if (value == dealii::internal::NumberType::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::value) + if (value == dealii::internal::NumberType::value(0.0)) + continue; if (snc != -1) { @@ -1094,8 +1138,12 @@ namespace FEValuesViews continue; const Number &value = dof_values[shape_function]; - if (value == dealii::internal::NumberType::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::value) + if (value == dealii::internal::NumberType::value(0.0)) + continue; if (snc != -1) { @@ -1182,8 +1230,12 @@ namespace FEValuesViews continue; const Number &value = dof_values[shape_function]; - if (value == dealii::internal::NumberType::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::value) + if (value == dealii::internal::NumberType::value(0.0)) + continue; if (snc != -1) { @@ -1238,8 +1290,12 @@ namespace FEValuesViews continue; const Number &value = dof_values[shape_function]; - if (value == dealii::internal::NumberType::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::value) + if (value == dealii::internal::NumberType::value(0.0)) + continue; if (snc != -1) { @@ -2687,8 +2743,12 @@ namespace internal for (unsigned int shape_func=0; shape_func::value) + if (value == dealii::internal::NumberType::value(0.0)) + continue; const double *shape_value_ptr = &shape_values(shape_func, 0); for (unsigned int point=0; point::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::value) + if (value == dealii::internal::NumberType::value(0.0)) + continue; if (fe.is_primitive(shape_func)) { @@ -2819,8 +2883,12 @@ namespace internal for (unsigned int shape_func=0; shape_func::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::value) + if (value == dealii::internal::NumberType::value(0.0)) + continue; const Tensor *shape_derivative_ptr = &shape_derivatives[shape_func][0]; @@ -2878,8 +2946,12 @@ namespace internal for (unsigned int shape_func=0; shape_func::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::value) + if (value == dealii::internal::NumberType::value(0.0)) + continue; if (fe.is_primitive(shape_func)) { @@ -2947,8 +3019,12 @@ namespace internal for (unsigned int shape_func=0; shape_func::value) + if (value == dealii::internal::NumberType::value(0.0)) + continue; const Tensor<2,spacedim> *shape_hessian_ptr = &shape_hessians[shape_func][0]; @@ -3005,8 +3081,12 @@ namespace internal for (unsigned int shape_func=0; shape_func::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::value) + if (value == dealii::internal::NumberType::value(0.0)) + continue; if (fe.is_primitive(shape_func)) {