52 #ifndef SACADO_ELRFAD_GENERALFAD_HPP 53 #define SACADO_ELRFAD_GENERALFAD_HPP 72 template <
typename T,
typename Storage>
107 Storage(sz, x, zero_out) {}
131 template <
typename S>
134 Storage(x.size(),
T(0.)) {
135 const int sz = x.size();
139 if (x.hasFastAccess())
140 for(
int i=0; i<sz; ++i)
143 for(
int i=0; i<sz; ++i)
148 if (x.hasFastAccess()) {
150 FastLocalAccumOp< Expr<S> > op(x);
153 for(op.i=0; op.i<sz; ++op.i) {
169 for(op.i=0; op.i<sz; ++op.i) {
186 this->
val() = x.val();
201 void diff(
const int ith,
const int n) {
202 if (this->size() !=
n)
219 template <
typename S>
223 if (x.size() != this->size())
return false;
224 bool eq = IE::eval(x.val(), this->
val());
225 for (
int i=0; i<this->size(); i++)
226 eq = eq && IE::eval(x.dx(i), this->
dx(i));
255 if (is_const && this->size()!=0)
267 template <
typename S>
271 if (this->size()) this->resize(0);
280 Storage::operator=(x);
285 template <
typename S>
288 const int xsz = x.size();
289 if (xsz != this->size())
290 this->resizeAndZero(xsz);
292 const int sz = this->size();
301 if (Expr<S>::is_linear) {
302 if (x.hasFastAccess())
303 for(
int i=0; i<sz; ++i)
306 for(
int i=0; i<sz; ++i)
311 if (x.hasFastAccess()) {
313 FastLocalAccumOp< Expr<S> > op(x);
316 for(op.i=0; op.i<sz; ++op.i) {
329 SlowLocalAccumOp< Expr<S> > op(x);
332 for(op.i=0; op.i<sz; ++op.i) {
347 this->
val() = x.val();
360 template <
typename S>
368 template <
typename S>
376 template <
typename S>
379 const int sz = this->size();
381 for (
int i=0; i<sz; ++i)
387 template <
typename S>
390 const int sz = this->size();
392 for (
int i=0; i<sz; ++i)
400 const int xsz = x.size(), sz = this->size();
402 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ ) 403 if ((xsz != sz) && (xsz != 0) && (sz != 0))
404 throw "Fad Error: Attempt to assign with incompatible sizes";
409 for (
int i=0; i<sz; ++i)
413 this->resizeAndZero(xsz);
414 for (
int i=0; i<xsz; ++i)
419 this->
val() += x.val();
427 const int xsz = x.size(), sz = this->size();
429 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ ) 430 if ((xsz != sz) && (xsz != 0) && (sz != 0))
431 throw "Fad Error: Attempt to assign with incompatible sizes";
436 for(
int i=0; i<sz; ++i)
440 this->resizeAndZero(xsz);
441 for(
int i=0; i<xsz; ++i)
446 this->
val() -= x.val();
455 const int xsz = x.size(), sz = this->size();
459 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ ) 460 if ((xsz != sz) && (xsz != 0) && (sz != 0))
461 throw "Fad Error: Attempt to assign with incompatible sizes";
466 for(
int i=0; i<sz; ++i)
470 this->resizeAndZero(xsz);
471 for(
int i=0; i<xsz; ++i)
477 for (
int i=0; i<sz; ++i)
490 const int xsz = x.size(), sz = this->size();
494 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ ) 495 if ((xsz != sz) && (xsz != 0) && (sz != 0))
496 throw "Fad Error: Attempt to assign with incompatible sizes";
501 for(
int i=0; i<sz; ++i)
503 ( this->
fastAccessDx(i)*xval - v*x.fastAccessDx(i) )/ (xval*xval);
506 this->resizeAndZero(xsz);
507 for(
int i=0; i<xsz; ++i)
508 this->
fastAccessDx(i) = - v*x.fastAccessDx(i) / (xval*xval);
513 for (
int i=0; i<sz; ++i)
524 template <
typename S>
527 const int xsz = x.size(), sz = this->size();
529 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ ) 530 if ((xsz != sz) && (xsz != 0) && (sz != 0))
531 throw "Fad Error: Attempt to assign with incompatible sizes";
534 if (Expr<S>::is_linear) {
537 if (x.hasFastAccess())
538 for (
int i=0; i<sz; ++i)
541 for (
int i=0; i<sz; ++i)
545 this->resizeAndZero(xsz);
546 if (x.hasFastAccess())
547 for (
int i=0; i<xsz; ++i)
550 for (
int i=0; i<xsz; ++i)
560 this->resizeAndZero(xsz);
562 if (x.hasFastAccess()) {
564 FastLocalAccumOp< Expr<S> > op(x);
567 for(op.i=0; op.i<xsz; ++op.i) {
580 SlowLocalAccumOp< Expr<S> > op(x);
583 for(op.i=0; op.i<xsz; ++op.i) {
600 this->
val() += x.val();
606 template <
typename S>
609 const int xsz = x.size(), sz = this->size();
611 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ ) 612 if ((xsz != sz) && (xsz != 0) && (sz != 0))
613 throw "Fad Error: Attempt to assign with incompatible sizes";
616 if (Expr<S>::is_linear) {
619 if (x.hasFastAccess())
620 for(
int i=0; i<sz; ++i)
623 for (
int i=0; i<sz; ++i)
627 this->resizeAndZero(xsz);
628 if (x.hasFastAccess())
629 for(
int i=0; i<xsz; ++i)
632 for (
int i=0; i<xsz; ++i)
642 this->resizeAndZero(xsz);
644 if (x.hasFastAccess()) {
646 FastLocalAccumOp< Expr<S> > op(x);
649 for(op.i=0; op.i<xsz; ++op.i) {
662 SlowLocalAccumOp< Expr<S> > op(x);
665 for(op.i=0; op.i<xsz; ++op.i) {
680 this->
val() -= x.val();
686 template <
typename S>
689 const int xsz = x.size(), sz = this->size();
693 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ ) 694 if ((xsz != sz) && (xsz != 0) && (sz != 0))
695 throw "Fad Error: Attempt to assign with incompatible sizes";
698 if (Expr<S>::is_linear) {
701 if (x.hasFastAccess())
702 for(
int i=0; i<sz; ++i)
705 for (
int i=0; i<sz; ++i)
709 this->resizeAndZero(xsz);
710 if (x.hasFastAccess())
711 for(
int i=0; i<xsz; ++i)
714 for (
int i=0; i<xsz; ++i)
720 for (
int i=0; i<sz; ++i)
731 if (x.hasFastAccess()) {
733 FastLocalAccumOp< Expr<S> > op(x);
736 for(op.i=0; op.i<xsz; ++op.i) {
750 SlowLocalAccumOp< Expr<S> > op(x);
753 for(op.i=0; op.i<xsz; ++op.i) {
770 this->resizeAndZero(xsz);
772 if (x.hasFastAccess()) {
774 FastLocalAccumOp< Expr<S> > op(x);
777 for(op.i=0; op.i<xsz; ++op.i) {
790 SlowLocalAccumOp< Expr<S> > op(x);
793 for(op.i=0; op.i<xsz; ++op.i) {
812 for (
int i=0; i<sz; ++i)
826 template <
typename S>
829 const int xsz = x.size(), sz = this->size();
833 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ ) 834 if ((xsz != sz) && (xsz != 0) && (sz != 0))
835 throw "Fad Error: Attempt to assign with incompatible sizes";
838 if (Expr<S>::is_linear) {
841 if (x.hasFastAccess())
842 for(
int i=0; i<sz; ++i)
845 for (
int i=0; i<sz; ++i)
849 this->resizeAndZero(xsz);
850 if (x.hasFastAccess())
851 for(
int i=0; i<xsz; ++i)
852 this->
fastAccessDx(i) = - v*x.fastAccessDx(i) / (xval*xval);
854 for (
int i=0; i<xsz; ++i)
860 for (
int i=0; i<sz; ++i)
873 if (x.hasFastAccess()) {
875 FastLocalAccumOp< Expr<S> > op(x);
878 for(op.i=0; op.i<xsz; ++op.i) {
892 SlowLocalAccumOp< Expr<S> > op(x);
895 for(op.i=0; op.i<xsz; ++op.i) {
912 this->resizeAndZero(xsz);
914 if (x.hasFastAccess()) {
916 FastLocalAccumOp< Expr<S> > op(x);
919 for(op.i=0; op.i<xsz; ++op.i) {
932 SlowLocalAccumOp< Expr<S> > op(x);
935 for(op.i=0; op.i<xsz; ++op.i) {
954 for (
int i=0; i<sz; ++i)
978 template <
typename ExprT>
979 struct FastLocalAccumOp {
980 typedef typename ExprT::value_type
value_type;
981 static const int N = ExprT::num_args;
987 FastLocalAccumOp(
const ExprT& x_) : x(x_) {
990 template <
typename ArgT>
992 void operator () (ArgT arg)
const {
993 const int Arg = ArgT::value;
994 t += partials[Arg] * x.template getTangent<Arg>(i);
998 template <
typename ExprT>
1002 FastLocalAccumOp<ExprT>(x_) {}
1003 template <
typename ArgT>
1006 const int Arg = ArgT::value;
1007 if (this->x.template isActive<Arg>())
1008 this->t += this->partials[Arg] * this->x.template getTangent<Arg>(this->i);
1015 template <
typename T,
typename Storage>
1018 os << x.val() <<
" [";
1020 for (
int i=0; i< x.size(); i++) {
1021 os <<
" " << x.dx(i);
1032 #endif // SACADO_ELRFAD_GENERALFAD_HPP
RemoveConst< T >::type value_type
Typename of values.
KOKKOS_INLINE_FUNCTION GeneralFad()
Default constructor.
KOKKOS_INLINE_FUNCTION SACADO_ENABLE_EXPR_FUNC(bool) isEqualTo(const Expr< S > &x) const
Returns whether two Fad objects have the same values.
#define SACADO_ENABLE_VALUE_CTOR_DECL
KOKKOS_INLINE_FUNCTION GeneralFad(const Storage &s)
Constructor with supplied storage s.
KOKKOS_INLINE_FUNCTION bool isPassive() const
Returns true if derivative array is empty.
#define SACADO_ENABLE_EXPR_CTOR_DECL
KOKKOS_INLINE_FUNCTION void setUpdateValue(bool update_val)
Set whether this Fad object should update values.
#define KOKKOS_INLINE_FUNCTION
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
KOKKOS_INLINE_FUNCTION SlowLocalAccumOp(const ExprT &x_)
KOKKOS_INLINE_FUNCTION void operator()(ArgT arg) const
Base template specification for testing equivalence.
KOKKOS_INLINE_FUNCTION bool updateValue() const
Return whether this Fad object has an updated value.
std::ostream & operator<<(std::ostream &os, const GeneralFad< T, Storage > &x)
KOKKOS_INLINE_FUNCTION GeneralFad(const GeneralFad &x)
Copy constructor.
KOKKOS_INLINE_FUNCTION GeneralFad(const S &x, SACADO_ENABLE_VALUE_CTOR_DECL)
Constructor with supplied value x.
DerivInit
Enum use to signal whether the derivative array should be initialized in AD object constructors...
Forward-mode AD class templated on the storage for the derivative array.
Wrapper for a generic expression template.
KOKKOS_INLINE_FUNCTION void diff(const int ith, const int n)
Set GeneralFad object as the ith independent variable.
KOKKOS_INLINE_FUNCTION ~GeneralFad()
Destructor.
KOKKOS_INLINE_FUNCTION SACADO_ENABLE_VALUE_FUNC(GeneralFad &) operator
Assignment operator with constant right-hand-side.
Initialize the derivative array.
ScalarType< value_type >::type scalar_type
Typename of scalar's (which may be different from T)
KOKKOS_INLINE_FUNCTION GeneralFad(const Expr< S > &x, SACADO_ENABLE_EXPR_CTOR_DECL)
Copy constructor from any Expression object.
KOKKOS_INLINE_FUNCTION GeneralFad(const int sz, const T &x, const DerivInit zero_out=InitDerivArray)
Constructor with size sz and value x.
KOKKOS_INLINE_FUNCTION GeneralFad(const int sz, const int i, const T &x)
Constructor with size sz, index i, and value x.
KOKKOS_INLINE_FUNCTION int availableSize() const
Returns number of derivative components that can be stored without reallocation.
KOKKOS_INLINE_FUNCTION void setIsConstant(bool is_const)
Set whether variable is constant.
KOKKOS_INLINE_FUNCTION bool hasFastAccess() const
Returns true if derivative array is not empty.