Reference documentation for deal.II version 9.1.0-pre
time_dependent.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1999 - 2018 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.md at
12 // the top level directory of deal.II.
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 
25 # include <deal.II/base/exceptions.h>
26 # include <deal.II/base/smartpointer.h>
27 # include <deal.II/base/subscriptor.h>
28 
29 # include <utility>
30 # include <vector>
31 
32 DEAL_II_NAMESPACE_OPEN
33 
34 // forward declarations
35 class TimeStepBase;
36 template <typename number>
37 class Vector;
38 template <int dim, int spacedim>
39 class Triangulation;
40 
363 {
364 public:
372  {
377  TimeSteppingData(const unsigned int look_ahead,
378  const unsigned int look_back);
379 
398  const unsigned int look_ahead;
399 
412  const unsigned int look_back;
413  };
414 
420  {
429  };
430 
434  TimeDependent(const TimeSteppingData &data_primal,
435  const TimeSteppingData &data_dual,
436  const TimeSteppingData &data_postprocess);
437 
438 
444  virtual ~TimeDependent();
445 
466  void
467  insert_timestep(const TimeStepBase *position, TimeStepBase *new_timestep);
468 
478  void
479  add_timestep(TimeStepBase *new_timestep);
480 
493  void
494  delete_timestep(const unsigned int position);
495 
504  void
506 
515  void
517 
526  void
527  postprocess();
528 
555  template <typename InitFunctionObject, typename LoopFunctionObject>
556  void
557  do_loop(InitFunctionObject init_function,
558  LoopFunctionObject loop_function,
559  const TimeSteppingData &timestepping_data,
560  const Direction direction);
561 
562 
580  virtual void
581  start_sweep(const unsigned int sweep_no);
582 
596  virtual void
597  end_sweep();
598 
603  std::size_t
604  memory_consumption() const;
605 
610  "You cannot insert a time step at the specified position.");
611 
612 protected:
618  std::vector<SmartPointer<TimeStepBase, TimeDependent>> timesteps;
619 
624  unsigned int sweep_no;
625 
631 
637 
643 
644 private:
649  void
650  end_sweep(const unsigned int begin_timestep, const unsigned int end_timestep);
651 };
652 
653 
654 
664 class TimeStepBase : public Subscriptor
665 {
666 public:
671  {
675  primal_problem = 0x0,
679  dual_problem = 0x1,
684  };
685 
689  TimeStepBase(const double time);
690 
694  virtual ~TimeStepBase() override = default;
695 
711  virtual void
712  wake_up(const unsigned int);
713 
723  virtual void
724  sleep(const unsigned int);
725 
741  virtual void
742  start_sweep();
743 
749  virtual void
750  end_sweep();
751 
759  virtual void
760  init_for_primal_problem();
761 
765  virtual void
766  init_for_dual_problem();
767 
771  virtual void
772  init_for_postprocessing();
773 
781  virtual void
782  solve_primal_problem() = 0;
783 
793  virtual void
795 
805  virtual void
806  postprocess_timestep();
807 
811  double
812  get_time() const;
813 
818  unsigned int
819  get_timestep_no() const;
820 
834  double
835  get_backward_timestep() const;
836 
842  double
843  get_forward_timestep() const;
844 
853  virtual std::size_t
854  memory_consumption() const;
855 
856 protected:
861 
866 
871  unsigned int sweep_no;
872 
878  unsigned int timestep_no;
879 
883  const double time;
884 
890  unsigned int next_action;
891 
892 private:
900  void
901  set_previous_timestep(const TimeStepBase *previous);
902 
910  void
911  set_next_timestep(const TimeStepBase *next);
912 
919  void
920  set_timestep_no(const unsigned int step_no);
921 
926  void
927  set_sweep_no(const unsigned int sweep_no);
928 
929 
936  TimeStepBase(const TimeStepBase &) = delete;
937 
944  TimeStepBase &
945  operator=(const TimeStepBase &) = delete;
946 
947  // make the manager object a friend
948  friend class TimeDependent;
949 };
950 
951 
952 
962 {
970  template <int dim>
971  struct Flags
972  {
976  Flags();
977 
982  Flags(const bool delete_and_rebuild_tria,
983  const unsigned int wakeup_level_to_build_grid,
984  const unsigned int sleep_level_to_delete_grid);
985 
997 
1006  const unsigned int wakeup_level_to_build_grid;
1007 
1012  const unsigned int sleep_level_to_delete_grid;
1013  };
1014 
1015 
1016 
1136  template <int dim>
1138  {
1144  using CorrectionRelaxations =
1145  std::vector<std::vector<std::pair<unsigned int, double>>>;
1146 
1151 
1156  RefinementFlags(const unsigned int max_refinement_level = 0,
1157  const unsigned int first_sweep_with_correction = 0,
1158  const unsigned int min_cells_for_correction = 0,
1159  const double cell_number_corridor_top = (1 << dim),
1160  const double cell_number_corridor_bottom = 1,
1161  const CorrectionRelaxations &correction_relaxations =
1163  const unsigned int cell_number_correction_steps = 0,
1164  const bool mirror_flags_to_previous_grid = false,
1165  const bool adapt_grids = false);
1166 
1175  const unsigned int max_refinement_level;
1176 
1182  const unsigned int first_sweep_with_correction;
1183 
1184 
1189  const unsigned int min_cells_for_correction;
1190 
1197 
1202 
1206  const std::vector<std::vector<std::pair<unsigned int, double>>>
1208 
1214  const unsigned int cell_number_correction_steps;
1215 
1233 
1237  const bool adapt_grids;
1238 
1242  DeclException1(ExcInvalidValue,
1243  double,
1244  << "The value " << arg1
1245  << " for the cell number corridor does not fulfill "
1246  "its natural requirements.");
1247  };
1248 
1249 
1250 
1257  template <int dim>
1259  {
1263  RefinementData(const double refinement_threshold,
1264  const double coarsening_threshold = 0);
1265 
1272  const double refinement_threshold;
1273 
1278  const double coarsening_threshold;
1279 
1283  DeclException1(ExcInvalidValue,
1284  double,
1285  << "The value " << arg1
1286  << " for the cell refinement thresholds does not fulfill "
1287  "its natural requirements.");
1288  };
1289 } // namespace TimeStepBase_Tria_Flags
1290 
1291 
1292 
1312 template <int dim>
1314 {
1315 public:
1321  using RefinementFlags =
1323  using RefinementData = typename TimeStepBase_Tria_Flags::RefinementData<dim>;
1324 
1325 
1331  {
1335  grid_refinement = 0x1000
1336  };
1337 
1338 
1348 
1362  const double time,
1363  const Triangulation<dim, dim> &coarse_grid,
1364  const Flags & flags,
1365  const RefinementFlags & refinement_flags = RefinementFlags());
1366 
1371  virtual ~TimeStepBase_Tria() override;
1372 
1393  virtual void
1394  wake_up(const unsigned int wakeup_level) override;
1395 
1409  virtual void
1410  sleep(const unsigned int) override;
1411 
1426  void
1427  refine_grid(const RefinementData data);
1428 
1434  virtual void
1435  init_for_refinement();
1436 
1444  virtual void
1445  get_tria_refinement_criteria(Vector<float> &criteria) const = 0;
1446 
1451  void
1452  save_refine_flags();
1453 
1462  virtual std::size_t
1463  memory_consumption() const override;
1464 
1468  DeclExceptionMsg(ExcGridNotDeleted,
1469  "When calling restore_grid(), you must have previously "
1470  "deleted the triangulation.");
1471 
1472 protected:
1481 
1489 
1494  const Flags flags;
1495 
1500  const RefinementFlags refinement_flags;
1501 
1502 private:
1508  std::vector<std::vector<bool>> refine_flags;
1509 
1513  std::vector<std::vector<bool>> coarsen_flags;
1514 
1519  void
1520  restore_grid();
1521 };
1522 
1523 
1524 
1525 /*--------------------------- template functions ----------------------------*/
1526 
1527 template <typename InitFunctionObject, typename LoopFunctionObject>
1528 void
1529 TimeDependent::do_loop(InitFunctionObject init_function,
1530  LoopFunctionObject loop_function,
1531  const TimeSteppingData &timestepping_data,
1532  const Direction direction)
1533 {
1534  // the following functions looks quite
1535  // disrupted due to the recurring switches
1536  // for forward and backward running loops.
1537  //
1538  // I chose to switch at every place where
1539  // it is needed, since it is so easy
1540  // to overlook something when you change
1541  // some code at one place when it needs
1542  // to be changed at a second place, here
1543  // for the other direction, also.
1544 
1545  const unsigned int n_timesteps = timesteps.size();
1546 
1547  // initialize the time steps for
1548  // a round of this loop
1549  for (unsigned int step = 0; step < n_timesteps; ++step)
1550  switch (direction)
1551  {
1552  case forward:
1553  init_function((&*timesteps[step]));
1554  break;
1555  case backward:
1556  init_function((&*timesteps[n_timesteps - step - 1]));
1557  break;
1558  };
1559 
1560 
1561  // wake up the first few time levels
1562  for (int step = -timestepping_data.look_ahead; step < 0; ++step)
1563  for (int look_ahead = 0;
1564  look_ahead <= static_cast<int>(timestepping_data.look_ahead);
1565  ++look_ahead)
1566  switch (direction)
1567  {
1568  case forward:
1569  if (step + look_ahead >= 0)
1570  timesteps[step + look_ahead]->wake_up(look_ahead);
1571  break;
1572  case backward:
1573  if (n_timesteps - (step + look_ahead) < n_timesteps)
1574  timesteps[n_timesteps - (step + look_ahead)]->wake_up(look_ahead);
1575  break;
1576  };
1577 
1578 
1579  for (unsigned int step = 0; step < n_timesteps; ++step)
1580  {
1581  // first thing: wake up the
1582  // timesteps ahead as necessary
1583  for (unsigned int look_ahead = 0;
1584  look_ahead <= timestepping_data.look_ahead;
1585  ++look_ahead)
1586  switch (direction)
1587  {
1588  case forward:
1589  if (step + look_ahead < n_timesteps)
1590  timesteps[step + look_ahead]->wake_up(look_ahead);
1591  break;
1592  case backward:
1593  if (n_timesteps > (step + look_ahead))
1594  timesteps[n_timesteps - (step + look_ahead) - 1]->wake_up(
1595  look_ahead);
1596  break;
1597  };
1598 
1599 
1600  // actually do the work
1601  switch (direction)
1602  {
1603  case forward:
1604  loop_function((&*timesteps[step]));
1605  break;
1606  case backward:
1607  loop_function((&*timesteps[n_timesteps - step - 1]));
1608  break;
1609  };
1610 
1611  // let the timesteps behind sleep
1612  for (unsigned int look_back = 0; look_back <= timestepping_data.look_back;
1613  ++look_back)
1614  switch (direction)
1615  {
1616  case forward:
1617  if (step >= look_back)
1618  timesteps[step - look_back]->sleep(look_back);
1619  break;
1620  case backward:
1621  if (n_timesteps - (step - look_back) <= n_timesteps)
1622  timesteps[n_timesteps - (step - look_back) - 1]->sleep(
1623  look_back);
1624  break;
1625  }
1626  }
1627 
1628  // make the last few timesteps sleep
1629  for (int step = n_timesteps;
1630  step < static_cast<int>(n_timesteps + timestepping_data.look_back);
1631  ++step)
1632  for (int look_back = 0;
1633  look_back <= static_cast<int>(timestepping_data.look_back);
1634  ++look_back)
1635  switch (direction)
1636  {
1637  case forward:
1638  if ((step - look_back >= 0) &&
1639  (step - look_back < static_cast<int>(n_timesteps)))
1640  timesteps[step - look_back]->sleep(look_back);
1641  break;
1642  case backward:
1643  if ((step - look_back >= 0) &&
1644  (step - look_back < static_cast<int>(n_timesteps)))
1645  timesteps[n_timesteps - (step - look_back) - 1]->sleep(look_back);
1646  break;
1647  };
1648 }
1649 
1650 DEAL_II_NAMESPACE_CLOSE
1651 
1652 /*---------------------------- time-dependent.h ---------------------------*/
1653 #endif
1654 /*---------------------------- time-dependent.h ---------------------------*/
std::size_t memory_consumption() const
unsigned int next_action
const std::vector< std::vector< std::pair< unsigned int, double > > > correction_relaxations
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
std::vector< std::vector< std::pair< unsigned int, double >>> CorrectionRelaxations
SmartPointer< const Triangulation< dim, dim >, TimeStepBase_Tria< dim > > coarse_grid
unsigned int timestep_no
void do_loop(InitFunctionObject init_function, LoopFunctionObject loop_function, const TimeSteppingData &timestepping_data, const Direction direction)
const RefinementFlags refinement_flags
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:408
const double time
std::vector< SmartPointer< TimeStepBase, TimeDependent > > timesteps
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:397
virtual ~TimeDependent()
const TimeSteppingData timestepping_data_primal
static::ExceptionBase & ExcInvalidPosition()
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)
typename TimeStepBase_Tria_Flags::Flags< dim > Flags
unsigned int sweep_no
void insert_timestep(const TimeStepBase *position, TimeStepBase *new_timestep)
std::vector< std::vector< bool > > refine_flags
SmartPointer< Triangulation< dim, dim >, TimeStepBase_Tria< dim > > tria
std::vector< std::vector< bool > > coarsen_flags
virtual void end_sweep()
unsigned int sweep_no
TimeSteppingData(const unsigned int look_ahead, const unsigned int look_back)