Geomi
DiagonalStepInternals.hpp
1 #ifndef DEF_RKMK_DIAGONALSTEPINTERNALS
2 #define DEF_RKMK_DIAGONALSTEPINTERNALS
3 
4 //#include "include/Step/AbstractStep.hpp"
5 //#include "RKMK_Abstract_Step.hpp"
6 //#include "../Common/Common_NOXVector.hpp"
7 //#include "../Common/Common_NOXGroup.hpp"
8 
9 namespace RKMK {
10 
11 template <typename T_LIE_ALGEBRA,
12  int T_N_INTERNAL_STAGES,
13  typename T_M = double>
14 class DiagonalStepInternals : public StepInternals<T_LIE_ALGEBRA,T_N_INTERNAL_STAGES,T_M>, public ::Abstract::NOXStep<NOXVector<T_LIE_ALGEBRA::DOF>,1>
15 {
16 private:
17  int m_fevals;
18  T_LIE_ALGEBRA m_initialGuess;
19  T_LIE_ALGEBRA m_solution;
20  int m_currentStep;
21 
22 public:
25  {
26  m_fevals = 0;
27  m_initialGuess = T_LIE_ALGEBRA::Zero();
28  m_solution = T_LIE_ALGEBRA::Zero();
29  m_currentStep = 0;
30  }
31 
33  getInitialGuess ()
35 
36  int
37  currentStep ()
38  { return m_currentStep; }
39 
40  // TODO : maybe some small checks ?
41  void
42  currentStep (int c)
43  { m_currentStep = c; }
44 
45  void
46  setSolutionK (const NOXVector<T_LIE_ALGEBRA::DOF>& x)
47  { this->m_k[m_currentStep] = T_LIE_ALGEBRA(x); }
48 
49  bool
51  {
52  bool success = false;
53 
54  this->m_k[m_currentStep] = T_LIE_ALGEBRA(x);
55 
56  T_LIE_ALGEBRA omega0 = T_LIE_ALGEBRA::Zero();
57  T_LIE_ALGEBRA omega = omega0;
58  T_LIE_ALGEBRA res = omega0;
59  T_LIE_ALGEBRA A;
60  int i,j;
61 
62  omega = omega0;
63  for (j=0; j<=m_currentStep; j++) {
64  omega += this->m_k[j]*this->a_coeffs(m_currentStep,j);
65  }
66  omega = this->m_h*omega;
67  this->m_problem.computeA(A,omega.exp()*this->m_y0);
68  res = omega.computeDExpRInv(A,this->m_order_q) - this->m_k[m_currentStep];
69 
70  f = res.toVector();
71 
72  m_fevals++;
73  return true;
74  }
75 
76  bool
77  computeJacobian (Eigen::Matrix<double,T_LIE_ALGEBRA::DOF,T_LIE_ALGEBRA::DOF>& J, const NOXVector<T_LIE_ALGEBRA::DOF>& x)
78  {
79  this->m_k[m_currentStep] = T_LIE_ALGEBRA(x);
80 
81  int i,j,p;
82  double factorial;
83 
84  // Setting up variables
85 
86  double a = this->a_coeffs(m_currentStep,m_currentStep);
87  // TODO : Check if a is zero and act accordingly
88 
89  T_LIE_ALGEBRA Gen;
90 
91  T_LIE_ALGEBRA w = T_LIE_ALGEBRA::Zero();
92  for (j=0; j<=m_currentStep; j++) {
93  w += this->a_coeffs(m_currentStep,j)*this->m_k[j];
94  }
95  w = this->m_h*w;
96 
97  NOXVector<T_LIE_ALGEBRA::DOF> Y = w.exp()*this->m_y0;
98 
99  T_LIE_ALGEBRA A;
100  this->computeA(A,Y);
101 
102  std::vector<T_LIE_ALGEBRA> JA;
103  this->computeJacobianA(JA,Y);
104  Eigen::Matrix<double,T_LIE_ALGEBRA::DOF,T_LIE_ALGEBRA::DOF> MatJA;
105  for (i=0; i<T_LIE_ALGEBRA::DOF; i++) {
106  // TODO : row ? col ?
107  MatJA.row(i) = (JA[i]).toVector();
108  }
109 
110  T_LIE_ALGEBRA dAdk;
111  T_LIE_ALGEBRA dfdk;
112  T_LIE_ALGEBRA daddk;
113  T_LIE_ALGEBRA ad;
114 
115  // Computing dF/dk_p
116 
117  for (p=0; p<T_LIE_ALGEBRA::DOF; p++) {
118  Gen = T_LIE_ALGEBRA::Generator(p);
119  dAdk = T_LIE_ALGEBRA(this->m_h*a*MatJA*w.partialExp(p)*this->m_y0);
120  dfdk = dAdk;
121  // d(ad^k_w(A))/dk
122  if (this->m_order_q > 0) {
123  daddk = dAdk;
124  ad = A;
125  factorial = 1.0;
126  for (i=0; i<this->m_order_q; i++) {
127  factorial = factorial*(i+1);
128  daddk = this->m_h*a*Gen.bracket(ad) + w.bracket(daddk);
129  if (i%2==0) { // odd Bernoulli are 0, so no need for the update
130  dfdk += (BERNOULLI_NUMBERS[i]/factorial)*daddk;
131  }
132  ad = w.bracket(ad);
133  }
134  }
135  // col ? row ?
136  J.col(p) = (dfdk-Gen).toVector();
137  }
138 
139  return true;
140  }
141 };
142 }
143 
144 #endif
Definition: DiagonalStepInternals.hpp:14
Definition: Abstract_Problem.hpp:10
Definition: Abstract_Integrator.hpp:4
Definition: StepInternals.hpp:11
Definition: NOXVector.hpp:14
Definition: Abstract_NOXStep.hpp:12