Plugins
Loading...
Searching...
No Matches
simple_integrator.hpp
Go to the documentation of this file.
2
3namespace ug {
4
6template<class TDomain, class TAlgebra>
8 public INonlinearTimeIntegrator<TDomain, TAlgebra>,
9 public ITimeDiscDependentObject<TAlgebra>,
10 public DebugWritingObject<TAlgebra>
11{
12protected:
14
15public:
18 typedef typename TAlgebra::vector_type vector_type;
22
23 // constructor
30
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
49
52
55
58
59protected:
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
78template<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
216template<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
parameterString s
Definition Biogas.lua:2
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
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
SmartPtr< grid_function_type > get_derivative()
Definition simple_integrator.hpp:50
INonlinearTimeIntegrator< TDomain, TAlgebra > base_type
Definition simple_integrator.hpp:16
void VecAssign(GPUVector< T > &dest, const GPUVector< T > &v1)
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)