Reference documentation for deal.II version GIT 2f5445400b 2023-02-05 22:30:02+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
time_dependent.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1999 - 2020 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 #include <deal.II/base/config.h>
21 
25 
26 #include <utility>
27 #include <vector>
28 
30 
31 // forward declarations
32 #ifndef DOXYGEN
33 class TimeStepBase;
34 template <typename number>
35 class Vector;
36 template <int dim, int spacedim>
37 class Triangulation;
38 #endif
39 
359 {
360 public:
368  {
373  TimeSteppingData(const unsigned int look_ahead,
374  const unsigned int look_back);
375 
394  const unsigned int look_ahead;
395 
408  const unsigned int look_back;
409  };
410 
416  {
424  backward
425  };
426 
430  TimeDependent(const TimeSteppingData &data_primal,
431  const TimeSteppingData &data_dual,
432  const TimeSteppingData &data_postprocess);
433 
434 
440  virtual ~TimeDependent();
441 
462  void
463  insert_timestep(const TimeStepBase *position, TimeStepBase *new_timestep);
464 
474  void
475  add_timestep(TimeStepBase *new_timestep);
476 
489  void
490  delete_timestep(const unsigned int position);
491 
500  void
502 
511  void
513 
522  void
523  postprocess();
524 
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 
662 class TimeStepBase : public Subscriptor
663 {
664 public:
669  {
681  postprocess = 0x2
682  };
683 
687  TimeStepBase(const double time);
688 
692  virtual ~TimeStepBase() override = default;
693 
698  TimeStepBase(const TimeStepBase &) = delete;
699 
704  TimeStepBase &
705  operator=(const TimeStepBase &) = delete;
706 
722  virtual void
723  wake_up(const unsigned int);
724 
734  virtual void
735  sleep(const unsigned int);
736 
752  virtual void
753  start_sweep();
754 
760  virtual void
761  end_sweep();
762 
770  virtual void
772 
776  virtual void
778 
782  virtual void
784 
792  virtual void
794 
804  virtual void
806 
816  virtual void
818 
822  double
823  get_time() const;
824 
829  unsigned int
830  get_timestep_no() const;
831 
845  double
846  get_backward_timestep() const;
847 
853  double
854  get_forward_timestep() const;
855 
864  virtual std::size_t
865  memory_consumption() const;
866 
867 protected:
872 
877 
882  unsigned int sweep_no;
883 
889  unsigned int timestep_no;
890 
894  const double time;
895 
901  unsigned int next_action;
902 
903 private:
911  void
912  set_previous_timestep(const TimeStepBase *previous);
913 
921  void
922  set_next_timestep(const TimeStepBase *next);
923 
930  void
931  set_timestep_no(const unsigned int step_no);
932 
937  void
938  set_sweep_no(const unsigned int sweep_no);
939 
940  // make the manager object a friend
941  friend class TimeDependent;
942 };
943 
944 
945 
953 {
961  template <int dim>
962  struct Flags
963  {
967  Flags();
968 
973  Flags(const bool delete_and_rebuild_tria,
974  const unsigned int wakeup_level_to_build_grid,
975  const unsigned int sleep_level_to_delete_grid);
976 
988 
997  const unsigned int wakeup_level_to_build_grid;
998 
1003  const unsigned int sleep_level_to_delete_grid;
1004  };
1005 
1006 
1007 
1127  template <int dim>
1129  {
1136  std::vector<std::vector<std::pair<unsigned int, double>>>;
1137 
1142 
1147  RefinementFlags(const unsigned int max_refinement_level = 0,
1148  const unsigned int first_sweep_with_correction = 0,
1149  const unsigned int min_cells_for_correction = 0,
1150  const double cell_number_corridor_top = (1 << dim),
1151  const double cell_number_corridor_bottom = 1,
1154  const unsigned int cell_number_correction_steps = 0,
1155  const bool mirror_flags_to_previous_grid = false,
1156  const bool adapt_grids = false);
1157 
1166  const unsigned int max_refinement_level;
1167 
1173  const unsigned int first_sweep_with_correction;
1174 
1175 
1180  const unsigned int min_cells_for_correction;
1181 
1188 
1193 
1197  const std::vector<std::vector<std::pair<unsigned int, double>>>
1199 
1205  const unsigned int cell_number_correction_steps;
1206 
1224 
1228  const bool adapt_grids;
1229 
1234  double,
1235  << "The value " << arg1
1236  << " for the cell number corridor does not fulfill "
1237  "its natural requirements.");
1238  };
1239 
1240 
1241 
1248  template <int dim>
1250  {
1254  RefinementData(const double refinement_threshold,
1255  const double coarsening_threshold = 0);
1256 
1263  const double refinement_threshold;
1264 
1269  const double coarsening_threshold;
1270 
1275  double,
1276  << "The value " << arg1
1277  << " for the cell refinement thresholds does not fulfill "
1278  "its natural requirements.");
1279  };
1280 } // namespace TimeStepBase_Tria_Flags
1281 
1282 
1283 
1300 template <int dim>
1302 {
1303 public:
1312 
1313 
1319  {
1323  grid_refinement = 0x1000
1324  };
1325 
1326 
1336 
1350  const double time,
1352  const Flags & flags,
1354 
1359  virtual ~TimeStepBase_Tria() override;
1360 
1381  virtual void
1382  wake_up(const unsigned int wakeup_level) override;
1383 
1397  virtual void
1398  sleep(const unsigned int) override;
1399 
1414  void
1415  refine_grid(const RefinementData data);
1416 
1422  virtual void
1424 
1432  virtual void
1434 
1439  void
1441 
1450  virtual std::size_t
1451  memory_consumption() const override;
1452 
1457  "When calling restore_grid(), you must have previously "
1458  "deleted the triangulation.");
1459 
1460 protected:
1469 
1477 
1482  const Flags flags;
1483 
1489 
1490 private:
1496  std::vector<std::vector<bool>> refine_flags;
1497 
1501  std::vector<std::vector<bool>> coarsen_flags;
1502 
1507  void
1508  restore_grid();
1509 };
1510 
1511 
1512 
1513 /*--------------------------- template functions ----------------------------*/
1514 
1515 template <typename InitFunctionObject, typename LoopFunctionObject>
1516 void
1517 TimeDependent::do_loop(InitFunctionObject init_function,
1518  LoopFunctionObject loop_function,
1519  const TimeSteppingData &timestepping_data,
1520  const Direction direction)
1521 {
1522  // the following functions looks quite
1523  // disrupted due to the recurring switches
1524  // for forward and backward running loops.
1525  //
1526  // I chose to switch at every place where
1527  // it is needed, since it is so easy
1528  // to overlook something when you change
1529  // some code at one place when it needs
1530  // to be changed at a second place, here
1531  // for the other direction, also.
1532 
1533  const unsigned int n_timesteps = timesteps.size();
1534 
1535  // initialize the time steps for
1536  // a round of this loop
1537  for (unsigned int step = 0; step < n_timesteps; ++step)
1538  switch (direction)
1539  {
1540  case forward:
1541  init_function((&*timesteps[step]));
1542  break;
1543  case backward:
1544  init_function((&*timesteps[n_timesteps - step - 1]));
1545  break;
1546  };
1547 
1548 
1549  // wake up the first few time levels
1550  for (int step = -static_cast<int>(timestepping_data.look_ahead); step < 0;
1551  ++step)
1552  for (int look_ahead = 0;
1553  look_ahead <= static_cast<int>(timestepping_data.look_ahead);
1554  ++look_ahead)
1555  switch (direction)
1556  {
1557  case forward:
1558  if (step + look_ahead >= 0)
1559  timesteps[step + look_ahead]->wake_up(look_ahead);
1560  break;
1561  case backward:
1562  if (n_timesteps - (step + look_ahead) < n_timesteps)
1563  timesteps[n_timesteps - (step + look_ahead)]->wake_up(look_ahead);
1564  break;
1565  };
1566 
1567 
1568  for (unsigned int step = 0; step < n_timesteps; ++step)
1569  {
1570  // first thing: wake up the
1571  // timesteps ahead as necessary
1572  for (unsigned int look_ahead = 0;
1573  look_ahead <= timestepping_data.look_ahead;
1574  ++look_ahead)
1575  switch (direction)
1576  {
1577  case forward:
1578  if (step + look_ahead < n_timesteps)
1579  timesteps[step + look_ahead]->wake_up(look_ahead);
1580  break;
1581  case backward:
1582  if (n_timesteps > (step + look_ahead))
1583  timesteps[n_timesteps - (step + look_ahead) - 1]->wake_up(
1584  look_ahead);
1585  break;
1586  };
1587 
1588 
1589  // actually do the work
1590  switch (direction)
1591  {
1592  case forward:
1593  loop_function((&*timesteps[step]));
1594  break;
1595  case backward:
1596  loop_function((&*timesteps[n_timesteps - step - 1]));
1597  break;
1598  };
1599 
1600  // let the timesteps behind sleep
1601  for (unsigned int look_back = 0; look_back <= timestepping_data.look_back;
1602  ++look_back)
1603  switch (direction)
1604  {
1605  case forward:
1606  if (step >= look_back)
1607  timesteps[step - look_back]->sleep(look_back);
1608  break;
1609  case backward:
1610  if (n_timesteps - (step - look_back) <= n_timesteps)
1611  timesteps[n_timesteps - (step - look_back) - 1]->sleep(
1612  look_back);
1613  break;
1614  }
1615  }
1616 
1617  // make the last few timesteps sleep
1618  for (int step = n_timesteps;
1619  step < static_cast<int>(n_timesteps + timestepping_data.look_back);
1620  ++step)
1621  for (int look_back = 0;
1622  look_back <= static_cast<int>(timestepping_data.look_back);
1623  ++look_back)
1624  switch (direction)
1625  {
1626  case forward:
1627  if ((step - look_back >= 0) &&
1628  (step - look_back < static_cast<int>(n_timesteps)))
1629  timesteps[step - look_back]->sleep(look_back);
1630  break;
1631  case backward:
1632  if ((step - look_back >= 0) &&
1633  (step - look_back < static_cast<int>(n_timesteps)))
1634  timesteps[n_timesteps - (step - look_back) - 1]->sleep(look_back);
1635  break;
1636  };
1637 }
1638 
1640 
1641 #endif
void insert_timestep(const TimeStepBase *position, TimeStepBase *new_timestep)
virtual void start_sweep(const unsigned int sweep_no)
std::size_t memory_consumption() const
const TimeSteppingData timestepping_data_primal
virtual void end_sweep()
std::vector< SmartPointer< TimeStepBase, TimeDependent > > timesteps
void solve_dual_problem()
virtual ~TimeDependent()
void do_loop(InitFunctionObject init_function, LoopFunctionObject loop_function, const TimeSteppingData &timestepping_data, const Direction direction)
const TimeSteppingData timestepping_data_dual
void solve_primal_problem()
unsigned int sweep_no
TimeDependent(const TimeSteppingData &data_primal, const TimeSteppingData &data_dual, const TimeSteppingData &data_postprocess)
void delete_timestep(const unsigned int position)
void add_timestep(TimeStepBase *new_timestep)
const TimeSteppingData timestepping_data_postprocess
virtual void wake_up(const unsigned int wakeup_level) override
typename TimeStepBase_Tria_Flags::Flags< dim > Flags
std::vector< std::vector< bool > > coarsen_flags
virtual void sleep(const unsigned int) override
TimeStepBase_Tria(const double time, const Triangulation< dim, dim > &coarse_grid, const Flags &flags, const RefinementFlags &refinement_flags=RefinementFlags())
virtual std::size_t memory_consumption() const override
void refine_grid(const RefinementData data)
virtual void init_for_refinement()
SmartPointer< const Triangulation< dim, dim >, TimeStepBase_Tria< dim > > coarse_grid
typename TimeStepBase_Tria_Flags::RefinementData< dim > RefinementData
virtual void get_tria_refinement_criteria(Vector< float > &criteria) const =0
const RefinementFlags refinement_flags
virtual ~TimeStepBase_Tria() override
SmartPointer< Triangulation< dim, dim >, TimeStepBase_Tria< dim > > tria
typename TimeStepBase_Tria_Flags::RefinementFlags< dim > RefinementFlags
std::vector< std::vector< bool > > refine_flags
virtual std::size_t memory_consumption() const
double get_forward_timestep() const
TimeStepBase(const double time)
virtual void wake_up(const unsigned int)
void set_timestep_no(const unsigned int step_no)
void set_previous_timestep(const TimeStepBase *previous)
const TimeStepBase * previous_timestep
TimeStepBase(const TimeStepBase &)=delete
virtual ~TimeStepBase() override=default
virtual void postprocess_timestep()
TimeStepBase & operator=(const TimeStepBase &)=delete
virtual void sleep(const unsigned int)
unsigned int timestep_no
void set_next_timestep(const TimeStepBase *next)
unsigned int get_timestep_no() const
unsigned int next_action
double get_backward_timestep() const
void set_sweep_no(const unsigned int sweep_no)
const double time
unsigned int sweep_no
virtual void end_sweep()
virtual void solve_primal_problem()=0
virtual void init_for_postprocessing()
virtual void start_sweep()
virtual void init_for_primal_problem()
double get_time() const
virtual void solve_dual_problem()
virtual void init_for_dual_problem()
const TimeStepBase * next_timestep
Definition: vector.h:109
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:461
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:462
static ::ExceptionBase & ExcGridNotDeleted()
static ::ExceptionBase & ExcInvalidValue(double arg1)
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:488
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:510
static ::ExceptionBase & ExcInvalidPosition()
static ::ExceptionBase & ExcInvalidValue(double arg1)
TimeSteppingData(const unsigned int look_ahead, const unsigned int look_back)
const unsigned int wakeup_level_to_build_grid
const unsigned int sleep_level_to_delete_grid
RefinementData(const double refinement_threshold, const double coarsening_threshold=0)
RefinementFlags(const unsigned int max_refinement_level=0, const unsigned int first_sweep_with_correction=0, const unsigned int min_cells_for_correction=0, const double cell_number_corridor_top=(1<< dim), const double cell_number_corridor_bottom=1, const CorrectionRelaxations &correction_relaxations=CorrectionRelaxations(), const unsigned int cell_number_correction_steps=0, const bool mirror_flags_to_previous_grid=false, const bool adapt_grids=false)
std::vector< std::vector< std::pair< unsigned int, double > >> CorrectionRelaxations
const std::vector< std::vector< std::pair< unsigned int, double > > > correction_relaxations
static CorrectionRelaxations default_correction_relaxations