From: wolf Date: Mon, 1 Mar 1999 20:48:27 +0000 (+0000) Subject: Extend the time dependent class. X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b113809cba7a7c5c14e96a96a1b0dcb44b9725b1;p=dealii-svn.git Extend the time dependent class. git-svn-id: https://svn.dealii.org/trunk@937 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/deal.II/include/numerics/time_dependent.h b/deal.II/deal.II/include/numerics/time_dependent.h index e4159864f7..57abe1febb 100644 --- a/deal.II/deal.II/include/numerics/time_dependent.h +++ b/deal.II/deal.II/include/numerics/time_dependent.h @@ -84,7 +84,9 @@ class TimeDependent /** * Constructor. */ - TimeDependent (const TimeSteppingData &data_primal); + TimeDependent (const TimeSteppingData &data_primal, + const TimeSteppingData &data_dual, + const TimeSteppingData &data_postprocess); /** @@ -143,9 +145,80 @@ class TimeDependent */ void delete_timestep (const unsigned int position); - + /** + * Solve the primal problem; uses the + * functions #init_for_primal_problem# + * and #solve_primal_problem# of the + * #TimeStepBase# class through the + * #do_loop# function of this class. + * + * Look ahead and look back are + * determined by the #timestepping_data_primal# + * object given to the constructor. + */ void solve_primal_problem (); + + /** + * Solve the dual problem; uses the + * functions #init_for_dual_problem# + * and #solve_dual_problem# of the + * #TimeStepBase# class through the + * #do_loop# function of this class. + * + * Look ahead and look back are + * determined by the #timestepping_data_dual# + * object given to the constructor. + */ + void solve_dual_problem (); + + /** + * Do a postprocessing round; uses the + * functions #init_for_postprocessing# + * and #postprocess# of the + * #TimeStepBase# class through the + * #do_loop# function of this class. + * + * Look ahead and look back are + * determined by the #timestepping_data_postprocess# + * object given to the constructor. + */ + void postprocess (); + + /** + * Do a loop over all timesteps, call the + * #init_function# at the beginning and + * the #loop_function# of each time step. + * The #timestepping_data# determine how + * many timesteps in front and behind + * the present one the #wake_up# and + * #sleep# functions are called. + * + * To see how this function work, note that + * the function #solve_primal_problem# only + * consists of a call to + * # do_loop (&TimeStepBase::init_for_primal_problem, + * &TimeStepBase::solve_primal_problem, + * timestepping_data_primal);#. + * + * Note also, that the given class from which + * the two functions are taken needs not + * necessarily be a #TimeStepBase#, but it + * should be a derived class, that is + * #static_cast#able from a #TimeStepBase#. + * The function may be a virtual function + * (even a pure one) of that class, which + * should help if the actual class where it + * is implemented is one which is derived + * through virtual base classes and thus + * unreachable by #static_cast# from the + * #TimeStepBase# class. + */ + template + void do_loop (void (TimeStepClass::*init_function) (), + void (TimeStepClass::*loop_function) (), + const TimeSteppingData ×tepping_data); + /** * Initialize the objects for the next * sweep. This function specifically does @@ -203,7 +276,74 @@ class TimeDependent * do. See the documentation of this struct * for more information. */ - TimeSteppingData timestepping_data_primal; + TimeSteppingData timestepping_data_primal; + + /** + * Some flags telling the + * #solve_dual_problem# function what to + * do. See the documentation of this struct + * for more information. + */ + TimeSteppingData timestepping_data_dual; + + /** + * Some flags telling the + * #postprocess# function what to + * do. See the documentation of this struct + * for more information. + */ + TimeSteppingData timestepping_data_postprocess; + +}; + + + + +template +void TimeDependent::do_loop (void (TimeStepClass::*init_function) (), + void (TimeStepClass::*loop_function) (), + const TimeSteppingData ×tepping_data) +{ + const unsigned int n_timesteps = timesteps.size(); + + // initialize the time steps for + // a round of primal problems + for (unsigned int step=0; step(timesteps[step])->*init_function) (); + + // wake up the first few time levels + for (int step=-timestepping_data.look_ahead; step<0; ++step) + for (int look_ahead=0; + look_ahead<=static_cast(timestepping_data.look_ahead); ++look_ahead) + if (step+look_ahead >= 0) + timesteps[step+look_ahead]->wake_up(look_ahead); + + for (unsigned int step=0; stepwake_up(look_ahead); + + // actually do the work + (static_cast(timesteps[step])->*loop_function) (); + + // let the timesteps behind sleep + for (unsigned int look_back=0; + look_back<=timestepping_data.look_back; ++look_back) + if (step>=look_back) + timesteps[step-look_back]->sleep(look_back); + }; + + // make the last few timesteps sleep + for (int step=n_timesteps; + step(n_timesteps+timestepping_data.look_back); ++step) + for (int look_back=0; + look_back<=static_cast(timestepping_data.look_back); ++look_back) + if ((step-look_back>=0) && (step-look_back(n_timesteps))) + timesteps[step-look_back]->sleep(look_back); }; @@ -212,6 +352,8 @@ class TimeDependent + + class TimeStepBase : public Subscriptor { public: @@ -221,7 +363,8 @@ class TimeStepBase : public Subscriptor */ enum NextAction { primal_problem, - dual_problem + dual_problem, + postprocess }; /** @@ -327,7 +470,13 @@ class TimeStepBase : public Subscriptor * a round of dual problem solves. */ virtual void init_for_dual_problem (); - + + /** + * Same as above, but called before + * a round of postprocessing steps. + */ + virtual void init_for_postprocessing (); + /** * This function is called by the * manager object when solving the @@ -359,6 +508,26 @@ class TimeStepBase : public Subscriptor * should really overload the function. */ virtual void solve_dual_problem (); + + /** + * This function is called by the + * manager object when postprocessing + * this time level + * is needed. It is called after + * the #wake_up# function was + * called and before the #sleep# + * function will be called. There + * is a default implementation + * doing plain nothing since some + * problems may not need doing a + * postprocess step, e.g. if everything + * was already done when solving the + * primal problem. However, it + * will abort the program when + * being called anyway, since then you + * should really overload the function. + */ + virtual void postprocess_timestep (); /** * Compute the time difference to the diff --git a/deal.II/deal.II/source/numerics/time_dependent.cc b/deal.II/deal.II/source/numerics/time_dependent.cc index eba4f604cf..0bfadf96f6 100644 --- a/deal.II/deal.II/source/numerics/time_dependent.cc +++ b/deal.II/deal.II/source/numerics/time_dependent.cc @@ -18,9 +18,13 @@ TimeDependent::TimeSteppingData::TimeSteppingData (const unsigned int look_ahead -TimeDependent::TimeDependent (const TimeSteppingData &data_primal): +TimeDependent::TimeDependent (const TimeSteppingData &data_primal, + const TimeSteppingData &data_dual, + const TimeSteppingData &data_postprocess): sweep_no (static_cast(-1)), - timestepping_data_primal (data_primal) + timestepping_data_primal (data_primal), + timestepping_data_dual (data_dual), + timestepping_data_postprocess (data_postprocess) {}; @@ -124,53 +128,39 @@ void TimeDependent::delete_timestep (const unsigned int position) + void TimeDependent::solve_primal_problem () { - const unsigned int n_timesteps = timesteps.size(); - - // initialize the time steps for - // a round of primal problems - for (unsigned int step=0; stepinit_for_primal_problem(); - - // wake up the first few time levels - for (int step=-timestepping_data_primal.look_ahead; step<0; ++step) - for (int look_ahead=0; - look_ahead<=static_cast(timestepping_data_primal.look_ahead); ++look_ahead) - if (step+look_ahead >= 0) - timesteps[step+look_ahead]->wake_up(look_ahead); - - for (unsigned int step=0; stepwake_up(look_ahead); - - // actually do the work - timesteps[step]->solve_primal_problem (); - - // let the timesteps behind sleep - for (unsigned int look_back=0; - look_back<=timestepping_data_primal.look_back; ++look_back) - if (step>=look_back) - timesteps[step-look_back]->sleep(look_back); - }; + do_loop (&TimeStepBase::init_for_primal_problem, + &TimeStepBase::solve_primal_problem, + timestepping_data_primal); +}; + + - // make the last few timesteps sleep - for (int step=n_timesteps; - step(n_timesteps+timestepping_data_primal.look_back); ++step) - for (int look_back=0; - look_back<=static_cast(timestepping_data_primal.look_back); ++look_back) - if ((step-look_back>=0) && (step-look_back(n_timesteps))) - timesteps[step-look_back]->sleep(look_back); +void +TimeDependent::solve_dual_problem () +{ + do_loop (&TimeStepBase::init_for_dual_problem, + &TimeStepBase::solve_dual_problem, + timestepping_data_dual); +}; + + + +void +TimeDependent::postprocess () +{ + do_loop (&TimeStepBase::init_for_postprocessing, + &TimeStepBase::postprocess_timestep, + timestepping_data_postprocess); }; + + void TimeDependent::start_sweep (const unsigned int s) { sweep_no = s; @@ -247,6 +237,14 @@ TimeStepBase::init_for_dual_problem () +void +TimeStepBase::init_for_postprocessing () +{ + next_action = postprocess; +}; + + + void TimeStepBase::solve_dual_problem () @@ -256,6 +254,14 @@ TimeStepBase::solve_dual_problem () +void +TimeStepBase::postprocess_timestep () +{ + Assert (false, ExcPureVirtualFunctionCalled()); +}; + + + double TimeStepBase::get_backward_timestep () const { @@ -375,6 +381,7 @@ TimeStepBase_Tria::~TimeStepBase_Tria () }; + template void TimeStepBase_Tria::wake_up (const unsigned wakeup_level) {