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);
166 number currdt = (t1-t0) / numSteps;
171 if(!base_type::m_bNoLogOut)
173 UG_LOG(
"+++ Integrating: [\t"<< t0 <<
"\t, \t"<< t1 <<
"\t] with dt=\t" << currdt <<
"("<< numSteps<<
" iters)" << std::endl);
177 for(
int step = 1; step<=numSteps; ++step)
181 const number dt = currdt;
183 if(!base_type::m_bNoLogOut)
185 UG_LOG(
"+++ Const timestep +++" << step<<
"(t=" << t <<
", dt=" << dt <<
")"<< std::endl);
187 this->notify_init_step(u1, step, t, dt);
190 tdisc.prepare_step(m_spSolTimeSeries, dt);
194 if(!base_type::m_bNoLogOut) UG_LOG(
"+++ Assemble (t=" << t <<
", dt=" << dt <<
")" << std::endl);
196 spAssOp=make_sp(
new typename base_type::assembled_operator_type(tdisc_dep_type::m_spTimeDisc, gl));
197 tdisc.assemble_linear(*spAssOp, *b, gl);
198 (base_type::m_spLinearSolver)->init(spAssOp, *u1);
204 tdisc.assemble_rhs(*b, gl);
208 if (base_type::m_spLinearSolver->apply(*u1, *b))
212 this->notify_finalize_step(u1, step, t+dt, dt);
216 SmartPtr<typename base_type::vector_type> tmp = m_spSolTimeSeries->oldest();
217 VecAssign(*tmp, *u1.template cast_dynamic<typename base_type::vector_type>());
218 m_spSolTimeSeries->push_discard_oldest(tmp, t);
223 UG_THROW(
"ConstStepLinearTimeIntegrator::apply failed!!!");
224 this->notify_rewind_step(u1, step, t+dt, dt);
229 this->notify_end(u1, numSteps, t1, currdt);
234template<
typename TDomain,
typename TAlgebra>
235bool TimeIntegratorLinearAdaptive<TDomain, TAlgebra>::apply
237 SmartPtr<grid_function_type> u1,
239 ConstSmartPtr<grid_function_type> u0,
244 GridLevel
const &gl = u0->grid_level();
245 time_disc_type &tdisc = *tdisc_dep_type::m_spTimeDisc;
246 time_disc_type &tdisc2 = *m_spTimeDisc2;
249 SmartPtr<typename base_type::vector_type> uold= u0->clone();
250 SmartPtr<typename base_type::vector_type> b= u0->clone_without_values();
253 SmartPtr<typename base_type::assembled_operator_type> spAssOp=make_sp(
new typename base_type::assembled_operator_type(tdisc_dep_type::m_spTimeDisc, gl));
256 SmartPtr<typename base_type::grid_function_type> u2old = u0->clone();
257 SmartPtr<typename base_type::grid_function_type> u2 = u0->clone();
260 SmartPtr<vector_time_series_type> m_spSolTimeSeries;
261 m_spSolTimeSeries=make_sp(
new vector_time_series_type());
262 m_spSolTimeSeries->push(uold, t0);
264 SmartPtr<vector_time_series_type> m_spSolTimeSeries2;
265 m_spSolTimeSeries2=make_sp(
new vector_time_series_type());
266 m_spSolTimeSeries2->push(u2old, t0);
269 if (m_dtmin <= 0.0) { m_dtmin = (t1 - t0)/1.0e+5; }
270 if (m_dtmax <= 0.0) { m_dtmax = (t1 - t0)/10.0; }
273 const size_t tsteps[2] = {1,2};
274 std::vector<size_t> vsteps (tsteps, tsteps+2);
278 if(!base_type::m_bNoLogOut)
279 UG_LOG(
"+++ Integrating: ["<< t0 <<
", "<< t1 <<
"]\n");
284 number dt = base_type::m_dt;
285 while((t < t1) && (t1-t > base_type::m_precisionBound))
288 bool bSuccess =
false;
293 if(!base_type::m_bNoLogOut)
294 UG_LOG(
"Step size below minimum")
296 dt = std::min(dt, t1-t);
299 if(!base_type::m_bNoLogOut)
300 UG_LOG(
"+++ Timestep: " << ++step <<
"\n");
302 tdisc.prepare_step(m_spSolTimeSeries, dt);
303 tdisc.assemble_linear(*spAssOp, *b, gl);
304 base_type::m_spLinearSolver->init(spAssOp, *u1);
305 base_type::m_spLinearSolver->apply(*u1, *b);
309 if(!base_type::m_bNoLogOut)
310 UG_LOG(
"+++ Control: " << step <<
"\n");
312 tdisc2.prepare_step(m_spSolTimeSeries, 0.5*dt);
313 tdisc2.assemble_linear(*spAssOp, *b, gl);
314 base_type::m_spLinearSolver->init(spAssOp, *u2);
315 base_type::m_spLinearSolver->apply(*u2, *b);
318 SmartPtr<typename base_type::vector_type> tmp2 = m_spSolTimeSeries2->oldest();
319 (*tmp2)=*(u2.template cast_static<typename base_type::vector_type>());
320 m_spSolTimeSeries2->push_discard_oldest(tmp2, t + 0.5*dt);
323 tdisc2.prepare_step(m_spSolTimeSeries2, 0.5*dt);
324 tdisc2.assemble_linear(*spAssOp, *b, gl);
325 base_type::m_spLinearSolver->init(spAssOp, *u2);
326 base_type::m_spLinearSolver->apply(*u2, *b);
329 timex.set_solution(u1, 0);
330 timex.set_solution(u2, 1);
334 number eps = timex.get_error_estimates()[0];
335 number lambda = std::pow(0.8* m_tol/eps, 0.5);
337 number dtEst= dt*lambda;
338 dtEst = std::min(dtEst, 1.5*dt);
339 dtEst = std::min(dtEst, m_dtmax);
345 if(!base_type::m_bNoLogOut)
346 UG_LOG(
"ACCEPTING solution, dtnew=" << dt);
353 if(!base_type::m_bNoLogOut)
354 UG_LOG(
"DISCARDING solution, dtnew=" << dt);
357 VecAssign(*u1.template cast_dynamic<typename base_type::vector_type>(), *uold);
360 SmartPtr<typename base_type::vector_type> tmp = m_spSolTimeSeries2->oldest();
361 VecAssign(*tmp, *uold);
362 m_spSolTimeSeries2->push_discard_oldest(tmp, t);
373 SmartPtr<typename base_type::vector_type> tmp = m_spSolTimeSeries->oldest();
374 VecAssign(*tmp,
static_cast<typename base_type::vector_type
> (*u2));
375 m_spSolTimeSeries->push_discard_oldest(tmp, t);
Definition time_extrapolation.h:986