Reference documentation for deal.II version 8.4.2
time_dependent.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1999 - 2015 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii__time_dependent_h
17 #define dealii__time_dependent_h
18 
19 
20 /*---------------------------- time-dependent.h ---------------------------*/
21 
22 
23 #include <deal.II/base/config.h>
24 #include <deal.II/base/exceptions.h>
25 #include <deal.II/base/subscriptor.h>
26 #include <deal.II/base/smartpointer.h>
27 
28 #include <vector>
29 #include <utility>
30 
31 DEAL_II_NAMESPACE_OPEN
32 
33 // forward declarations
34 class TimeStepBase;
35 template <typename number> class Vector;
36 template <int dim, int spacedim> class Triangulation;
37 
352 {
353 public:
361  {
366  TimeSteppingData (const unsigned int look_ahead,
367  const unsigned int look_back);
368 
387  const unsigned int look_ahead;
388 
401  const unsigned int look_back;
402  };
403 
409  {
410  forward, backward
411  };
412 
416  TimeDependent (const TimeSteppingData &data_primal,
417  const TimeSteppingData &data_dual,
418  const TimeSteppingData &data_postprocess);
419 
420 
426  virtual ~TimeDependent ();
427 
448  void insert_timestep (const TimeStepBase *position,
449  TimeStepBase *new_timestep);
450 
460  void add_timestep (TimeStepBase *new_timestep);
461 
474  void delete_timestep (const unsigned int position);
475 
484  void solve_primal_problem ();
485 
494  void solve_dual_problem ();
495 
504  void postprocess ();
505 
532  template <typename InitFunctionObject, typename LoopFunctionObject>
533  void do_loop (InitFunctionObject init_function,
534  LoopFunctionObject loop_function,
535  const TimeSteppingData &timestepping_data,
536  const Direction direction);
537 
538 
556  virtual void start_sweep (const unsigned int sweep_no);
557 
571  virtual void end_sweep ();
572 
577  std::size_t memory_consumption () const;
578 
582  DeclExceptionMsg (ExcInvalidPosition,
583  "You cannot insert a time step at the specified position.");
584 
585 protected:
591  std::vector<SmartPointer<TimeStepBase,TimeDependent> > timesteps;
592 
597  unsigned int sweep_no;
598 
604 
610 
616 
617 private:
618 
623  void end_sweep (const unsigned int begin_timestep,
624  const unsigned int end_timestep);
625 };
626 
627 
628 
638 class TimeStepBase : public Subscriptor
639 {
640 public:
645  {
646  primal_problem = 0x0,
647  dual_problem = 0x1,
648  postprocess = 0x2
649  };
650 
654  TimeStepBase (const double time);
655 
659  virtual ~TimeStepBase ();
660 
676  virtual void wake_up (const unsigned int);
677 
687  virtual void sleep (const unsigned int);
688 
704  virtual void start_sweep ();
705 
711  virtual void end_sweep ();
712 
720  virtual void init_for_primal_problem ();
721 
725  virtual void init_for_dual_problem ();
726 
730  virtual void init_for_postprocessing ();
731 
739  virtual void solve_primal_problem () = 0;
740 
750  virtual void solve_dual_problem ();
751 
761  virtual void postprocess_timestep ();
762 
766  double get_time () const;
767 
772  unsigned int get_timestep_no () const;
773 
787  double get_backward_timestep () const;
788 
794  double get_forward_timestep () const;
795 
804  virtual std::size_t memory_consumption () const;
805 
806 protected:
811 
816 
821  unsigned int sweep_no;
822 
828  unsigned int timestep_no;
829 
833  const double time;
834 
840  unsigned int next_action;
841 
842 private:
850  void set_previous_timestep (const TimeStepBase *previous);
851 
859  void set_next_timestep (const TimeStepBase *next);
860 
867  void set_timestep_no (const unsigned int step_no);
868 
873  void set_sweep_no (const unsigned int sweep_no);
874 
875 
882  TimeStepBase (const TimeStepBase &);
883 
890  TimeStepBase &operator = (const TimeStepBase &);
891 
892  // make the manager object a friend
893  friend class TimeDependent;
894 };
895 
896 
897 
898 
908 {
916  template <int dim>
917  struct Flags
918  {
922  Flags ();
923 
928  Flags (const bool delete_and_rebuild_tria,
929  const unsigned int wakeup_level_to_build_grid,
930  const unsigned int sleep_level_to_delete_grid);
931 
943 
952  const unsigned int wakeup_level_to_build_grid;
953 
958  const unsigned int sleep_level_to_delete_grid;
959  };
960 
961 
962 
1082  template <int dim>
1084  {
1090  typedef std::vector<std::vector<std::pair<unsigned int, double> > > CorrectionRelaxations;
1091 
1095  static CorrectionRelaxations default_correction_relaxations;
1096 
1101  RefinementFlags (const unsigned int max_refinement_level = 0,
1102  const unsigned int first_sweep_with_correction = 0,
1103  const unsigned int min_cells_for_correction = 0,
1104  const double cell_number_corridor_top = (1<<dim),
1105  const double cell_number_corridor_bottom = 1,
1106  const CorrectionRelaxations &correction_relaxations = CorrectionRelaxations(),
1107  const unsigned int cell_number_correction_steps = 0,
1108  const bool mirror_flags_to_previous_grid = false,
1109  const bool adapt_grids = false);
1110 
1119  const unsigned int max_refinement_level;
1120 
1126  const unsigned int first_sweep_with_correction;
1127 
1128 
1133  const unsigned int min_cells_for_correction;
1134 
1141 
1146 
1150  const std::vector<std::vector<std::pair<unsigned int,double> > > correction_relaxations;
1151 
1157  const unsigned int cell_number_correction_steps;
1158 
1176 
1180  const bool adapt_grids;
1181 
1185  DeclException1 (ExcInvalidValue,
1186  double,
1187  << "The value " << arg1
1188  << " for the cell number corridor does not fulfill "
1189  "its natural requirements.");
1190  };
1191 
1192 
1193 
1200  template <int dim>
1202  {
1206  RefinementData (const double refinement_threshold,
1207  const double coarsening_threshold=0);
1208 
1215  const double refinement_threshold;
1216 
1221  const double coarsening_threshold;
1222 
1226  DeclException1 (ExcInvalidValue,
1227  double,
1228  << "The value " << arg1
1229  << " for the cell refinement thresholds does not fulfill "
1230  "its natural requirements.");
1231  };
1232 }
1233 
1234 
1235 
1236 
1256 template <int dim>
1258 {
1259 public:
1267 
1268 
1274  {
1275  grid_refinement = 0x1000
1276  };
1277 
1278 
1287  TimeStepBase_Tria ();
1288 
1301  TimeStepBase_Tria (const double time,
1302  const Triangulation<dim, dim> &coarse_grid,
1303  const Flags &flags,
1304  const RefinementFlags &refinement_flags = RefinementFlags());
1305 
1310  virtual ~TimeStepBase_Tria ();
1311 
1332  virtual void wake_up (const unsigned int wakeup_level);
1333 
1347  virtual void sleep (const unsigned int);
1348 
1363  void refine_grid (const RefinementData data);
1364 
1370  virtual void init_for_refinement ();
1371 
1379  virtual void get_tria_refinement_criteria (Vector<float> &criteria) const = 0;
1380 
1385  void save_refine_flags ();
1386 
1395  virtual std::size_t memory_consumption () const;
1396 
1400  DeclExceptionMsg (ExcGridNotDeleted,
1401  "When calling restore_grid(), you must have previously "
1402  "deleted the triangulation.");
1403 
1404 protected:
1405 
1414 
1421 
1426  const Flags flags;
1427 
1432  const RefinementFlags refinement_flags;
1433 
1434 private:
1440  std::vector<std::vector<bool> > refine_flags;
1441 
1445  std::vector<std::vector<bool> > coarsen_flags;
1446 
1451  void restore_grid ();
1452 };
1453 
1454 
1455 
1456 
1457 
1458 /*----------------------------- template functions ------------------------------*/
1459 
1460 template <typename InitFunctionObject, typename LoopFunctionObject>
1461 void TimeDependent::do_loop (InitFunctionObject init_function,
1462  LoopFunctionObject loop_function,
1463  const TimeSteppingData &timestepping_data,
1464  const Direction direction)
1465 {
1466  // the following functions looks quite
1467  // disrupted due to the recurring switches
1468  // for forward and backward running loops.
1469  //
1470  // I chose to switch at every place where
1471  // it is needed, since it is so easy
1472  // to overlook something when you change
1473  // some code at one place when it needs
1474  // to be changed at a second place, here
1475  // for the other direction, also.
1476 
1477  const unsigned int n_timesteps = timesteps.size();
1478 
1479  // initialize the time steps for
1480  // a round of this loop
1481  for (unsigned int step=0; step<n_timesteps; ++step)
1482  switch (direction)
1483  {
1484  case forward:
1485  init_function (static_cast<typename InitFunctionObject::argument_type>
1486  (&*timesteps[step]));
1487  break;
1488  case backward:
1489  init_function (static_cast<typename InitFunctionObject::argument_type>
1490  (&*timesteps[n_timesteps-@ref step_1 "step-1"]));
1491  break;
1492  };
1493 
1494 
1495  // wake up the first few time levels
1496  for (int step=-timestepping_data.look_ahead; step<0; ++step)
1497  for (int look_ahead=0;
1498  look_ahead<=static_cast<int>(timestepping_data.look_ahead); ++look_ahead)
1499  switch (direction)
1500  {
1501  case forward:
1502  if (step+look_ahead >= 0)
1503  timesteps[step+look_ahead]->wake_up(look_ahead);
1504  break;
1505  case backward:
1506  if (n_timesteps-(step+look_ahead) < n_timesteps)
1507  timesteps[n_timesteps-(step+look_ahead)]->wake_up(look_ahead);
1508  break;
1509  };
1510 
1511 
1512  for (unsigned int step=0; step<n_timesteps; ++step)
1513  {
1514  // first thing: wake up the
1515  // timesteps ahead as necessary
1516  for (unsigned int look_ahead=0;
1517  look_ahead<=timestepping_data.look_ahead; ++look_ahead)
1518  switch (direction)
1519  {
1520  case forward:
1521  if (step+look_ahead < n_timesteps)
1522  timesteps[step+look_ahead]->wake_up(look_ahead);
1523  break;
1524  case backward:
1525  if (n_timesteps > (step+look_ahead))
1526  timesteps[n_timesteps-(step+look_ahead)-1]->wake_up(look_ahead);
1527  break;
1528  };
1529 
1530 
1531  // actually do the work
1532  switch (direction)
1533  {
1534  case forward:
1535  loop_function (static_cast<typename LoopFunctionObject::argument_type>
1536  (&*timesteps[step]));
1537  break;
1538  case backward:
1539  loop_function (static_cast<typename LoopFunctionObject::argument_type>
1540  (&*timesteps[n_timesteps-@ref step_1 "step-1"]));
1541  break;
1542  };
1543 
1544  // let the timesteps behind sleep
1545  for (unsigned int look_back=0;
1546  look_back<=timestepping_data.look_back; ++look_back)
1547  switch (direction)
1548  {
1549  case forward:
1550  if (step>=look_back)
1551  timesteps[step-look_back]->sleep(look_back);
1552  break;
1553  case backward:
1554  if (n_timesteps-(step-look_back) <= n_timesteps)
1555  timesteps[n_timesteps-(step-look_back)-1]->sleep(look_back);
1556  break;
1557  };
1558  };
1559 
1560  // make the last few timesteps sleep
1561  for (int step=n_timesteps;
1562  step<static_cast<int>(n_timesteps+timestepping_data.look_back); ++step)
1563  for (int look_back=0;
1564  look_back<=static_cast<int>(timestepping_data.look_back); ++look_back)
1565  switch (direction)
1566  {
1567  case forward:
1568  if ((step-look_back >= 0)
1569  &&
1570  (step-look_back < static_cast<int>(n_timesteps)))
1571  timesteps[step-look_back]->sleep(look_back);
1572  break;
1573  case backward:
1574  if ((step-look_back >= 0)
1575  &&
1576  (step-look_back < static_cast<int>(n_timesteps)))
1577  timesteps[n_timesteps-(step-look_back)-1]->sleep(look_back);
1578  break;
1579  };
1580 }
1581 
1582 DEAL_II_NAMESPACE_CLOSE
1583 
1584 /*---------------------------- time-dependent.h ---------------------------*/
1585 #endif
1586 /*---------------------------- time-dependent.h ---------------------------*/
unsigned int next_action
TimeDependent(const TimeSteppingData &data_primal, const TimeSteppingData &data_dual, const TimeSteppingData &data_postprocess)
void solve_primal_problem()
void add_timestep(TimeStepBase *new_timestep)
void solve_dual_problem()
const TimeStepBase * next_timestep
const TimeSteppingData timestepping_data_postprocess
const unsigned int wakeup_level_to_build_grid
const TimeStepBase * previous_timestep
const TimeSteppingData timestepping_data_dual
unsigned int timestep_no
void do_loop(InitFunctionObject init_function, LoopFunctionObject loop_function, const TimeSteppingData &timestepping_data, const Direction direction)
const RefinementFlags refinement_flags
const std::vector< std::vector< std::pair< unsigned int, double > > > correction_relaxations
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:542
SmartPointer< const Triangulation< dim, dim >, TimeStepBase_Tria< dim > > coarse_grid
std::size_t memory_consumption() const
const double time
virtual ~TimeDependent()
const TimeSteppingData timestepping_data_primal
virtual void start_sweep(const unsigned int sweep_no)
static CorrectionRelaxations default_correction_relaxations
const unsigned int sleep_level_to_delete_grid
void delete_timestep(const unsigned int position)
TimeStepBase_Tria_Flags::Flags< dim > Flags
DeclExceptionMsg(ExcInvalidPosition, "You cannot insert a time step at the specified position.")
std::vector< SmartPointer< TimeStepBase, TimeDependent > > timesteps
unsigned int sweep_no
void insert_timestep(const TimeStepBase *position, TimeStepBase *new_timestep)
std::vector< std::vector< bool > > refine_flags
std::vector< std::vector< bool > > coarsen_flags
std::vector< std::vector< std::pair< unsigned int, double > > > CorrectionRelaxations
virtual void end_sweep()
unsigned int sweep_no
TimeSteppingData(const unsigned int look_ahead, const unsigned int look_back)
SmartPointer< Triangulation< dim, dim >, TimeStepBase_Tria< dim > > tria