My Project
AbstractRKMKStep.hpp
1 #ifndef DEF_ABSTRACT_RKMK_STEP
2 #define DEF_ABSTRACT_RKMK_STEP
3 
4 #include <algorithm> // std::max
5 #include <iterator> // C style array copy
6 
7 #include "include/Problem/ProblemInterface.hpp"
8 #include "include/Common/Utils.hpp"
9 
10 
11 namespace RKMK {
12 template <typename T_M,
13  typename T_Q,
14  typename T_LIE_ALGEBRA,
15  int T_N_INTERNAL_STAGES>
17 {
18 protected:
19  T_Q m_y0;
20  T_M m_h;
21 
22  T_LIE_ALGEBRA m_solution;
23 
25 
26  double m_a_coeffs [T_N_INTERNAL_STAGES * T_N_INTERNAL_STAGES];
27  double m_b_coeffs [T_N_INTERNAL_STAGES];
28  T_LIE_ALGEBRA m_k [T_N_INTERNAL_STAGES];
29  unsigned int m_order_q;
30 
31 public:
33  : m_interface(interface)
34  { setTruncatureOrder(); }
35 
37  newFromProblem (Abstract::Problem<T_M,T_Q,T_LIE_ALGEBRA>& interface)
38  {
40  return *res;
41  }
42 
43  void
45  {
46  // TODO: Cod'e avec le cul, il faut verifier tout ca.
47  m_y0 = other.m_y0;
48  m_h = other.m_h;
49  m_solution = other.m_solution;
50  m_interface = other.m_interface;
51  std::copy(std::begin(other.m_a_coeffs),std::end(other.m_a_coeffs),std::begin(m_a_coeffs));
52  std::copy(std::begin(other.m_b_coeffs),std::end(other.m_b_coeffs),std::begin(m_b_coeffs));
53  std::copy(std::begin(other.m_k),std::end(other.m_k),std::begin(m_k));
54  m_order_q = other.m_order_q;
55  }
56 
57  double
58  a_coeffs (int i, int j) const
59  { return m_a_coeffs[i*T_N_INTERNAL_STAGES+j]; }
60 
61  void
62  setData (T_M h_var, T_Q y0_var)
63  {
64  m_h = h_var;
65  m_y0 = y0_var;
66  }
67 
68  bool
69  setCoeffs (std::vector<double> a, std::vector<double> b)
70  {
71  if ((a.size()!=T_N_INTERNAL_STAGES*T_N_INTERNAL_STAGES) || (b.size()!=T_N_INTERNAL_STAGES))
72  return false;
73  for (int i=0; i<T_N_INTERNAL_STAGES; i++)
74  m_b_coeffs[i] = b[i];
75  for (int i=0; i<T_N_INTERNAL_STAGES*T_N_INTERNAL_STAGES; i++)
76  m_a_coeffs[i] = a[i];
77  return true;
78  }
79 
80  void
81  setTruncatureOrder ( )
82  { m_order_q = std::max(0,T_N_INTERNAL_STAGES-2); }
83 
88  bool
90  {
91  bool success = false;
92 
93  T_LIE_ALGEBRA omega0 = T_LIE_ALGEBRA::Zero();
94  T_LIE_ALGEBRA omega = omega0;
95  T_LIE_ALGEBRA sol = omega0;
96  T_LIE_ALGEBRA A;
97  int i,j;
98 
99  for (i=0; i<T_N_INTERNAL_STAGES; i++) {
100 
101  // do something smarter if a(i,j) is zero
102  omega = omega0;
103  for (j=0; j<T_N_INTERNAL_STAGES; j++) {
104  omega += this->m_k[j]*this->m_h*this->a_coeffs(i,j);
105  }
106 
107  this->m_interface.computeA(A,omega.exp()*this->m_y0);
108  // TODO: should you really overwrite m_k[i] ?
109  this->m_k[i] = omega.computeDExpRInv(A,this->m_order_q);
110  sol += this->m_b_coeffs[i]*this->m_h*this->m_k[i];
111  }
112 
113  this->m_solution = sol;
114  success = true;
115 
116  return success;
117  }
118 
119  const T_Q
120  reconstruct (const NOXVector<T_Q::DOF>& solution)
121  {
122  T_LIE_ALGEBRA w(solution);
123  return T_Q(w.exp()*m_y0);
124  }
125 
126  const T_Q
127  reconstruct ()
128  { return this->reconstruct(this->m_solution.toVector()); }
129 
130  /*
131  const T_Q
132  reconstruct ()
133  {
134  T_LIE_ALGEBRA w = T_LIE_ALGEBRA::Zero();
135  for (int i=0; i<T_N_INTERNAL_STAGES; i++)
136  w += m_h*m_b_coeffs[i]*m_k[i];
137  return T_Q(w.exp()*m_y0);
138  }
139  */
140 
141  bool
142  computeA (T_LIE_ALGEBRA& A, const T_Q& y)
143  { return m_interface.computeA(A,y); }
144 
145  bool
146  computeJacobianA (std::vector<T_LIE_ALGEBRA>& JA, const T_Q& y)
147  { return m_interface.computeJacobianA(JA,y); }
148 
149 };
150 } // namespace RKMK
151 
152 
153 namespace RKMK {
154 namespace Abstract {
160 template <typename T_M,
161  typename T_Q,
162  typename T_LIE_ALGEBRA,
163  int T_N_INTERNAL_STAGES>
164 class Step
165 {
166 protected:
169  char m_type;
170 
171 public:
172  static const char TYPE_UNKNOWN = 0;
173  static const char TYPE_EXPLICIT = 1;
174  static const char TYPE_DIAGONAL_IMPLICIT = 2;
175 
176 public:
178  // Abstract::RKMKStepInternals<T_M,T_Q,T_LIE_ALGEBRA,T_N_INTERNAL_STAGES>& internals)
179  : m_interface(interface)
180  //m_internals(internals)
181  //m_internals(Abstract::RKMKStepInternals<T_M,T_Q,T_LIE_ALGEBRA,T_N_INTERNAL_STAGES>::newFromProblem(interface))
182  {
184  setType();
185  }
186 
187  /*
188  RKMKStep<T_M,T_Q,T_LIE_ALGEBRA,T_N_INTERNAL_STAGES> (Abstract::Problem<T_M,T_Q,T_LIE_ALGEBRA>& interface,
189  std::vector<double> a,
190  std::vector<double> b)
191  : m_interface(interface),
192  m_internals(Abstract::RKMKStepInternals<T_M,T_Q,T_LIE_ALGEBRA,T_N_INTERNAL_STAGES>::newFromProblem(interface))
193  { m_internals.setCoeffs(a,b); }
194  */
195 
197  { }
198 
199  bool
200  setCoeffs (std::vector<double> a, std::vector<double> b) const
201  { return m_internals->setCoeffs(a,b); }
202 
203  void
204  setData (T_M h_var, T_Q y0_var)
205  { m_internals->setData(h_var,y0_var); }
206 
207  void
208  setType ( )
209  {
210  int i,j;
211  bool tmp_isZero;
212  bool isExplicit = true;
213  bool isDIRK = true;
214 
215  for (i=0; i<T_N_INTERNAL_STAGES; i++) {
216  isExplicit &= isZero<double>(m_internals->a_coeffs(i,i));
217  for (j=i+1; j<T_N_INTERNAL_STAGES; j++) {
218  tmp_isZero = isZero<double>(m_internals->a_coeffs(i,j));
219  isExplicit &= tmp_isZero;
220  isDIRK &= tmp_isZero;
221  }
222  }
223 
224  if (isExplicit)
225  m_type = TYPE_EXPLICIT;
226  else if (isDIRK)
227  m_type = TYPE_DIAGONAL_IMPLICIT;
228  else
229  m_type = TYPE_UNKNOWN;
230  }
231 
232  const char
233  type ()
234  { return m_type; }
235 
236  virtual const T_Q
237  makeStep () = 0;
238 };
239 } // namespace Abstract
240 } // namespace RKMK
241 
242 #endif
Definition: ProblemInterface.hpp:10
Definition: AbstractRKMKStep.hpp:16
Definition: Factory.hpp:8
bool computeSolution(void)
Definition: AbstractRKMKStep.hpp:89
Definition: AbstractRKMKStep.hpp:164
Definition: AbstractStep.hpp:9
Definition: NOXVector.hpp:14