Reference documentation for deal.II version 8.4.2
time_dependent.cc
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 #include <deal.II/numerics/time_dependent.h>
17 #include <deal.II/base/memory_consumption.h>
18 #include <deal.II/base/thread_management.h>
19 #include <deal.II/base/utilities.h>
20 #include <deal.II/base/parallel.h>
21 #include <deal.II/grid/tria.h>
22 #include <deal.II/grid/tria_accessor.h>
23 #include <deal.II/grid/tria_iterator.h>
24 #include <deal.II/grid/grid_refinement.h>
25 #include <deal.II/lac/vector.h>
26 
27 #include <functional>
28 #include <algorithm>
29 #include <numeric>
30 
31 DEAL_II_NAMESPACE_OPEN
32 
34  const unsigned int look_back)
35  :
36  look_ahead (look_ahead),
37  look_back (look_back)
38 {}
39 
40 
42  const TimeSteppingData &data_dual,
43  const TimeSteppingData &data_postprocess):
44  sweep_no (numbers::invalid_unsigned_int),
45  timestepping_data_primal (data_primal),
46  timestepping_data_dual (data_dual),
47  timestepping_data_postprocess (data_postprocess)
48 {}
49 
50 
52 {
53  while (timesteps.size() != 0)
54  delete_timestep (0);
55 }
56 
57 
58 void
60  TimeStepBase *new_timestep)
61 {
62  Assert ((std::find(timesteps.begin(), timesteps.end(), position) != timesteps.end()) ||
63  (position == 0),
64  ExcInvalidPosition());
65  // first insert the new time step
66  // into the doubly linked list
67  // of timesteps
68  if (position == 0)
69  {
70  // at the end
71  new_timestep->set_next_timestep (0);
72  if (timesteps.size() > 0)
73  {
74  timesteps.back()->set_next_timestep (new_timestep);
75  new_timestep->set_previous_timestep (timesteps.back());
76  }
77  else
78  new_timestep->set_previous_timestep (0);
79  }
80  else if (position == timesteps[0])
81  {
82  // at the beginning
83  new_timestep->set_previous_timestep (0);
84  if (timesteps.size() > 0)
85  {
86  timesteps[0]->set_previous_timestep (new_timestep);
87  new_timestep->set_next_timestep (timesteps[0]);
88  }
89  else
90  new_timestep->set_next_timestep (0);
91  }
92  else
93  {
94  // inner time step
95  std::vector<SmartPointer<TimeStepBase,TimeDependent> >::iterator insert_position
96  = std::find(timesteps.begin(), timesteps.end(), position);
97 
98  (*(insert_position-1))->set_next_timestep (new_timestep);
99  new_timestep->set_previous_timestep (*(insert_position-1));
100  new_timestep->set_next_timestep (*insert_position);
101  (*insert_position)->set_previous_timestep (new_timestep);
102  };
103 
104  // finally enter it into the
105  // array
106  timesteps.insert ((position == 0 ?
107  timesteps.end() :
108  std::find(timesteps.begin(), timesteps.end(), position)),
109  new_timestep);
110 }
111 
112 
113 void
115 {
116  insert_timestep (0, new_timestep);
117 }
118 
119 
120 void TimeDependent::delete_timestep (const unsigned int position)
121 {
122  Assert (position<timesteps.size(),
123  ExcInvalidPosition());
124 
125  // Remember time step object for
126  // later deletion and unlock
127  // SmartPointer
128  TimeStepBase *t = timesteps[position];
129  timesteps[position] = 0;
130  // Now delete unsubscribed object
131  delete t;
132 
133  timesteps.erase (timesteps.begin() + position);
134 
135  // reset "next" pointer of previous
136  // time step if possible
137  //
138  // note that if now position==size,
139  // then we deleted the last time step
140  if (position != 0)
141  timesteps[position-1]->set_next_timestep ((position<timesteps.size()) ?
142  timesteps[position] :
144 
145  // same for "previous" pointer of next
146  // time step
147  if (position<timesteps.size())
148  timesteps[position]->set_previous_timestep ((position!=0) ?
149  timesteps[position-1] :
151 }
152 
153 
154 void
156 {
158  std::mem_fun(&TimeStepBase::solve_primal_problem),
160  forward);
161 }
162 
163 
164 void
166 {
168  std::mem_fun(&TimeStepBase::solve_dual_problem),
170  backward);
171 }
172 
173 
174 void
176 {
178  std::mem_fun(&TimeStepBase::postprocess_timestep),
180  forward);
181 }
182 
183 
184 
185 void TimeDependent::start_sweep (const unsigned int s)
186 {
187  sweep_no = s;
188 
189  // reset the number each
190  // time step has, since some time
191  // steps might have been added since
192  // the last time we visited them
193  //
194  // also set the sweep we will
195  // process in the sequel
196  for (unsigned int step=0; step<timesteps.size(); ++step)
197  {
198  timesteps[step]->set_timestep_no (step);
199  timesteps[step]->set_sweep_no (sweep_no);
200  };
201 
202  for (unsigned int step=0; step<timesteps.size(); ++step)
203  timesteps[step]->start_sweep ();
204 }
205 
206 
207 
209 {
210  void (TimeDependent::*p) (const unsigned int, const unsigned int)
213  std_cxx11::bind (p, this, std_cxx11::_1, std_cxx11::_2),
214  1);
215 }
216 
217 
218 
219 void TimeDependent::end_sweep (const unsigned int begin,
220  const unsigned int end)
221 {
222  for (unsigned int step=begin; step<end; ++step)
223  timesteps[step]->end_sweep ();
224 }
225 
226 
227 
228 std::size_t
230 {
231  std::size_t mem = (MemoryConsumption::memory_consumption (timesteps) +
233  sizeof(timestepping_data_primal) +
234  sizeof(timestepping_data_dual) +
236  for (unsigned int i=0; i<timesteps.size(); ++i)
238 
239  return mem;
240 }
241 
242 
243 
244 /* --------------------------------------------------------------------- */
245 
246 
247 TimeStepBase::TimeStepBase (const double time) :
248  previous_timestep(0),
249  next_timestep (0),
250  sweep_no (numbers::invalid_unsigned_int),
251  timestep_no (numbers::invalid_unsigned_int),
252  time (time)
253 {}
254 
255 
256 
258 {}
259 
260 
261 
262 void
263 TimeStepBase::wake_up (const unsigned int )
264 {}
265 
266 
267 
268 void
269 TimeStepBase::sleep (const unsigned)
270 {}
271 
272 
273 
274 void
276 {}
277 
278 
279 
280 void
282 {}
283 
284 
285 
286 void
288 {
289  next_action = primal_problem;
290 }
291 
292 
293 
294 void
296 {
297  next_action = dual_problem;
298 }
299 
300 
301 
302 void
304 {
305  next_action = postprocess;
306 }
307 
308 
309 
310 void
312 {
313  Assert (false, ExcPureFunctionCalled());
314 }
315 
316 
317 
318 void
320 {
321  Assert (false, ExcPureFunctionCalled());
322 }
323 
324 
325 
326 double
328 {
329  return time;
330 }
331 
332 
333 
334 unsigned int
336 {
337  return timestep_no;
338 }
339 
340 
341 
342 double
344 {
346  ExcMessage("The backward time step cannot be computed because "
347  "there is no previous time step."));
348  return time - previous_timestep->time;
349 }
350 
351 
352 
353 double
355 {
356  Assert (next_timestep != 0,
357  ExcMessage("The forward time step cannot be computed because "
358  "there is no next time step."));
359  return next_timestep->time - time;
360 }
361 
362 
363 
364 void
366 {
367  previous_timestep = previous;
368 }
369 
370 
371 
372 void
374 {
375  next_timestep = next;
376 }
377 
378 
379 
380 void
381 TimeStepBase::set_timestep_no (const unsigned int step_no)
382 {
383  timestep_no = step_no;
384 }
385 
386 
387 
388 void
389 TimeStepBase::set_sweep_no (const unsigned int sweep)
390 {
391  sweep_no = sweep;
392 }
393 
394 
395 
396 std::size_t
398 {
399  // only simple data types
400  return sizeof(*this);
401 }
402 
403 
404 
405 template <int dim>
407  TimeStepBase (0),
408  tria (0, typeid(*this).name()),
409  coarse_grid (0, typeid(*this).name()),
410  flags (),
411  refinement_flags(0)
412 {
413  Assert (false, ExcPureFunctionCalled());
414 }
415 
416 
417 
418 template <int dim>
421  const Flags &flags,
423  TimeStepBase (time),
424  tria(0, typeid(*this).name()),
425  coarse_grid (&coarse_grid, typeid(*this).name()),
426  flags (flags),
427  refinement_flags (refinement_flags)
428 {}
429 
430 
431 
432 template <int dim>
434 {
435  if (!flags.delete_and_rebuild_tria)
436  {
438  tria = 0;
439  delete t;
440  }
441  else
442  Assert (tria==0, ExcInternalError());
443 
444  coarse_grid = 0;
445 }
446 
447 
448 
449 template <int dim>
450 void
451 TimeStepBase_Tria<dim>::wake_up (const unsigned int wakeup_level)
452 {
453  TimeStepBase::wake_up (wakeup_level);
454 
455  if (wakeup_level == flags.wakeup_level_to_build_grid)
456  if (flags.delete_and_rebuild_tria || !tria)
457  restore_grid ();
458 }
459 
460 
461 
462 template <int dim>
463 void
464 TimeStepBase_Tria<dim>::sleep (const unsigned int sleep_level)
465 {
466  if (sleep_level == flags.sleep_level_to_delete_grid)
467  {
468  Assert (tria!=0, ExcInternalError());
469 
470  if (flags.delete_and_rebuild_tria)
471  {
473  tria = 0;
474  delete t;
475  }
476  }
477 
478  TimeStepBase::sleep (sleep_level);
479 }
480 
481 
482 
483 template <int dim>
485 {
486  // for any of the non-initial grids
487  // store the refinement flags
488  refine_flags.push_back (std::vector<bool>());
489  coarsen_flags.push_back (std::vector<bool>());
492 }
493 
494 
495 
496 template <int dim>
498 {
499  Assert (tria == 0, ExcGridNotDeleted());
500  Assert (refine_flags.size() == coarsen_flags.size(),
501  ExcInternalError());
502 
503  // create a virgin triangulation and
504  // set it to a copy of the coarse grid
505  tria = new Triangulation<dim> ();
506  tria->copy_triangulation (*coarse_grid);
507 
508  // for each of the previous refinement
509  // sweeps
510  for (unsigned int previous_sweep=0; previous_sweep<refine_flags.size();
511  ++previous_sweep)
512  {
513  // get flags
514  tria->load_refine_flags (refine_flags[previous_sweep]);
515  tria->load_coarsen_flags (coarsen_flags[previous_sweep]);
516 
517  // limit refinement depth if the user
518  // desired so
519 // if (flags.max_refinement_level != 0)
520 // {
521 // typename Triangulation<dim>::active_cell_iterator cell, endc;
522 // for (cell = tria->begin_active(),
523 // endc = tria->end();
524 // cell!=endc; ++cell)
525 // if (static_cast<unsigned int>(cell->level()) >=
526 // flags.max_refinement_level)
527 // cell->clear_refine_flag();
528 // };
529 
530  tria->execute_coarsening_and_refinement ();
531  };
532 }
533 
534 
535 
536 // have a few helper functions
537 namespace
538 {
539  template <int dim>
540  void
541  mirror_refinement_flags (const typename Triangulation<dim>::cell_iterator &new_cell,
542  const typename Triangulation<dim>::cell_iterator &old_cell)
543  {
544  // mirror the refinement
545  // flags from the present time level to
546  // the previous if the dual problem was
547  // used for the refinement, since the
548  // error is computed on a time-space cell
549  //
550  // we don't mirror the coarsening flags
551  // since we want stronger refinement. if
552  // this was the wrong decision, the error
553  // on the child cells of the previous
554  // time slab will indicate coarsening
555  // in the next iteration, so this is not
556  // so dangerous here.
557  //
558  // also, we only have to check whether
559  // the present cell flagged for
560  // refinement and the previous one is on
561  // the same level and also active. If it
562  // already has children, then there is
563  // no problem at all, if it is on a lower
564  // level than the present one, then it
565  // will be refined below anyway.
566  if (new_cell->active())
567  {
568  if (new_cell->refine_flag_set() && old_cell->active())
569  {
570  if (old_cell->coarsen_flag_set())
571  old_cell->clear_coarsen_flag();
572 
573  old_cell->set_refine_flag();
574  };
575 
576  return;
577  };
578 
579  if (old_cell->has_children() && new_cell->has_children())
580  {
581  Assert(old_cell->n_children()==new_cell->n_children(), ExcNotImplemented());
582  for (unsigned int c=0; c<new_cell->n_children(); ++c)
583  ::mirror_refinement_flags<dim> (new_cell->child(c), old_cell->child(c));
584  }
585  }
586 
587 
588 
589  template <int dim>
590  bool
591  adapt_grid_cells (const typename Triangulation<dim>::cell_iterator &cell1,
592  const typename Triangulation<dim>::cell_iterator &cell2)
593  {
594 
595  if (cell2->has_children() && cell1->has_children())
596  {
597  bool grids_changed = false;
598 
599  Assert(cell2->n_children()==cell1->n_children(), ExcNotImplemented());
600  for (unsigned int c=0; c<cell1->n_children(); ++c)
601  grids_changed |= ::adapt_grid_cells<dim> (cell1->child(c),
602  cell2->child(c));
603  return grids_changed;
604  };
605 
606 
607  if (!cell1->has_children() && !cell2->has_children())
608  // none of the two have children, so
609  // make sure that not one is flagged
610  // for refinement and the other for
611  // coarsening
612  {
613  if (cell1->refine_flag_set() && cell2->coarsen_flag_set())
614  {
615  cell2->clear_coarsen_flag();
616  return true;
617  }
618  else if (cell1->coarsen_flag_set() && cell2->refine_flag_set())
619  {
620  cell1->clear_coarsen_flag();
621  return true;
622  };
623 
624  return false;
625  };
626 
627 
628  if (cell1->has_children() && !cell2->has_children())
629  // cell1 has children, cell2 has not
630  // -> cell2 needs to be refined if any
631  // of cell1's children is flagged
632  // for refinement. None of them should
633  // be refined further, since then in the
634  // last round something must have gone
635  // wrong
636  //
637  // if cell2 was flagged for coarsening,
638  // we need to clear that flag in any
639  // case. The only exception would be
640  // if all children of cell1 were
641  // flagged for coarsening, but rules
642  // for coarsening are so complicated
643  // that we will not attempt to cover
644  // them. Rather accept one cell which
645  // is not coarsened...
646  {
647  bool changed_grid = false;
648  if (cell2->coarsen_flag_set())
649  {
650  cell2->clear_coarsen_flag();
651  changed_grid = true;
652  };
653 
654  if (!cell2->refine_flag_set())
655  for (unsigned int c=0; c<cell1->n_children(); ++c)
656  if (cell1->child(c)->refine_flag_set() ||
657  cell1->child(c)->has_children())
658  {
659  cell2->set_refine_flag();
660  changed_grid = true;
661  break;
662  };
663  return changed_grid;
664  };
665 
666  if (!cell1->has_children() && cell2->has_children())
667  // same thing, other way round...
668  {
669  bool changed_grid = false;
670  if (cell1->coarsen_flag_set())
671  {
672  cell1->clear_coarsen_flag();
673  changed_grid = true;
674  };
675 
676  if (!cell1->refine_flag_set())
677  for (unsigned int c=0; c<cell2->n_children(); ++c)
678  if (cell2->child(c)->refine_flag_set() ||
679  cell2->child(c)->has_children())
680  {
681  cell1->set_refine_flag();
682  changed_grid = true;
683  break;
684  };
685  return changed_grid;
686  };
687 
688  Assert (false, ExcInternalError());
689  return false;
690  }
691 
692 
693 
694  template <int dim>
695  bool
696  adapt_grids (Triangulation<dim> &tria1,
697  Triangulation<dim> &tria2)
698  {
699  bool grids_changed = false;
700 
701  typename Triangulation<dim>::cell_iterator cell1 = tria1.begin(),
702  cell2 = tria2.begin();
703  typename Triangulation<dim>::cell_iterator endc;
704  endc = (tria1.n_levels() == 1 ?
705  typename Triangulation<dim>::cell_iterator(tria1.end()) :
706  tria1.begin(1));
707  for (; cell1!=endc; ++cell1, ++cell2)
708  grids_changed |= ::adapt_grid_cells<dim> (cell1, cell2);
709 
710  return grids_changed;
711  }
712 }
713 
714 
715 template <int dim>
717 {
718  Vector<float> criteria;
719  get_tria_refinement_criteria (criteria);
720 
721  // copy the following two values since
722  // we may need modified values in the
723  // process of this function
724  double refinement_threshold = refinement_data.refinement_threshold,
725  coarsening_threshold = refinement_data.coarsening_threshold;
726 
727  // prepare an array where the criteria
728  // are stored in a sorted fashion
729  // we need this if cell number correction
730  // is switched on.
731  // the criteria are sorted in ascending
732  // order
733  // only fill it when needed
734  Vector<float> sorted_criteria;
735  // two pointers into this array denoting
736  // the position where the two thresholds
737  // are assumed
738  Vector<float>::const_iterator p_refinement_threshold=0,
739  p_coarsening_threshold=0;
740 
741 
742  // if we are to do some cell number
743  // correction steps, we have to find out
744  // which further cells (beyond
745  // refinement_threshold) to refine in case
746  // we need more cells, and which cells
747  // to not refine in case we need less cells
748  // (or even to coarsen, if necessary). to
749  // this end, we first define pointers into
750  // a sorted array of criteria pointing
751  // to the thresholds of refinement or
752  // coarsening; moving these pointers amounts
753  // to changing the threshold such that the
754  // number of cells flagged for refinement
755  // or coarsening would be changed by one
756  if ((timestep_no != 0) &&
757  (sweep_no>=refinement_flags.first_sweep_with_correction) &&
758  (refinement_flags.cell_number_correction_steps > 0))
759  {
760  sorted_criteria = criteria;
761  std::sort (sorted_criteria.begin(),
762  sorted_criteria.end());
763  p_refinement_threshold = Utilities::lower_bound (sorted_criteria.begin(),
764  sorted_criteria.end(),
765  static_cast<float>(refinement_threshold));
766  p_coarsening_threshold = std::upper_bound (sorted_criteria.begin(),
767  sorted_criteria.end(),
768  static_cast<float>(coarsening_threshold));
769  };
770 
771 
772  // actually flag cells the first time
773  GridRefinement::refine (*tria, criteria, refinement_threshold);
774  GridRefinement::coarsen (*tria, criteria, coarsening_threshold);
775 
776  // store this number for the following
777  // since its computation is rather
778  // expensive and since it doesn't change
779  const unsigned int n_active_cells = tria->n_active_cells ();
780 
781  // if not on first time level: try to
782  // adjust the number of resulting
783  // cells to those on the previous
784  // time level. Only do the cell number
785  // correction for higher sweeps and if
786  // there are sufficiently many cells
787  // already to avoid "grid stall" i.e.
788  // that the grid's evolution is hindered
789  // by the correction (this usually
790  // happens if there are very few cells,
791  // since then the number of cells touched
792  // by the correction step may exceed the
793  // number of cells which are flagged for
794  // refinement; in this case it often
795  // happens that the number of cells
796  // does not grow between sweeps, which
797  // clearly is not the wanted behaviour)
798  //
799  // however, if we do not do anything, we
800  // can get into trouble somewhen later.
801  // therefore, we also use the correction
802  // step for the first sweep or if the
803  // number of cells is between 100 and 300
804  // (unlike in the first version of the
805  // algorithm), but relax the conditions
806  // for the correction to allow deviations
807  // which are three times as high than
808  // allowed (sweep==1 || cell number<200)
809  // or twice as high (sweep==2 ||
810  // cell number<300). Also, since
811  // refinement never does any harm other
812  // than increased work, we allow for
813  // arbitrary growth of cell number if
814  // the estimated cell number is below
815  // 200.
816  //
817  // repeat this loop several times since
818  // the first estimate may not be totally
819  // correct
820  if ((timestep_no != 0) && (sweep_no>=refinement_flags.first_sweep_with_correction))
821  for (unsigned int loop=0;
822  loop<refinement_flags.cell_number_correction_steps; ++loop)
823  {
824  Triangulation<dim> *previous_tria
825  = dynamic_cast<const TimeStepBase_Tria<dim>*>(previous_timestep)->tria;
826 
827  // do one adaption step if desired
828  // (there are more coming below then
829  // also)
830  if (refinement_flags.adapt_grids)
831  ::adapt_grids<dim> (*previous_tria, *tria);
832 
833  // perform flagging of cells
834  // needed to regularize the
835  // triangulation
837  previous_tria->prepare_coarsening_and_refinement ();
838 
839 
840  // now count the number of elements
841  // which will result on the previous
842  // grid after it will be refined. The
843  // number which will really result
844  // should be approximately that that we
845  // compute here, since we already
846  // performed most of the prepare*
847  // steps for the previous grid
848  //
849  // use a double value since for each
850  // four cells (in 2D) that we flagged
851  // for coarsening we result in one
852  // new. but since we loop over flagged
853  // cells, we have to subtract 3/4 of
854  // a cell for each flagged cell
855  Assert(!tria->get_anisotropic_refinement_flag(), ExcNotImplemented());
856  Assert(!previous_tria->get_anisotropic_refinement_flag(), ExcNotImplemented());
857  double previous_cells = previous_tria->n_active_cells();
858  typename Triangulation<dim>::active_cell_iterator cell, endc;
859  cell = previous_tria->begin_active();
860  endc = previous_tria->end();
861  for (; cell!=endc; ++cell)
862  if (cell->refine_flag_set())
863  previous_cells += (GeometryInfo<dim>::max_children_per_cell-1);
864  else if (cell->coarsen_flag_set())
865  previous_cells -= (GeometryInfo<dim>::max_children_per_cell-1) /
867 
868  // @p{previous_cells} now gives the
869  // number of cells which would result
870  // from the flags on the previous grid
871  // if we refined it now. However, some
872  // more flags will be set when we adapt
873  // the previous grid with this one
874  // after the flags have been set for
875  // this time level; on the other hand,
876  // we don't account for this, since the
877  // number of cells on this time level
878  // will be changed afterwards by the
879  // same way, when it is adapted to the
880  // next time level
881 
882  // now estimate the number of cells which
883  // will result on this level
884  double estimated_cells = n_active_cells;
885  cell = tria->begin_active();
886  endc = tria->end();
887  for (; cell!=endc; ++cell)
888  if (cell->refine_flag_set())
889  estimated_cells += (GeometryInfo<dim>::max_children_per_cell-1);
890  else if (cell->coarsen_flag_set())
891  estimated_cells -= (GeometryInfo<dim>::max_children_per_cell-1) /
893 
894  // calculate the allowed delta in
895  // cell numbers; be more lenient
896  // if there are few cells
897  double delta_up = refinement_flags.cell_number_corridor_top,
898  delta_down = refinement_flags.cell_number_corridor_bottom;
899 
900  const std::vector<std::pair<unsigned int,double> > &relaxations
901  = (sweep_no >= refinement_flags.correction_relaxations.size() ?
902  refinement_flags.correction_relaxations.back() :
903  refinement_flags.correction_relaxations[sweep_no]);
904  for (unsigned int r=0; r!=relaxations.size(); ++r)
905  if (n_active_cells < relaxations[r].first)
906  {
907  delta_up *= relaxations[r].second;
908  delta_down *= relaxations[r].second;
909  break;
910  };
911 
912  // now, if the number of estimated
913  // cells exceeds the number of cells
914  // on the old time level by more than
915  // delta: cut the top threshold
916  //
917  // note that for each cell that
918  // we unflag we have to diminish the
919  // estimated number of cells by
920  // @p{children_per_cell}.
921  if (estimated_cells > previous_cells*(1.+delta_up))
922  {
923  // only limit the cell number
924  // if there will not be less
925  // than some number of cells
926  //
927  // also note that when using the
928  // dual estimator, the initial
929  // time level is not refined
930  // on its own, so we may not
931  // limit the number of the second
932  // time level on the basis of
933  // the initial one; since for
934  // the dual estimator, we
935  // mirror the refinement
936  // flags, the initial level
937  // will be passively refined
938  // later on.
939  if (estimated_cells>refinement_flags.min_cells_for_correction)
940  {
941  // number of cells by which the
942  // new grid is to be diminished
943  double delta_cells = estimated_cells -
944  previous_cells*(1.+delta_up);
945 
946  // if we need to reduce the
947  // number of cells, we need
948  // to raise the thresholds,
949  // i.e. move ahead in the
950  // sorted array, since this
951  // is sorted in ascending
952  // order. do so by removing
953  // cells tagged for refinement
954 
955  for (unsigned int i=0; i<delta_cells;
957  if (p_refinement_threshold != sorted_criteria.end())
958  ++p_refinement_threshold;
959  else
960  break;
961  }
962  else
963  // too many cells, but we
964  // won't do anything about
965  // that
966  break;
967  }
968  else
969  // likewise: if the estimated number
970  // of cells is less than 90 per cent
971  // of those at the previous time level:
972  // raise threshold by refining
973  // additional cells. if we start to
974  // run into the area of cells
975  // which are to be coarsened, we
976  // raise the limit for these too
977  if (estimated_cells < previous_cells*(1.-delta_down))
978  {
979  // number of cells by which the
980  // new grid is to be enlarged
981  double delta_cells = previous_cells*(1.-delta_down)-estimated_cells;
982  // heuristics: usually, if we
983  // add @p{delta_cells} to the
984  // present state, we end up
985  // with much more than only
986  // (1-delta_down)*prev_cells
987  // because of the effect of
988  // regularization and because
989  // of adaption to the
990  // following grid. Therefore,
991  // if we are not in the last
992  // correction loop, we try not
993  // to add as many cells as seem
994  // necessary at first and hope
995  // to get closer to the limit
996  // this way. Only in the last
997  // loop do we have to take the
998  // full number to guarantee the
999  // wanted result.
1000  //
1001  // The value 0.9 is taken from
1002  // practice, as the additional
1003  // number of cells introduced
1004  // by regularization is
1005  // approximately 10 per cent
1006  // of the flagged cells.
1007  if (loop != refinement_flags.cell_number_correction_steps-1)
1008  delta_cells *= 0.9;
1009 
1010  // if more cells need to be
1011  // refined, we need to lower
1012  // the thresholds, i.e. to
1013  // move to the beginning
1014  // of sorted_criteria, which is
1015  // sorted in ascending order
1016  for (unsigned int i=0; i<delta_cells;
1018  if (p_refinement_threshold != p_coarsening_threshold)
1019  --refinement_threshold;
1020  else if (p_coarsening_threshold != sorted_criteria.begin())
1021  --p_coarsening_threshold, --p_refinement_threshold;
1022  else
1023  break;
1024  }
1025  else
1026  // estimated cell number is ok,
1027  // stop correction steps
1028  break;
1029 
1030  if (p_refinement_threshold == sorted_criteria.end())
1031  {
1032  Assert (p_coarsening_threshold != p_refinement_threshold,
1033  ExcInternalError());
1034  --p_refinement_threshold;
1035  };
1036 
1037  coarsening_threshold = *p_coarsening_threshold;
1038  refinement_threshold = *p_refinement_threshold;
1039 
1040  if (coarsening_threshold>=refinement_threshold)
1041  coarsening_threshold = 0.999*refinement_threshold;
1042 
1043  // now that we have re-adjusted
1044  // thresholds: clear all refine and
1045  // coarsening flags and do it all
1046  // over again
1047  cell = tria->begin_active();
1048  endc = tria->end();
1049  for (; cell!=endc; ++cell)
1050  {
1051  cell->clear_refine_flag ();
1052  cell->clear_coarsen_flag ();
1053  };
1054 
1055 
1056  // flag cells finally
1057  GridRefinement::refine (*tria, criteria, refinement_threshold);
1058  GridRefinement::coarsen (*tria, criteria, coarsening_threshold);
1059  };
1060 
1061  // if step number is greater than
1062  // one: adapt this and the previous
1063  // grid to each other. Don't do so
1064  // for the initial grid because
1065  // it is always taken to be the first
1066  // grid and needs therefore no
1067  // treatment of its own.
1068  if ((timestep_no >= 1) && (refinement_flags.adapt_grids))
1069  {
1070  Triangulation<dim> *previous_tria
1071  = dynamic_cast<const TimeStepBase_Tria<dim>*>(previous_timestep)->tria;
1072 
1073 
1074  // if we used the dual estimator, we
1075  // computed the error information on
1076  // a time slab, rather than on a level
1077  // of its own. we then mirror the
1078  // refinement flags we determined for
1079  // the present level to the previous
1080  // one
1081  //
1082  // do this mirroring only, if cell number
1083  // adjustment is on, since otherwise
1084  // strange things may happen
1085  if (refinement_flags.mirror_flags_to_previous_grid)
1086  {
1087  ::adapt_grids<dim> (*previous_tria, *tria);
1088 
1089  typename Triangulation<dim>::cell_iterator old_cell, new_cell, endc;
1090  old_cell = previous_tria->begin(0);
1091  new_cell = tria->begin(0);
1092  endc = tria->end(0);
1093  for (; new_cell!=endc; ++new_cell, ++old_cell)
1094  ::mirror_refinement_flags<dim> (new_cell, old_cell);
1095  };
1096 
1098  previous_tria->prepare_coarsening_and_refinement ();
1099 
1100  // adapt present and previous grids
1101  // to each other: flag additional
1102  // cells to avoid the previous grid
1103  // to have cells refined twice more
1104  // than the present one and vica versa.
1105  ::adapt_grids<dim> (*previous_tria, *tria);
1106  };
1107 }
1108 
1109 
1110 
1111 template <int dim>
1113 {
1114  next_action = grid_refinement;
1115 }
1116 
1117 
1118 
1119 template <int dim>
1120 std::size_t
1122 {
1124  sizeof(tria) +
1126  sizeof(flags) + sizeof(refinement_flags) +
1129 }
1130 
1131 
1132 
1133 template <int dim>
1135  :
1136  delete_and_rebuild_tria (false),
1137  wakeup_level_to_build_grid (0),
1138  sleep_level_to_delete_grid (0)
1139 {
1140  Assert (false, ExcInternalError());
1141 }
1142 
1143 
1144 
1145 template <int dim>
1147  const unsigned int wakeup_level_to_build_grid,
1148  const unsigned int sleep_level_to_delete_grid):
1149  delete_and_rebuild_tria (delete_and_rebuild_tria),
1150  wakeup_level_to_build_grid (wakeup_level_to_build_grid),
1151  sleep_level_to_delete_grid (sleep_level_to_delete_grid)
1152 {
1153 // Assert (!delete_and_rebuild_tria || (wakeup_level_to_build_grid>=1),
1154 // ExcInvalidParameter(wakeup_level_to_build_grid));
1155 // Assert (!delete_and_rebuild_tria || (sleep_level_to_delete_grid>=1),
1156 // ExcInvalidParameter(sleep_level_to_delete_grid));
1157 }
1158 
1159 
1160 template <int dim>
1163 (1, // one element, denoting the first and all subsequent sweeps
1164  std::vector<std::pair<unsigned int,double> >(1, // one element, denoting the upper bound
1165  // for the following
1166  // relaxation
1167  std::make_pair (0U, 0.)));
1168 
1169 
1170 template <int dim>
1172 RefinementFlags (const unsigned int max_refinement_level,
1173  const unsigned int first_sweep_with_correction,
1174  const unsigned int min_cells_for_correction,
1175  const double cell_number_corridor_top,
1176  const double cell_number_corridor_bottom,
1177  const CorrectionRelaxations &correction_relaxations,
1178  const unsigned int cell_number_correction_steps,
1179  const bool mirror_flags_to_previous_grid,
1180  const bool adapt_grids) :
1181  max_refinement_level(max_refinement_level),
1182  first_sweep_with_correction (first_sweep_with_correction),
1183  min_cells_for_correction(min_cells_for_correction),
1184  cell_number_corridor_top(cell_number_corridor_top),
1185  cell_number_corridor_bottom(cell_number_corridor_bottom),
1186  correction_relaxations (correction_relaxations.size() != 0 ?
1187  correction_relaxations :
1188  default_correction_relaxations),
1189  cell_number_correction_steps(cell_number_correction_steps),
1190  mirror_flags_to_previous_grid(mirror_flags_to_previous_grid),
1191  adapt_grids(adapt_grids)
1192 {
1193  Assert (cell_number_corridor_top>=0, ExcInvalidValue (cell_number_corridor_top));
1194  Assert (cell_number_corridor_bottom>=0, ExcInvalidValue (cell_number_corridor_bottom));
1195  Assert (cell_number_corridor_bottom<=1, ExcInvalidValue (cell_number_corridor_bottom));
1196 }
1197 
1198 
1199 template <int dim>
1201 RefinementData (const double _refinement_threshold,
1202  const double _coarsening_threshold) :
1203  refinement_threshold(_refinement_threshold),
1204  // in some rare cases it may happen that
1205  // both thresholds are the same (e.g. if
1206  // there are many cells with the same
1207  // error indicator). That would mean that
1208  // all cells will be flagged for
1209  // refinement or coarsening, but some will
1210  // be flagged for both, namely those for
1211  // which the indicator equals the
1212  // thresholds. This is forbidden, however.
1213  //
1214  // In some rare cases with very few cells
1215  // we also could get integer round off
1216  // errors and get problems with
1217  // the top and bottom fractions.
1218  //
1219  // In these case we arbitrarily reduce the
1220  // bottom threshold by one permille below
1221  // the top threshold
1222  coarsening_threshold((_coarsening_threshold == _refinement_threshold ?
1223  _coarsening_threshold :
1224  0.999*_coarsening_threshold))
1225 {
1226  Assert (refinement_threshold >= 0, ExcInvalidValue(refinement_threshold));
1227  Assert (coarsening_threshold >= 0, ExcInvalidValue(coarsening_threshold));
1228  // allow both thresholds to be zero,
1229  // since this is needed in case all indicators
1230  // are zero
1232  ((coarsening_threshold == 0) && (refinement_threshold == 0)),
1233  ExcInvalidValue (coarsening_threshold));
1234 }
1235 
1236 
1237 
1238 /*-------------- Explicit Instantiations -------------------------------*/
1239 #include "time_dependent.inst"
1240 
1241 
1242 DEAL_II_NAMESPACE_CLOSE
void set_sweep_no(const unsigned int sweep_no)
virtual std::size_t memory_consumption() const
virtual void solve_primal_problem()=0
Iterator lower_bound(Iterator first, Iterator last, const T &val)
Definition: utilities.h:604
virtual void sleep(const unsigned int)
virtual void start_sweep()
unsigned int n_active_cells() const
Definition: tria.cc:10973
void refine_grid(const RefinementData data)
unsigned int next_action
TimeDependent(const TimeSteppingData &data_primal, const TimeSteppingData &data_dual, const TimeSteppingData &data_postprocess)
virtual void solve_dual_problem()
void set_timestep_no(const unsigned int step_no)
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
::ExceptionBase & ExcMessage(std::string arg1)
double get_forward_timestep() const
void set_next_timestep(const TimeStepBase *next)
virtual ~TimeStepBase()
virtual void copy_triangulation(const Triangulation< dim, spacedim > &old_tria)
Definition: tria.cc:9043
double get_time() const
const TimeStepBase * previous_timestep
active_cell_iterator begin_active(const unsigned int level=0) const
Definition: tria.cc:10397
const TimeSteppingData timestepping_data_dual
iterator end()
cell_iterator begin(const unsigned int level=0) const
Definition: tria.cc:10377
void apply_to_subranges(const RangeType &begin, const typename identity< RangeType >::type &end, const Function &f, const unsigned int grainsize)
Definition: parallel.h:417
unsigned int n_levels() const
void set_previous_timestep(const TimeStepBase *previous)
cell_iterator end() const
Definition: tria.cc:10465
unsigned int timestep_no
unsigned int get_timestep_no() const
void do_loop(InitFunctionObject init_function, LoopFunctionObject loop_function, const TimeSteppingData &timestepping_data, const Direction direction)
const RefinementFlags refinement_flags
virtual bool prepare_coarsening_and_refinement()
Definition: tria.cc:12269
const std::vector< std::vector< std::pair< unsigned int, double > > > correction_relaxations
TriaIterator< CellAccessor< dim, spacedim > > cell_iterator
Definition: tria.h:1392
SmartPointer< const Triangulation< dim, dim >, TimeStepBase_Tria< dim > > coarse_grid
std::size_t memory_consumption() const
virtual void init_for_refinement()
RefinementData(const double refinement_threshold, const double coarsening_threshold=0)
#define Assert(cond, exc)
Definition: exceptions.h:294
const double time
bool get_anisotropic_refinement_flag() const
Definition: tria.cc:9475
virtual void get_tria_refinement_criteria(Vector< float > &criteria) const =0
virtual ~TimeDependent()
const TimeSteppingData timestepping_data_primal
void loop(ITERATOR begin, typename identity< ITERATOR >::type end, DOFINFO &dinfo, INFOBOX &info, const std_cxx11::function< void(DOFINFO &, typename INFOBOX::CellInfo &)> &cell_worker, const std_cxx11::function< void(DOFINFO &, typename INFOBOX::CellInfo &)> &boundary_worker, const std_cxx11::function< void(DOFINFO &, DOFINFO &, typename INFOBOX::CellInfo &, typename INFOBOX::CellInfo &)> &face_worker, ASSEMBLER &assembler, const LoopControl &lctrl=LoopControl())
Definition: loop.h:370
virtual void start_sweep(const unsigned int sweep_no)
void save_coarsen_flags(std::ostream &out) const
Definition: tria.cc:9435
void save_refine_flags(std::ostream &out) const
Definition: tria.cc:9370
virtual void init_for_postprocessing()
virtual ~TimeStepBase_Tria()
static CorrectionRelaxations default_correction_relaxations
void coarsen(Triangulation< dim, spacedim > &tria, const VectorType &criteria, const double threshold)
iterator begin()
double get_backward_timestep() const
const unsigned int sleep_level_to_delete_grid
void delete_timestep(const unsigned int position)
virtual std::size_t memory_consumption() const
std_cxx11::enable_if< std_cxx11::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
virtual void wake_up(const unsigned int)
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)
virtual void sleep(const unsigned int)
std::vector< SmartPointer< TimeStepBase, TimeDependent > > timesteps
virtual void init_for_dual_problem()
virtual void init_for_primal_problem()
unsigned int sweep_no
void insert_timestep(const TimeStepBase *position, TimeStepBase *new_timestep)
std::vector< std::vector< bool > > refine_flags
virtual void end_sweep()
std::vector< std::vector< bool > > coarsen_flags
virtual void postprocess_timestep()
void refine(Triangulation< dim, spacedim > &tria, const VectorType &criteria, const double threshold, const unsigned int max_to_mark=numbers::invalid_unsigned_int)
std::vector< std::vector< std::pair< unsigned int, double > > > CorrectionRelaxations
virtual void end_sweep()
unsigned int sweep_no
virtual void wake_up(const unsigned int wakeup_level)
TimeStepBase(const double time)
TimeSteppingData(const unsigned int look_ahead, const unsigned int look_back)
SmartPointer< Triangulation< dim, dim >, TimeStepBase_Tria< dim > > tria