Reference documentation for deal.II version Git 7026f387cc 2019-10-15 14:19:01 -0400
\(\newcommand{\dealcoloneq}{\mathrel{\vcenter{:}}=}\)
time_dependent.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1999 - 2019 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 # ifndef DOXYGEN
36 class TimeStepBase;
37 template <typename number>
38 class Vector;
39 template <int dim, int spacedim>
40 class Triangulation;
41 # endif
42 
365 {
366 public:
374  {
379  TimeSteppingData(const unsigned int look_ahead,
380  const unsigned int look_back);
381 
400  const unsigned int look_ahead;
401 
414  const unsigned int look_back;
415  };
416 
422  {
431  };
432 
436  TimeDependent(const TimeSteppingData &data_primal,
437  const TimeSteppingData &data_dual,
438  const TimeSteppingData &data_postprocess);
439 
440 
446  virtual ~TimeDependent();
447 
468  void
469  insert_timestep(const TimeStepBase *position, TimeStepBase *new_timestep);
470 
480  void
481  add_timestep(TimeStepBase *new_timestep);
482 
495  void
496  delete_timestep(const unsigned int position);
497 
506  void
508 
517  void
519 
528  void
529  postprocess();
530 
557  template <typename InitFunctionObject, typename LoopFunctionObject>
558  void
559  do_loop(InitFunctionObject init_function,
560  LoopFunctionObject loop_function,
561  const TimeSteppingData &timestepping_data,
562  const Direction direction);
563 
564 
582  virtual void
583  start_sweep(const unsigned int sweep_no);
584 
598  virtual void
599  end_sweep();
600 
605  std::size_t
606  memory_consumption() const;
607 
612  "You cannot insert a time step at the specified position.");
613 
614 protected:
620  std::vector<SmartPointer<TimeStepBase, TimeDependent>> timesteps;
621 
626  unsigned int sweep_no;
627 
633 
639 
645 
646 private:
651  void
652  end_sweep(const unsigned int begin_timestep, const unsigned int end_timestep);
653 };
654 
655 
656 
666 class TimeStepBase : public Subscriptor
667 {
668 public:
673  {
677  primal_problem = 0x0,
681  dual_problem = 0x1,
686  };
687 
691  TimeStepBase(const double time);
692 
696  virtual ~TimeStepBase() override = default;
697 
702  TimeStepBase(const TimeStepBase &) = delete;
703 
708  TimeStepBase &
709  operator=(const TimeStepBase &) = delete;
710 
726  virtual void
727  wake_up(const unsigned int);
728 
738  virtual void
739  sleep(const unsigned int);
740 
756  virtual void
757  start_sweep();
758 
764  virtual void
765  end_sweep();
766 
774  virtual void
775  init_for_primal_problem();
776 
780  virtual void
781  init_for_dual_problem();
782 
786  virtual void
787  init_for_postprocessing();
788 
796  virtual void
797  solve_primal_problem() = 0;
798 
808  virtual void
810 
820  virtual void
821  postprocess_timestep();
822 
826  double
827  get_time() const;
828 
833  unsigned int
834  get_timestep_no() const;
835 
849  double
850  get_backward_timestep() const;
851 
857  double
858  get_forward_timestep() const;
859 
868  virtual std::size_t
869  memory_consumption() const;
870 
871 protected:
876 
881 
886  unsigned int sweep_no;
887 
893  unsigned int timestep_no;
894 
898  const double time;
899 
905  unsigned int next_action;
906 
907 private:
915  void
916  set_previous_timestep(const TimeStepBase *previous);
917 
925  void
926  set_next_timestep(const TimeStepBase *next);
927 
934  void
935  set_timestep_no(const unsigned int step_no);
936 
941  void
942  set_sweep_no(const unsigned int sweep_no);
943 
944  // make the manager object a friend
945  friend class TimeDependent;
946 };
947 
948 
949 
959 {
967  template <int dim>
968  struct Flags
969  {
973  Flags();
974 
979  Flags(const bool delete_and_rebuild_tria,
980  const unsigned int wakeup_level_to_build_grid,
981  const unsigned int sleep_level_to_delete_grid);
982 
994 
1003  const unsigned int wakeup_level_to_build_grid;
1004 
1009  const unsigned int sleep_level_to_delete_grid;
1010  };
1011 
1012 
1013 
1133  template <int dim>
1135  {
1141  using CorrectionRelaxations =
1142  std::vector<std::vector<std::pair<unsigned int, double>>>;
1143 
1148 
1153  RefinementFlags(const unsigned int max_refinement_level = 0,
1154  const unsigned int first_sweep_with_correction = 0,
1155  const unsigned int min_cells_for_correction = 0,
1156  const double cell_number_corridor_top = (1 << dim),
1157  const double cell_number_corridor_bottom = 1,
1158  const CorrectionRelaxations &correction_relaxations =
1160  const unsigned int cell_number_correction_steps = 0,
1161  const bool mirror_flags_to_previous_grid = false,
1162  const bool adapt_grids = false);
1163 
1172  const unsigned int max_refinement_level;
1173 
1179  const unsigned int first_sweep_with_correction;
1180 
1181 
1186  const unsigned int min_cells_for_correction;
1187 
1194 
1199 
1203  const std::vector<std::vector<std::pair<unsigned int, double>>>
1205 
1211  const unsigned int cell_number_correction_steps;
1212 
1230 
1234  const bool adapt_grids;
1235 
1239  DeclException1(ExcInvalidValue,
1240  double,
1241  << "The value " << arg1
1242  << " for the cell number corridor does not fulfill "
1243  "its natural requirements.");
1244  };
1245 
1246 
1247 
1254  template <int dim>
1256  {
1260  RefinementData(const double refinement_threshold,
1261  const double coarsening_threshold = 0);
1262 
1269  const double refinement_threshold;
1270 
1275  const double coarsening_threshold;
1276 
1280  DeclException1(ExcInvalidValue,
1281  double,
1282  << "The value " << arg1
1283  << " for the cell refinement thresholds does not fulfill "
1284  "its natural requirements.");
1285  };
1286 } // namespace TimeStepBase_Tria_Flags
1287 
1288 
1289 
1309 template <int dim>
1311 {
1312 public:
1318  using RefinementFlags =
1320  using RefinementData = typename TimeStepBase_Tria_Flags::RefinementData<dim>;
1321 
1322 
1328  {
1332  grid_refinement = 0x1000
1333  };
1334 
1335 
1345 
1359  const double time,
1360  const Triangulation<dim, dim> &coarse_grid,
1361  const Flags & flags,
1362  const RefinementFlags & refinement_flags = RefinementFlags());
1363 
1368  virtual ~TimeStepBase_Tria() override;
1369 
1390  virtual void
1391  wake_up(const unsigned int wakeup_level) override;
1392 
1406  virtual void
1407  sleep(const unsigned int) override;
1408 
1423  void
1424  refine_grid(const RefinementData data);
1425 
1431  virtual void
1432  init_for_refinement();
1433 
1441  virtual void
1442  get_tria_refinement_criteria(Vector<float> &criteria) const = 0;
1443 
1448  void
1449  save_refine_flags();
1450 
1459  virtual std::size_t
1460  memory_consumption() const override;
1461 
1465  DeclExceptionMsg(ExcGridNotDeleted,
1466  "When calling restore_grid(), you must have previously "
1467  "deleted the triangulation.");
1468 
1469 protected:
1478 
1486 
1491  const Flags flags;
1492 
1497  const RefinementFlags refinement_flags;
1498 
1499 private:
1505  std::vector<std::vector<bool>> refine_flags;
1506 
1510  std::vector<std::vector<bool>> coarsen_flags;
1511 
1516  void
1517  restore_grid();
1518 };
1519 
1520 
1521 
1522 /*--------------------------- template functions ----------------------------*/
1523 
1524 template <typename InitFunctionObject, typename LoopFunctionObject>
1525 void
1526 TimeDependent::do_loop(InitFunctionObject init_function,
1527  LoopFunctionObject loop_function,
1528  const TimeSteppingData &timestepping_data,
1529  const Direction direction)
1530 {
1531  // the following functions looks quite
1532  // disrupted due to the recurring switches
1533  // for forward and backward running loops.
1534  //
1535  // I chose to switch at every place where
1536  // it is needed, since it is so easy
1537  // to overlook something when you change
1538  // some code at one place when it needs
1539  // to be changed at a second place, here
1540  // for the other direction, also.
1541 
1542  const unsigned int n_timesteps = timesteps.size();
1543 
1544  // initialize the time steps for
1545  // a round of this loop
1546  for (unsigned int step = 0; step < n_timesteps; ++step)
1547  switch (direction)
1548  {
1549  case forward:
1550  init_function((&*timesteps[step]));
1551  break;
1552  case backward:
1553  init_function((&*timesteps[n_timesteps - step - 1]));
1554  break;
1555  };
1556 
1557 
1558  // wake up the first few time levels
1559  for (int step = -static_cast<int>(timestepping_data.look_ahead); step < 0;
1560  ++step)
1561  for (int look_ahead = 0;
1562  look_ahead <= static_cast<int>(timestepping_data.look_ahead);
1563  ++look_ahead)
1564  switch (direction)
1565  {
1566  case forward:
1567  if (step + look_ahead >= 0)
1568  timesteps[step + look_ahead]->wake_up(look_ahead);
1569  break;
1570  case backward:
1571  if (n_timesteps - (step + look_ahead) < n_timesteps)
1572  timesteps[n_timesteps - (step + look_ahead)]->wake_up(look_ahead);
1573  break;
1574  };
1575 
1576 
1577  for (unsigned int step = 0; step < n_timesteps; ++step)
1578  {
1579  // first thing: wake up the
1580  // timesteps ahead as necessary
1581  for (unsigned int look_ahead = 0;
1582  look_ahead <= timestepping_data.look_ahead;
1583  ++look_ahead)
1584  switch (direction)
1585  {
1586  case forward:
1587  if (step + look_ahead < n_timesteps)
1588  timesteps[step + look_ahead]->wake_up(look_ahead);
1589  break;
1590  case backward:
1591  if (n_timesteps > (step + look_ahead))
1592  timesteps[n_timesteps - (step + look_ahead) - 1]->wake_up(
1593  look_ahead);
1594  break;
1595  };
1596 
1597 
1598  // actually do the work
1599  switch (direction)
1600  {
1601  case forward:
1602  loop_function((&*timesteps[step]));
1603  break;
1604  case backward:
1605  loop_function((&*timesteps[n_timesteps - step - 1]));
1606  break;
1607  };
1608 
1609  // let the timesteps behind sleep
1610  for (unsigned int look_back = 0; look_back <= timestepping_data.look_back;
1611  ++look_back)
1612  switch (direction)
1613  {
1614  case forward:
1615  if (step >= look_back)
1616  timesteps[step - look_back]->sleep(look_back);
1617  break;
1618  case backward:
1619  if (n_timesteps - (step - look_back) <= n_timesteps)
1620  timesteps[n_timesteps - (step - look_back) - 1]->sleep(
1621  look_back);
1622  break;
1623  }
1624  }
1625 
1626  // make the last few timesteps sleep
1627  for (int step = n_timesteps;
1628  step < static_cast<int>(n_timesteps + timestepping_data.look_back);
1629  ++step)
1630  for (int look_back = 0;
1631  look_back <= static_cast<int>(timestepping_data.look_back);
1632  ++look_back)
1633  switch (direction)
1634  {
1635  case forward:
1636  if ((step - look_back >= 0) &&
1637  (step - look_back < static_cast<int>(n_timesteps)))
1638  timesteps[step - look_back]->sleep(look_back);
1639  break;
1640  case backward:
1641  if ((step - look_back >= 0) &&
1642  (step - look_back < static_cast<int>(n_timesteps)))
1643  timesteps[n_timesteps - (step - look_back) - 1]->sleep(look_back);
1644  break;
1645  };
1646 }
1647 
1648 DEAL_II_NAMESPACE_CLOSE
1649 
1650 /*---------------------------- time-dependent.h ---------------------------*/
1651 #endif
1652 /*---------------------------- time-dependent.h ---------------------------*/
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
LinearAlgebra::distributed::Vector< Number > Vector
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
std::vector< std::vector< std::pair< unsigned int, double > >> CorrectionRelaxations
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:518
std::size_t memory_consumption() const
const double time
std::vector< SmartPointer< TimeStepBase, TimeDependent > > timesteps
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:496
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)