35#ifndef __H__LIMEX__TIME_INTEGRATOR_IMPL_HPP__
36#define __H__LIMEX__TIME_INTEGRATOR_IMPL_HPP__
40template<
typename TDomain,
typename TAlgebra>
41bool LinearTimeIntegrator<TDomain, TAlgebra>::apply
43 SmartPtr<grid_function_type> u1,
45 ConstSmartPtr<grid_function_type> u0,
51 UG_COND_THROW(!base_type::m_spLinearSolver.valid(),
"Linear solver invalid");
54 GridLevel const &gl = u0->grid_level();
55 time_disc_type &tdisc = *tdisc_dep_type::m_spTimeDisc;
58 SmartPtr<typename base_type::vector_type> uold= u0->clone();
59 SmartPtr<typename base_type::vector_type> b= u0->clone_without_values();
62 SmartPtr<vector_time_series_type> m_spSolTimeSeries;
63 m_spSolTimeSeries=make_sp(new vector_time_series_type());
64 m_spSolTimeSeries->clear();
65 m_spSolTimeSeries->push(uold, t0);
68 SmartPtr<typename base_type::assembled_operator_type> spAssOp=make_sp(new typename base_type::assembled_operator_type(tdisc_dep_type::m_spTimeDisc, gl));
71 if(!base_type::m_bNoLogOut)
72 UG_LOG(
"+++ Integrating: ["<< t0 <<
", "<< t1 <<
"]\n");
75 number dt_assembled = -1.0;
78 number currdt = base_type::m_dt;
80 while((t < t1) && (t1-t > base_type::m_precisionBound))
83 if(!base_type::m_bNoLogOut)
84 { UG_LOG(
"+++ Timestep +++" << step <<
"\n"); }
87 number dt = std::min(currdt, t1-t);
90 tdisc.prepare_step(m_spSolTimeSeries, dt);
91 if (fabs(dt-dt_assembled) > base_type::m_precisionBound)
94 if(!base_type::m_bNoLogOut)
95 UG_LOG(
"+++ Reassemble (t=" << t <<
", dt=" << dt <<
")\n");
97 tdisc.assemble_linear(*spAssOp, *b, gl);
98 (base_type::m_spLinearSolver)->init(spAssOp, *u1);
104 tdisc.assemble_rhs(*b, gl);
108 if (base_type::m_spLinearSolver->apply(*u1, *b))
112 this->notify_finalize_step(u1, step++, t+dt, dt);
117 SmartPtr<typename base_type::vector_type> tmp = m_spSolTimeSeries->oldest();
118 VecAssign(*tmp, *u1.template cast_dynamic<typename base_type::vector_type>());
119 m_spSolTimeSeries->push_discard_oldest(tmp, t);
130 this->notify_end(u1, step, t1, currdt);
136template<
typename TDomain,
typename TAlgebra>
137bool ConstStepLinearTimeIntegrator<TDomain, TAlgebra>::apply
139 SmartPtr<grid_function_type> u1,
141 ConstSmartPtr<grid_function_type> u0,
146 UG_COND_THROW(!base_type::m_spLinearSolver.valid(),
"Linear solver invalid");
149 GridLevel const &gl = u0->grid_level();
150 time_disc_type &tdisc = *tdisc_dep_type::m_spTimeDisc;
153 SmartPtr<typename base_type::vector_type> uold= u0->clone();
154 SmartPtr<typename base_type::vector_type> b= u0->clone_without_values();
157 SmartPtr<vector_time_series_type> m_spSolTimeSeries;
158 m_spSolTimeSeries=make_sp(new vector_time_series_type());
159 m_spSolTimeSeries->push(uold, t0);
161 SmartPtr<typename base_type::assembled_operator_type> spAssOp = SPNULL;
165 int numSteps = round((t1-t0) / base_type::m_dt);
168 const
double dt = (t1-t0) / numSteps;
171 if(!base_type::m_bNoLogOut)
173 UG_LOG(
"+++ Integrating: [\t"<< t0 <<
"\t, \t"<< t1 <<
"\t] with dt=\t" << dt <<
"("<< numSteps<<
" iters)" << std::endl);
177 for(
int step = 1; step<=numSteps; ++step)
180 if(!base_type::m_bNoLogOut)
182 UG_LOG(
"+++ Const timestep +++" << step<<
"(t=" << t <<
", dt=" << dt <<
")"<< std::endl);
184 this->notify_init_step(u1, step, t, dt);
187 tdisc.prepare_step(m_spSolTimeSeries, dt);
191 if(!base_type::m_bNoLogOut)
192 { UG_LOG(
"+++ Assemble (t=" << t <<
", dt=" << dt <<
")" << std::endl); }
194 spAssOp=make_sp(
new typename base_type::assembled_operator_type(tdisc_dep_type::m_spTimeDisc, gl));
195 tdisc.assemble_linear(*spAssOp, *b, gl);
196 (base_type::m_spLinearSolver)->init(spAssOp, *u1);
202 tdisc.assemble_rhs(*b, gl);
206 if (base_type::m_spLinearSolver->apply(*u1, *b))
210 this->notify_finalize_step(u1, step, t+dt, dt);
214 SmartPtr<typename base_type::vector_type> tmp = m_spSolTimeSeries->oldest();
215 VecAssign(*tmp, *u1.template cast_dynamic<typename base_type::vector_type>());
216 m_spSolTimeSeries->push_discard_oldest(tmp, t);
221 UG_THROW(
"ConstStepLinearTimeIntegrator::apply failed!!!");
222 this->notify_rewind_step(u1, step, t+dt, dt);
227 this->notify_end(u1, numSteps, t1, dt);
232template<
typename TDomain,
typename TAlgebra>
233bool TimeIntegratorLinearAdaptive<TDomain, TAlgebra>::apply
235 SmartPtr<grid_function_type> u1,
237 ConstSmartPtr<grid_function_type> u0,
242 GridLevel
const &gl = u0->grid_level();
243 time_disc_type &tdisc = *tdisc_dep_type::m_spTimeDisc;
244 time_disc_type &tdisc2 = *m_spTimeDisc2;
247 SmartPtr<typename base_type::vector_type> uold= u0->clone();
248 SmartPtr<typename base_type::vector_type> b= u0->clone_without_values();
251 SmartPtr<typename base_type::assembled_operator_type> spAssOp=make_sp(
new typename base_type::assembled_operator_type(tdisc_dep_type::m_spTimeDisc, gl));
254 SmartPtr<typename base_type::grid_function_type> u2old = u0->clone();
255 SmartPtr<typename base_type::grid_function_type> u2 = u0->clone();
258 SmartPtr<vector_time_series_type> m_spSolTimeSeries;
259 m_spSolTimeSeries=make_sp(
new vector_time_series_type());
260 m_spSolTimeSeries->push(uold, t0);
262 SmartPtr<vector_time_series_type> m_spSolTimeSeries2;
263 m_spSolTimeSeries2=make_sp(
new vector_time_series_type());
264 m_spSolTimeSeries2->push(u2old, t0);
267 if (m_dtmin <= 0.0) { m_dtmin = (t1 - t0)/1.0e+5; }
268 if (m_dtmax <= 0.0) { m_dtmax = (t1 - t0)/10.0; }
271 const size_t tsteps[2] = {1,2};
272 std::vector<size_t> vsteps (tsteps, tsteps+2);
276 if(!base_type::m_bNoLogOut)
277 UG_LOG(
"+++ Integrating: ["<< t0 <<
", "<< t1 <<
"]\n");
282 number dt = base_type::m_dt;
283 while((t < t1) && (t1-t > base_type::m_precisionBound))
286 bool bSuccess =
false;
291 if(!base_type::m_bNoLogOut)
292 UG_LOG(
"Step size below minimum")
294 dt = std::min(dt, t1-t);
297 if(!base_type::m_bNoLogOut)
298 UG_LOG(
"+++ Timestep: " << ++step <<
"\n");
300 tdisc.prepare_step(m_spSolTimeSeries, dt);
301 tdisc.assemble_linear(*spAssOp, *b, gl);
302 base_type::m_spLinearSolver->init(spAssOp, *u1);
303 base_type::m_spLinearSolver->apply(*u1, *b);
307 if(!base_type::m_bNoLogOut)
308 UG_LOG(
"+++ Control: " << step <<
"\n");
310 tdisc2.prepare_step(m_spSolTimeSeries, 0.5*dt);
311 tdisc2.assemble_linear(*spAssOp, *b, gl);
312 base_type::m_spLinearSolver->init(spAssOp, *u2);
313 base_type::m_spLinearSolver->apply(*u2, *b);
316 SmartPtr<typename base_type::vector_type> tmp2 = m_spSolTimeSeries2->oldest();
317 (*tmp2)=*(u2.template cast_static<typename base_type::vector_type>());
318 m_spSolTimeSeries2->push_discard_oldest(tmp2, t + 0.5*dt);
321 tdisc2.prepare_step(m_spSolTimeSeries2, 0.5*dt);
322 tdisc2.assemble_linear(*spAssOp, *b, gl);
323 base_type::m_spLinearSolver->init(spAssOp, *u2);
324 base_type::m_spLinearSolver->apply(*u2, *b);
327 timex.set_solution(u1, 0);
328 timex.set_solution(u2, 1);
332 number eps = timex.get_error_estimates()[0];
333 number lambda = std::pow(0.8* m_tol/eps, 0.5);
335 number dtEst= dt*lambda;
336 dtEst = std::min(dtEst, 1.5*dt);
337 dtEst = std::min(dtEst, m_dtmax);
343 if(!base_type::m_bNoLogOut)
344 UG_LOG(
"ACCEPTING solution, dtnew=" << dt);
351 if(!base_type::m_bNoLogOut)
352 UG_LOG(
"DISCARDING solution, dtnew=" << dt);
355 VecAssign(*u1.template cast_dynamic<typename base_type::vector_type>(), *uold);
358 SmartPtr<typename base_type::vector_type> tmp = m_spSolTimeSeries2->oldest();
359 VecAssign(*tmp, *uold);
360 m_spSolTimeSeries2->push_discard_oldest(tmp, t);
371 SmartPtr<typename base_type::vector_type> tmp = m_spSolTimeSeries->oldest();
372 VecAssign(*tmp,
static_cast<typename base_type::vector_type
> (*u2));
373 m_spSolTimeSeries->push_discard_oldest(tmp, t);
Definition time_extrapolation.h:1034