16 #include "../../linalg/dual.hpp"
20 #ifdef MFEM_USE_CODIPACK
28 #ifdef MFEM_USE_ADFORWARD
50 template<
int vector_size=1,
int state_size=1,
int param_size=0>
73 #ifdef MFEM_USE_ADFORWARD
75 jac.
SetSize(vector_size, state_size);
80 for (
int i=0; i<state_size; i++)
82 ad_state[i].setValue(vstate[i]);
83 ad_state[i].setGradient(0.0);
85 for (
int ii=0; ii<state_size; ii++)
87 ad_state[ii].setGradient(1.0);
88 F(vparam,ad_state,ad_result);
89 for (
int jj=0; jj<vector_size; jj++)
91 jac(jj,ii)=ad_result[jj].getGradient();
93 ad_state[ii].setGradient(0.0);
96 #else // use reverse mode
97 jac.
SetSize(vector_size, state_size);
102 for (
int i=0; i<state_size; i++)
104 ad_state[i]=vstate[i];
107 ad::ADFloatType::TapeType& tape =ad::ADFloatType::getGlobalTape();
108 typename ad::ADFloatType::TapeType::Position pos=tape.getPosition();
111 for (
int ii=0; ii<state_size; ii++) { tape.registerInput(ad_state[ii]); }
112 F(vparam,ad_state,ad_result);
113 for (
int ii=0; ii<vector_size; ii++) { tape.registerOutput(ad_result[ii]); }
116 for (
int jj=0; jj<vector_size; jj++)
118 ad_result[jj].setGradient(1.0);
120 for (
int ii=0; ii<state_size; ii++)
122 jac(jj,ii)=ad_state[ii].getGradient();
124 tape.clearAdjoints();
125 ad_result[jj].setGradient(0.0);
132 std::function<void(mfem::Vector&, ad::ADVectorType&, ad::ADVectorType&)> F;
144 template<
template<
typename,
typename,
typename,
int,
int,
int>
class TFunctor
145 ,
int vector_size=1,
int state_size=1,
int param_size=0>
161 #ifdef MFEM_USE_ADFORWARD
163 jac.
SetSize(vector_size, state_size);
168 for (
int i=0; i<state_size; i++)
170 aduu[i].setValue(uu[i]);
171 aduu[i].setGradient(0.0);
174 for (
int ii=0; ii<state_size; ii++)
176 aduu[ii].setGradient(1.0);
178 for (
int jj=0; jj<vector_size; jj++)
180 jac(jj,ii)=rr[jj].getGradient();
182 aduu[ii].setGradient(0.0);
185 #else // end MFEM_USE_ADFORWARD
187 jac.
SetSize(vector_size, state_size);
192 for (
int i=0; i<state_size; i++)
197 ad::ADFloatType::TapeType& tape =ad::ADFloatType::getGlobalTape();
198 typename ad::ADFloatType::TapeType::Position pos=tape.getPosition();
201 for (
int ii=0; ii<state_size; ii++) { tape.registerInput(aduu[ii]); }
203 for (
int ii=0; ii<vector_size; ii++) { tape.registerOutput(rr[ii]); }
205 for (
int jj=0; jj<vector_size; jj++)
207 rr[jj].setGradient(1.0);
209 for (
int ii=0; ii<state_size; ii++)
211 jac(jj,ii)=aduu[ii].getGradient();
213 tape.clearAdjoints();
214 rr[jj].setGradient(0.0);
224 vector_size, state_size, param_size> tf;
227 vector_size, state_size, param_size> rf;
240 template<
template<
typename,
typename,
typename,
int,
int>
class TFunctor
241 ,
int state_size=1,
int param_size=0>
250 return rf(vparam,uu);
264 #ifdef MFEM_USE_ADFORWARD
269 for (
int i=0; i<state_size; i++)
271 aduu[i].setValue(uu[i]);
272 aduu[i].setGradient(0.0);
277 for (
int ii=0; ii<state_size; ii++)
279 aduu[ii].setGradient(1.0);
281 rr[ii]=rez.getGradient();
282 aduu[ii].setGradient(0.0);
289 for (
int i=0; i<state_size; i++)
294 ad::ADFloatType::TapeType& tape =ad::ADFloatType::getGlobalTape();
295 typename ad::ADFloatType::TapeType::Position pos=tape.getPosition();
298 for (
int ii=0; ii<state_size; ii++) { tape.registerInput(aduu[ii]); }
301 tape.registerOutput(rez);
304 rez.setGradient(1.0);
306 for (
int i=0; i<state_size; i++)
308 rr[i]=aduu[i].getGradient();
321 #ifdef MFEM_USE_ADFORWARD
327 typedef codi::RealForwardGen<ADFType>
ADSType;
336 typedef codi::RealReverseGen<ADFType>
ADSType;
347 #ifdef MFEM_USE_ADFORWARD
353 for (
int ii = 0; ii < state_size; ii++)
355 aduu[ii].value().value()=uu[ii];
356 aduu[ii].value().gradient()=0.0;
357 aduu[ii].gradient().value()=0.0;
358 aduu[ii].gradient().gradient()=0.0;
361 for (
int ii = 0; ii < state_size; ii++)
363 aduu[ii].value().gradient()=1.0;
364 for (
int jj=0; jj<(ii+1); jj++)
366 aduu[jj].gradient().value()=1.0;
368 jac(ii,jj)=rez.gradient().gradient();
369 jac(jj,ii)=jac(ii,jj);
370 aduu[jj].gradient().value()=0.0;
372 aduu[ii].value().gradient()=0.0;
381 for (
int ii=0; ii < state_size ; ii++)
383 aduu[ii].value().value()=uu[ii];
388 ADSType::TapeType& tape = ADSType::getGlobalTape();
389 typename ADSType::TapeType::Position pos;
390 for (
int ii = 0; ii < state_size ; ii++)
392 pos=tape.getPosition();
395 for (
int jj=0; jj < state_size; jj++)
397 if (jj==ii) {aduu[jj].value().gradient()=1.0;}
398 else {aduu[jj].value().gradient()=0.0;}
399 tape.registerInput(aduu[jj]);
403 tape.registerOutput(rez);
406 rez.gradient().value()=1.0;
409 for (
int jj=0; jj<(ii+1); jj++)
411 jac(ii,jj)=aduu[jj].gradient().gradient();
412 jac(jj,ii)=jac(ii,jj);
428 state_size, param_size> sf;
432 #else // end MFEM_USE_CODIPACK
441 typedef internal::dual<double, double>
ADFloatType;
453 template<
int vector_size=1,
int state_size=1,
int param_size=0>
454 class VectorFuncAutoDiff
475 jac.
SetSize(vector_size, state_size);
481 for (
int ii = 0; ii < state_size; ii++)
483 aduu[ii].gradient = 1.0;
485 for (
int jj = 0; jj < vector_size; jj++)
487 jac(jj, ii) = rr[jj].gradient;
489 aduu[ii].gradient = 0.0;
495 std::function<void(mfem::Vector&, ad::ADVectorType&, ad::ADVectorType&)> F;
529 template<
template<
typename,
typename,
typename,
int,
int,
int>
class TFunctor
530 ,
int vector_size=1,
int state_size=1,
int param_size=0>
531 class QVectorFuncAutoDiff
535 typedef internal::dual<double, double> ADFType;
537 typedef TAutoDiffVector<ADFType> ADFVector;
539 typedef TAutoDiffDenseMatrix<ADFType> ADFDenseMatrix;
547 func(vparam, uu, rr);
556 jac.
SetSize(vector_size, state_size);
562 for (
int ii = 0; ii < state_size; ii++)
564 aduu[ii].gradient = 1.0;
565 Eval(vparam, aduu, rr);
566 for (
int jj = 0; jj < vector_size; jj++)
568 jac(jj, ii) = rr[jj].gradient;
570 aduu[ii].gradient = 0.0;
578 void Eval(
const Vector &vparam, ADFVector &uu, ADFVector &rr)
583 TFunctor<double,
const Vector, Vector,
584 vector_size, state_size, param_size> func;
586 TFunctor<ADFType,
const Vector, ADFVector,
587 vector_size, state_size, param_size> tf;
614 template<
template<
typename,
typename,
typename,
int,
int>
class TFunctor
615 ,
int state_size=1,
int param_size=0>
616 class QFunctionAutoDiff
620 typedef internal::dual<double, double>
ADFType;
622 typedef TAutoDiffVector<ADFType>
ADFVector;
626 typedef internal::dual<ADFType, ADFType>
ADSType;
628 typedef TAutoDiffVector<ADSType>
ADSVector;
637 return tf(vparam,uu);
654 for (
int ii = 0; ii < n; ii++)
656 aduu[ii].gradient = 1.0;
657 rez = ff(vparam, aduu);
658 rr[ii] = rez.gradient;
659 aduu[ii].gradient = 0.0;
679 for (
int ii = 0; ii < n; ii++)
681 aduu[ii].value =
ADFType{uu[ii], 0.0};
682 aduu[ii].gradient =
ADFType{0.0, 0.0};
685 for (
int ii = 0; ii < n; ii++)
687 aduu[ii].value =
ADFType{uu[ii], 1.0};
688 for (
int jj = 0; jj < (ii + 1); jj++)
690 aduu[jj].gradient =
ADFType{1.0, 0.0};
691 ADSType rez = sf(vparam, aduu);
692 jac(ii, jj) = rez.gradient.gradient;
693 jac(jj, ii) = rez.gradient.gradient;
694 aduu[jj].gradient =
ADFType{0.0, 0.0};
696 aduu[ii].value =
ADFType{uu[ii], 0.0};
702 TFunctor<double, const Vector, Vector, state_size, param_size> tf;
703 TFunctor<ADFType, const Vector, ADFVector, state_size, param_size> ff;
704 TFunctor<ADSType, const Vector, ADSVector, state_size, param_size> sf;
void VectorFunc(const mfem::Vector &vparam, mfem::Vector &uu, mfem::Vector &rr)
void VectorFunc(const mfem::Vector &vparam, mfem::Vector &uu, mfem::Vector &rr)
Provides the same functionality as Grad.
void VectorFunc(const Vector &vparam, Vector &uu, Vector &rr)
Provides the same functionality as Grad.
void Grad(const Vector &vparam, Vector &uu, Vector &rr)
void SetSize(int s)
Resize the vector to size s.
void Grad(const mfem::Vector &vparam, mfem::Vector &uu, mfem::Vector &rr)
Data type dense matrix using column-major storage.
int Size() const
Returns the size of the vector.
codi::RealForwardGen< ADFType > ADSType
codi::RealForward ADFloatType
Forward AD type declaration.
double Eval(const Vector &vparam, Vector &uu)
codi::RealForwardGen< double > ADFType
VectorFuncAutoDiff(std::function< void(mfem::Vector &, ad::ADVectorType &, ad::ADVectorType &)> F_)
void VectorFunc(const Vector &vparam, Vector &uu, Vector &rr)
void Jacobian(mfem::Vector &vparam, mfem::Vector &uu, mfem::DenseMatrix &jac)
void Jacobian(mfem::Vector &vparam, mfem::Vector &uu, mfem::DenseMatrix &jac)
TAutoDiffDenseMatrix< ADFType > ADFDenseMatrix
void Jacobian(mfem::Vector &vparam, mfem::Vector &uu, mfem::DenseMatrix &jac)
Provides same functionality as Hessian.
TAutoDiffVector< ADFloatType > ADVectorType
Vector type for AD-numbers.
TAutoDiffVector< ADSType > ADSVector
Templated vector data type.
codi::RealReverseGen< ADFType > ADSType
TAutoDiffDenseMatrix< ADSType > ADSDenseMatrix
void Hessian(mfem::Vector &vparam, mfem::Vector &uu, mfem::DenseMatrix &jac)
TAutoDiffVector< ADFType > ADFVector
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Templated dense matrix data type.
void Jacobian(mfem::Vector &vparam, mfem::Vector &vstate, mfem::DenseMatrix &jac)
double Eval(const mfem::Vector &vparam, mfem::Vector &uu)
TAutoDiffDenseMatrix< ADFloatType > ADMatrixType
Matrix type for AD-numbers.