// 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;
      }
      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;
      }
Example #3
0
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);
    }
}