Plugins
simple_integrator.hpp
Go to the documentation of this file.
2 
3 namespace ug {
4 
6 template<class TDomain, class TAlgebra>
8  public INonlinearTimeIntegrator<TDomain, TAlgebra>,
9  public ITimeDiscDependentObject<TAlgebra>,
10  public DebugWritingObject<TAlgebra>
11 {
12 protected:
14 
15 public:
22 
23  // constructor
25  : base_type(), ITimeDiscDependentObject<TAlgebra>(tDisc),
28 
29  {}
30 
32  : base_type(), ITimeDiscDependentObject<TAlgebra>(tDisc),
33  m_spBanachSpace(spSpace),
35  {}
36 
37 
39  {
41  if (tdisc.num_stages() == 1)
42  return apply_single_stage(u1,t1,u0,t0);
43  else
44  return apply_multi_stage(u1,t1,u0,t0);
45  }
46 
48  { m_spDerivative = udot; }
49 
51  { return m_spDerivative; }
52 
54  { return m_initial_consistency_error; }
55 
57  { m_spBanachSpace = spSpace; }
58 
59 protected:
62 
63  inline bool hasTerminated(double tCurrent, double tStart, double tFinal) const
64  {
65  /*return (! ((tCurrent < tFinal) && (tFinal-tCurrent > base_type::m_precisionBound)));*/
66  return tCurrent >= tFinal || tFinal-tCurrent < (tFinal-tStart)*base_type::m_precisionBound;
67  }
68 
71 
73 
75 };
76 
77 
78 template<typename TDomain, typename TAlgebra>
80 {
82 
83  // short-cuts
84  GridLevel const &gl = u0->grid_level();
85  time_disc_type &tdisc = *tdisc_dep_type::m_spTimeDisc;
86  typename base_type::solver_type &solver = *base_type::m_spSolver;
87 
88  // create solution vector & right hand side
90 
91  // init solution time series
92  SmartPtr<vector_time_series_type> m_spSolTimeSeries;
93  m_spSolTimeSeries=make_sp(new vector_time_series_type());
94  m_spSolTimeSeries->clear();
95  m_spSolTimeSeries->push(u0->clone(), t0);
96 
97  // init solver (and matrix operator)
99  spAssOp = make_sp(new typename base_type::assembled_operator_type(tdisc_dep_type::m_spTimeDisc, gl));
100  solver.init(spAssOp);
101 
102  // integrate
103  double t = t0;
104  number currdt = base_type::m_dt;
105  int step = 1;
106 
107  double final_dt = base_type::m_dt;
108 
109  if(!base_type::m_bNoLogOut)
110  UG_LOG("+++ Integrating: [\t"<< t0 <<"\t, \t"<< t1 <<"\t] with\t" << currdt <<"\n");
111 
112  while(!hasTerminated(t, t0, t1)) {
113  if(!base_type::m_bNoLogOut)
114  UG_LOG("+++ Timestep +++" << step << "\n");
115 
116  if (this->debug_writer_valid())
117  {
118  char debug_name_ext[16]; snprintf(debug_name_ext, 16, "%04d", step);
119  this->enter_debug_writer_section(std::string("SimpleTimeIntegrator_step") + debug_name_ext);
120  }
121 
122  // determine step size
123  UG_COND_THROW(currdt < base_type::get_dt_min(), "Time step size below minimum. ABORTING!")
124  number dt = std::min(currdt, t1-t);
125  final_dt = dt;
126 
127  // prepare step
128  tdisc.prepare_step(m_spSolTimeSeries, dt);
129  if (solver.prepare(*u1) == false)
130  {
131  if(!base_type::m_bNoLogOut)
132  UG_LOG("Initialization failed! RETRY");
133 
134  currdt *= base_type::get_reduction_factor();
135  continue;
136  }
137  //UG_LOG("m_spSolTimeSeries.size="<< m_spSolTimeSeries->size());
138 
139  // execute step
140  if (solver.apply(*u1))
141  {
142  //
143  // ACCEPT step
144  //
145 
146  // post prcess (e.g. physics)
147  if(!base_type::m_bNoLogOut)
148  {
149  // m_spSolTimeSeries->oldest() actually holds a pointer to a grid function
150  // but as the time series does not know this, we have to cast ourselves
151  // SmartPtr<grid_function_type> tmpOld = m_spSolTimeSeries->oldest().template cast_static<grid_function_type>();
152  this->notify_finalize_step(u1, step, t+dt, dt);
153  }
154 
155  // update time
156  t += dt;
157 
158  // push updated solution into time series (and continue)
159  //SmartPtr<typename base_type::vector_type> utmp = m_spSolTimeSeries->oldest();
160  //VecAssign(*utmp, static_cast<typename base_type::vector_type> (*u1) );
161  uold = m_spSolTimeSeries->push_discard_oldest(u1->clone(), t).template cast_static<grid_function_type>();
162  }
163  else
164  {
165  //
166  // REJECT step
167  //
168  UG_LOG("Solution failed! RETRY");
169  currdt *= base_type::get_reduction_factor();
170  continue;
171  }
172 
173  // consistency check
174  if (step == 1 && m_spDerivative.valid())
175  {
176  UG_LOG("Computing consistency error: "<< std::endl);
177  UG_ASSERT(static_cast<typename base_type::vector_type*> (&*u1) != &(*u0),
178  "Huhh: Different vectors required!");
179  *m_spDerivative = *u0;
180  m_initial_consistency_error = m_spBanachSpace->distance(*m_spDerivative, *u1);
181  }
182 
183  step++;
184  // tdisc.finish_step_elem(m_spSolTimeSeries, dt);
185 
186  this->leave_debug_writer_section();
187  }
188 
189  if(base_type::m_bNoLogOut)
190  {
191  this->notify_finalize_step(u1, /*uold,*/ step, t, final_dt);
192  }
193 
194 
195  if (m_spDerivative.valid())
196  {
197 
198  //
199  // approximate derivative (by forward difference)
200  //
201  UG_ASSERT(static_cast<typename base_type::vector_type*> (&*u1) != &(*uold),
202  "Huhh: Different vectors required!");
203 
204  VecScaleAdd(static_cast<typename TAlgebra::vector_type&>(*m_spDerivative),
205  1.0/final_dt, static_cast<typename TAlgebra::vector_type&>(*u1),
206  -1.0/final_dt, static_cast<typename TAlgebra::vector_type&>(*uold));
207 
208  }
209 
210  m_spSolTimeSeries->clear();
211 
212  return true;
213 
214 };
215 
216 template<typename TDomain, typename TAlgebra>
218 {
219 
221 
222  // short-cuts
223  GridLevel const &gl = u0->grid_level();
224  time_disc_type &tdisc = *tdisc_dep_type::m_spTimeDisc;
225  typename base_type::solver_type &solver = *base_type::m_spSolver;
226 
227  //using TimeIntegratorSubject<TDomain,TAlgebra>::notify_step_postprocess;
228 
229  // create solution vector & right hand side
230  SmartPtr<grid_function_type> uold = u0->clone();
231 
232  // init solution time series
233  SmartPtr<vector_time_series_type> m_spSolTimeSeries;
234  m_spSolTimeSeries=make_sp(new vector_time_series_type());
235  m_spSolTimeSeries->clear();
236  m_spSolTimeSeries->push(u0->clone(), t0);
237 
238  // init solver (and matrix operator)
239  SmartPtr<typename base_type::assembled_operator_type> spAssOp=make_sp(new typename base_type::assembled_operator_type(tdisc_dep_type::m_spTimeDisc, gl));
240  solver.init(spAssOp);
241 
242  // integrate
243  double t = t0;
244  number currdt = base_type::m_dt;
245  int step = 1;
246 
247  double final_dt = base_type::m_dt;
248 
249  if(!base_type::m_bNoLogOut)
250  UG_LOG("+++ Integrating: ["<< t0 <<", "<< t1 <<"] with " << currdt <<"\n");
251 
252  while(!hasTerminated(t, t0, t1))
253  {
254  if(!base_type::m_bNoLogOut)
255  UG_LOG("++++++ TIMESTEP " << step++ << " BEGIN (current time: " << t << ") ++++++\n");
256 
257  // determine step size
258  UG_COND_THROW(currdt < base_type::get_dt_min(), "Time step size below minimum. ABORTING!")
259  number dt = std::min(currdt, t1-t);
260 
261  final_dt = dt;
262 
263  double told = t;
264 
265  const int num_stages = tdisc.num_stages();
266  int s=1;
267  do // 'for-each-stage' loop
268  {
269 
270  // for (int s=1; s<=num_stages; ++s)
271  if(!base_type::m_bNoLogOut)
272  UG_LOG("+++ STAGE "<< s << " BEGIN +++\n");
273 
274  // set stage
275  tdisc.set_stage(s);
276 
277  // prepare step
278  tdisc.prepare_step(m_spSolTimeSeries, dt);
279  if (solver.prepare(*u1) == false) break;
280 
281  // execute step
282  if (!solver.apply(*u1)) break;
283 
284  // stage was successful:
285  // a. update (intermediate) time
286  t = tdisc.future_time();
287 
288  // b. push updated solution into time series (and continue)
289  SmartPtr<typename base_type::vector_type> oldest= m_spSolTimeSeries->oldest();
290  VecAssign(*oldest, static_cast<typename base_type::vector_type> (*u1));
291  m_spSolTimeSeries->push_discard_oldest(oldest, t);
292 
293  // c. output
294  if(!base_type::m_bNoLogOut)
295  UG_LOG("+++ STAGE "<< s << " END +++\n");
296 
297  } while ((++s) <=num_stages);
298 
299 
300  if (s<=num_stages)
301  {
302  // REJECT time step
303  if(!base_type::m_bNoLogOut)
304  UG_LOG("Solution failed! RETRY");
305 
306  currdt *= this->get_reduction_factor();
307  t = told;
308  continue;
309  }
310  else
311  {
312  if(!base_type::m_bNoLogOut)
313  {
314  this->notify_finalize_step(u1, /*uold, */step, t, dt);
315  }
316 
317  // ACCEPT time step
318  if (!hasTerminated(t, t0, t1))
319  *uold = *u1; // save solution (but not in last step)
320  // tdisc.finish_step_elem(m_spSolTimeSeries, dt);
321 
322  if(!base_type::m_bNoLogOut)
323  UG_LOG("++++++ TIMESTEP " << step++ << " END (current time: " << t << ") ++++++\n");
324  }
325  }
326 
327  if(base_type::m_bNoLogOut)
328  {
329  this->notify_finalize_step(u1, /*uold,*/ step, t, final_dt);
330  }
331  return true;
332 };
333 
334 } // ug
integration of non-linear systems (with bounds on dt)
Definition: time_integrator.hpp:1097
base_type::vector_type vector_type
Definition: time_integrator.hpp:1100
virtual bool apply(X &u)=0
virtual bool prepare(X &u)=0
virtual bool init(SmartPtr< IOperator< Y, X > > N)=0
ITimeDiscDependentObject.
Definition: time_integrator.hpp:620
SmartPtr< time_disc_type > m_spTimeDisc
Definition: time_integrator.hpp:630
virtual void set_stage(size_t stage)=0
virtual void prepare_step(SmartPtr< VectorTimeSeries< vector_type > > prevSol, number dt)=0
virtual number future_time() const=0
virtual size_t num_stages() const=0
double m_precisionBound
Definition: time_integrator.hpp:512
Integrate (a non-linear problem) over a given time interval.
Definition: simple_integrator.hpp:11
SimpleTimeIntegrator(SmartPtr< time_disc_type > tDisc, SmartPtr< grid_function_space_type > spSpace)
Definition: simple_integrator.hpp:31
number get_consistency_error() const
Definition: simple_integrator.hpp:53
void set_banach_space(SmartPtr< IGridFunctionSpace< grid_function_type > > spSpace)
Definition: simple_integrator.hpp:56
SimpleTimeIntegrator(SmartPtr< time_disc_type > tDisc)
Definition: simple_integrator.hpp:24
bool apply_single_stage(SmartPtr< grid_function_type > u1, number t1, ConstSmartPtr< grid_function_type > u0, number t0)
Definition: simple_integrator.hpp:79
bool hasTerminated(double tCurrent, double tStart, double tFinal) const
Definition: simple_integrator.hpp:63
void set_derivative(SmartPtr< grid_function_type > udot)
Definition: simple_integrator.hpp:47
IGridFunctionSpace< grid_function_type > grid_function_space_type
Definition: simple_integrator.hpp:20
ITimeDiscretization< TAlgebra > time_disc_type
Definition: simple_integrator.hpp:17
VectorTimeSeries< typename base_type::vector_type > vector_time_series_type
Definition: simple_integrator.hpp:21
SmartPtr< grid_function_type > m_spDerivative
Definition: simple_integrator.hpp:72
SmartPtr< grid_function_type > get_derivative()
Definition: simple_integrator.hpp:50
bool apply(SmartPtr< grid_function_type > u1, number t1, ConstSmartPtr< grid_function_type > u0, number t0)
Definition: simple_integrator.hpp:38
base_type::grid_function_type grid_function_type
Definition: simple_integrator.hpp:19
SmartPtr< IGridFunctionSpace< grid_function_type > > m_spBanachSpace
metric
Definition: simple_integrator.hpp:70
TAlgebra::vector_type vector_type
Definition: simple_integrator.hpp:18
number m_initial_consistency_error
Definition: simple_integrator.hpp:74
bool apply_multi_stage(SmartPtr< grid_function_type > u1, number t1, ConstSmartPtr< grid_function_type > u0, number t0)
Definition: simple_integrator.hpp:217
ITimeDiscDependentObject< TAlgebra > tdisc_dep_type
Definition: simple_integrator.hpp:13
INonlinearTimeIntegrator< TDomain, TAlgebra > base_type
Definition: simple_integrator.hpp:16
ParallelVector< Vector< double > > vector_type
void VecAssign(GPUVector< T > &dest, const GPUVector< T > &v1)
StringTable s
const NullSmartPtr SPNULL
#define UG_ASSERT(expr, msg)
#define UG_LOG(msg)
#define UG_COND_THROW(cond, msg)
double number
#define LIMEX_PROFILE_FUNC()
Definition: limex_tools.h:38
void VecScaleAdd(double &dest, double alpha1, const double &v1, double alpha2, const double &v2)
SmartPtr< T, FreePolicy > make_sp(T *inst)
function ProblemDisc new(problemDesc, dom)