static bool isnaninf(const FadType& x) { if (Teuchos::ScalarTraits<ValueT>::isnaninf(x.val())) return true; for (int i=0; i<x.size(); i++) if (Teuchos::ScalarTraits<ValueT>::isnaninf(x.dx(i))) return true; return false; }
// Real part is only defined for real derivative components static FadType real(const FadType& x) { #ifdef TEUCHOS_DEBUG TEST_FOR_EXCEPTION(is_fad_real(x) == false, std::runtime_error, "Real component is not a differentiable " "function of complex inputs."); #endif FadType y = x; y.val() = Teuchos::ScalarTraits<ValueT>::real(x.val()); return y; }
// Helper function to determine whether a Fad type is real static bool is_fad_real(const FadType& x) { if (x.size() == 0) return true; if (Teuchos::ScalarTraits<ValueT>::isComplex) { if (!is_complex_real(x.val())) return false; for (int i=0; i<x.size(); i++) if (!is_complex_real(x.fastAccessDx(i))) return false; } return true; }
TEUCHOS_UNIT_TEST_TEMPLATE_3_DECL( Kokkos_View_Fad, UnmanagedConst, FadType, Layout, Device ) { typedef typename FadType::value_type scalar_type; typedef typename ApplyView<scalar_type***,Layout,Device>::type ViewType; typedef typename ApplyView<const scalar_type***,Layout,Device>::type ConstViewType; typedef typename ApplyView<FadType**,Layout,Device,Kokkos::MemoryUnmanaged>::type FadViewType; typedef typename ApplyView<const FadType**,Layout,Device,Kokkos::MemoryUnmanaged>::type ConstFadViewType; typedef typename ViewType::size_type size_type; typedef typename ViewType::HostMirror host_view_type; typedef typename FadViewType::HostMirror fad_host_view_type; const size_type num_rows = global_num_rows; const size_type num_cols = global_num_cols; const size_type fad_size = global_fad_size; // Create and fill view ViewType v("view", num_rows, num_cols, fad_size+1); host_view_type h_v = Kokkos::create_mirror_view(v); for (size_type i=0; i<num_rows; ++i) { for (size_type j=0; j<num_cols; ++j) { FadType f = generate_fad<FadType>(num_rows, num_cols, fad_size, i, j); for (size_type k=0; k<fad_size; k++) h_v(i,j,k) = f.dx(k); h_v(i,j,fad_size) = f.val(); } } Kokkos::deep_copy(v, h_v); ConstViewType v_const = v; // Create unmanaged view ConstFadViewType v_fad( v_const.ptr_on_device(), num_rows, num_cols, fad_size+1); // Copy back -- can't use create_mirror_view() because v_fad is unmanaged fad_host_view_type h_v_fad("host_view_fad", num_rows, num_cols, fad_size+1); Kokkos::deep_copy(h_v_fad, v_fad); // Check success = true; for (size_type i=0; i<num_rows; ++i) { for (size_type j=0; j<num_cols; ++j) { FadType f = generate_fad<FadType>(num_rows, num_cols, fad_size, i, j); success = success && checkFads(f, h_v_fad(i,j), out); } } }
// Imaginary part is only defined for real derivative components static FadType imag(const FadType& x) { #ifdef TEUCHOS_DEBUG TEST_FOR_EXCEPTION(is_fad_real(x) == false, std::runtime_error, "Imaginary component is not a differentiable " "function of complex inputs."); #endif return FadType(Teuchos::ScalarTraits<ValueT>::imag(x.val())); }
void fad_process_fill(const ElemData& e, unsigned int neqn, const std::vector< std::vector<double> >& w_local, const std::vector<FadType>& f_fad, std::vector<double>& f, std::vector< std::vector<double> >& adj) { // Get residual for (unsigned int node=0; node<e.nnode; node++) for (unsigned int eqn=0; eqn<neqn; eqn++) f[e.gid[node]*neqn+eqn] += f_fad[node*neqn+eqn].val(); // Get adjoint for each adjoint direction for (unsigned int col=0; col<w_local.size(); col++) { FadType z = 0.0; for (unsigned int node=0; node<e.nnode; node++) for (unsigned int eqn=0; eqn<neqn; eqn++) z += f_fad[node*neqn+eqn]*w_local[col][node*neqn+eqn]; for (unsigned int node=0; node<e.nnode; node++) for (unsigned int eqn=0; eqn<neqn; eqn++) adj[col][e.gid[node]*neqn+eqn] += z.fastAccessDx(node*neqn+eqn); } }
TEUCHOS_UNIT_TEST_TEMPLATE_3_DECL( Kokkos_View_Fad, DeepCopy_ConstantFad, FadType, Layout, Device ) { typedef typename ApplyView<FadType**,Layout,Device>::type ViewType; typedef typename ViewType::size_type size_type; typedef typename ViewType::HostMirror host_view_type; const size_type num_rows = global_num_rows; const size_type num_cols = global_num_cols; const size_type fad_size = global_fad_size; // Create and fill view ViewType v("view", num_rows, num_cols, fad_size+1); typename ViewType::array_type va = v; Kokkos::deep_copy( va, 1.0 ); // Deep copy a constant scalar FadType a = 2.3456; Kokkos::deep_copy( v, a ); // Copy to host host_view_type hv = Kokkos::create_mirror_view(v); Kokkos::deep_copy(hv, v); // Check success = true; for (size_type i=0; i<num_rows; ++i) { for (size_type j=0; j<num_cols; ++j) { #if defined(HAVE_SACADO_VIEW_SPEC) && !defined(SACADO_DISABLE_FAD_VIEW_SPEC) FadType f = FadType(fad_size, a.val()); #else FadType f = a; #endif success = success && checkFads(f, hv(i,j), out); } } }
static magnitudeType magnitude(const FadType& a) { #ifdef TEUCHOS_DEBUG TEUCHOS_SCALAR_TRAITS_NAN_INF_ERR( a, "Error, the input value to magnitude(...) a = " << a << " can not be NaN!" ); TEST_FOR_EXCEPTION(is_fad_real(a) == false, std::runtime_error, "Complex magnitude is not a differentiable " "function of complex inputs."); #endif //return std::fabs(a); magnitudeType b(a.size(), Teuchos::ScalarTraits<ValueT>::magnitude(a.val())); if (Teuchos::ScalarTraits<ValueT>::real(a.val()) >= 0) for (int i=0; i<a.size(); i++) b.fastAccessDx(i) = Teuchos::ScalarTraits<ValueT>::magnitude(a.fastAccessDx(i)); else for (int i=0; i<a.size(); i++) b.fastAccessDx(i) = -Teuchos::ScalarTraits<ValueT>::magnitude(a.fastAccessDx(i)); return b; }