LCOV - code coverage report
Current view: top level - ugbase/lib_disc/time_disc - time_integrator_subject.hpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 47 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 270 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2010-2020:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Tim Schön
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #ifndef __H__UG__LIB_DISC__TIME_DISC__TIME_INTEGRATOR_SUBJECT
      34              : #define __H__UG__LIB_DISC__TIME_DISC__TIME_INTEGRATOR_SUBJECT
      35              : 
      36              : #include "./time_integrator_observers/time_integrator_observer_interface.h"
      37              : 
      38              : namespace ug {
      39              : 
      40              : /// Base class for a subject notifying observers attachment.
      41              : /** Provides the option to perform pre-/postprocessing for a (tentative step for evolving from t -> t+dt). Seven cases are distinguished
      42              :  *  1) INIT (STEP)                : Called at t=t_i before time step is executed. Contains solution u0=u(t0).
      43              :  *  2) FINALIZE (STEP)    : Called at t=t_i+dt, after time step has been executed and can be accepted. Provides solution u = u(t+dt).
      44              :  *  3) REWIND (STEP)      : Called at t=t_i+dt, after time step has been executed, but must be rejected. Provides (rejected) solution u = u(t+dt).
      45              :  *  4) PREPROCESS (STEP)  : Called at t=t_i before newton solver is executed (if applicable). Contains solution u0=u(t0). This may happen multiple times per time step.
      46              :  *  5) POSTPROCESS (STEP) : Called at t=t_i+dt, after newton solver has been executed (if applicable). Provides solution u = u(t+dt). This may happen multiple times per time step.
      47              :  *  6) START                      : Called at t=t_0, at the beginning of the time integration process (start of the simulation)
      48              :  *  7) END                        : Called at t=T, at the end of the time integration process (end of the simulation)
      49              :  */
      50              : template<class TDomain, class TAlgebra>
      51              : class TimeIntegratorSubject
      52              : {
      53              : public:
      54              :         typedef GridFunction<TDomain, TAlgebra> grid_function_type;
      55              :         typedef ITimeIntegratorObserver<TDomain, TAlgebra> process_observer_type;
      56              :         typedef ITimeIntegratorStageObserver_init<TDomain, TAlgebra> init_observer_type;
      57              :         typedef ITimeIntegratorStageObserver_rewind<TDomain, TAlgebra> rewind_observer_type;
      58              :         typedef ITimeIntegratorStageObserver_finalize<TDomain, TAlgebra> finalize_observer_type;
      59              :         typedef ITimeIntegratorStageObserver_preprocess<TDomain, TAlgebra> preprocess_observer_type;
      60              :         typedef ITimeIntegratorStageObserver_postprocess<TDomain, TAlgebra> postprocess_observer_type;
      61              :         typedef ITimeIntegratorStageObserver_start<TDomain, TAlgebra> start_observer_type;
      62              :         typedef ITimeIntegratorStageObserver_end<TDomain, TAlgebra> end_observer_type;
      63              :         typedef typename std::vector<SmartPtr<process_observer_type> > process_observer_container_type;
      64              : 
      65              :         enum observer_group_type {
      66              :                 TIO_GROUP_INIT_STEP=0, 
      67              :                 TIO_GROUP_REWIND_STEP, 
      68              :                 TIO_GROUP_FINALIZE_STEP, 
      69              :                 TIO_GROUP_PREPROCESS_STEP, 
      70              :                 TIO_GROUP_POSTPROCESS_STEP, 
      71              :                 TIO_GROUP_START, 
      72              :                 TIO_GROUP_END, 
      73              :                 TIO_GROUP_SIZE};
      74              : 
      75              : protected:
      76              :         // process_observer_container_type m_vProcessObservers;
      77              :         process_observer_container_type m_vProcessObservers[TIO_GROUP_SIZE];
      78              : 
      79              :         // container for statically mapped observers
      80              :         std::vector<SmartPtr<init_observer_type> > m_vInitObservers;
      81              :         std::vector<SmartPtr<rewind_observer_type> > m_vRewindObservers;
      82              :         std::vector<SmartPtr<finalize_observer_type> > m_vFinalizeObservers;
      83              :         std::vector<SmartPtr<preprocess_observer_type> > m_vPreprocessObservers;
      84              :         std::vector<SmartPtr<postprocess_observer_type> > m_vPostprocessObservers;
      85              :         std::vector<SmartPtr<start_observer_type> > m_vStartObservers;
      86              :         std::vector<SmartPtr<end_observer_type> > m_vEndObservers;
      87              : 
      88              : 
      89              : protected:
      90              :         //! register observer (default: postprocess)
      91              :         template<int tGroup>
      92              :         void attach_to_group(SmartPtr<process_observer_type> obs)
      93              :         {
      94              :                 //UG_LOG("TimeIntegratorSubject::attach_observer[" << tGroup <<"]" << this << std::endl);
      95            0 :                 m_vProcessObservers[tGroup].push_back(obs);
      96            0 :         }
      97              : 
      98              :         //! register observer (default: postprocess)
      99              :         void attach_to_group(int tGroup, SmartPtr<process_observer_type> obs)
     100              :         {
     101              :                 //UG_LOG("TimeIntegratorSubject::attach_observer[" << tGroup <<"]" << this << std::endl);
     102              :                 m_vProcessObservers[tGroup].push_back(obs);
     103              :         }
     104              : public:
     105              : 
     106              : #define DECLARE_CHECK_STATIC_ATTACH(stage, container) \
     107              :         bool check_attach_##stage(SmartPtr<process_observer_type> obs)\
     108              :         {\
     109              :                 SmartPtr<stage##_observer_type> sp_staticObs = obs.template cast_dynamic<stage##_observer_type>();\
     110              :                 if (sp_staticObs.valid())\
     111              :                 {\
     112              :                         (container).push_back(sp_staticObs);\
     113              :                         return true;\
     114              :                 }\
     115              :                 return false;\
     116              :         }
     117              : 
     118            0 :         DECLARE_CHECK_STATIC_ATTACH(init, m_vInitObservers)
     119            0 :         DECLARE_CHECK_STATIC_ATTACH(rewind, m_vRewindObservers)
     120            0 :         DECLARE_CHECK_STATIC_ATTACH(finalize, m_vFinalizeObservers)
     121            0 :         DECLARE_CHECK_STATIC_ATTACH(preprocess, m_vPreprocessObservers)
     122            0 :         DECLARE_CHECK_STATIC_ATTACH(postprocess, m_vPostprocessObservers)
     123            0 :         DECLARE_CHECK_STATIC_ATTACH(start, m_vStartObservers)
     124            0 :         DECLARE_CHECK_STATIC_ATTACH(end, m_vEndObservers)
     125              : 
     126              :         //! Attach statically mapped observers to their respective stages.
     127              :         //! Other observers are mapped to the finalize stage.
     128            0 :         void attach_observer(SmartPtr<process_observer_type> obs)
     129              :         {
     130              :                 const bool isStaticallyAttached =
     131            0 :                         check_attach_init(obs) ||
     132            0 :                         check_attach_rewind(obs) ||
     133            0 :                         check_attach_finalize(obs) ||
     134            0 :                         check_attach_preprocess(obs) ||
     135            0 :                         check_attach_postprocess(obs) ||
     136            0 :                         check_attach_start(obs) ||
     137            0 :                         check_attach_end(obs);
     138              : 
     139            0 :                 if (!isStaticallyAttached)
     140            0 :                         attach_finalize_observer(obs);
     141            0 :         }
     142              : 
     143            0 :         void attach_init_observer(SmartPtr<process_observer_type> obs)
     144            0 :         { attach_to_group<TIO_GROUP_INIT_STEP>(obs); }
     145              : 
     146            0 :         void attach_rewind_observer(SmartPtr<process_observer_type> obs)
     147            0 :         { attach_to_group<TIO_GROUP_REWIND_STEP>(obs); }
     148              : 
     149            0 :         void attach_finalize_observer(SmartPtr<process_observer_type> obs)
     150            0 :         { attach_to_group<TIO_GROUP_FINALIZE_STEP>(obs); }
     151              : 
     152            0 :         void attach_preprocess_observer(SmartPtr<process_observer_type> obs)
     153            0 :         { attach_to_group<TIO_GROUP_PREPROCESS_STEP>(obs); }
     154              : 
     155            0 :         void attach_postprocess_observer(SmartPtr<process_observer_type> obs)
     156            0 :         { attach_to_group<TIO_GROUP_POSTPROCESS_STEP>(obs); }
     157              : 
     158            0 :         void attach_start_observer(SmartPtr<process_observer_type> obs)
     159            0 :         { attach_to_group<TIO_GROUP_START>(obs); }
     160              : 
     161            0 :         void attach_end_observer(SmartPtr<process_observer_type> obs)
     162            0 :         { attach_to_group<TIO_GROUP_END>(obs); }
     163              : 
     164            0 :         void reset_observers()
     165              :         {
     166              :                 m_vProcessObservers[TIO_GROUP_INIT_STEP].clear();
     167              :                 m_vProcessObservers[TIO_GROUP_REWIND_STEP].clear();
     168              :                 m_vProcessObservers[TIO_GROUP_FINALIZE_STEP].clear();
     169              :                 m_vProcessObservers[TIO_GROUP_PREPROCESS_STEP].clear();
     170              :                 m_vProcessObservers[TIO_GROUP_POSTPROCESS_STEP].clear();
     171              :                 m_vProcessObservers[TIO_GROUP_START].clear();
     172              :                 m_vProcessObservers[TIO_GROUP_END].clear();
     173              : 
     174              :                 m_vInitObservers.clear();
     175              :                 m_vRewindObservers.clear();
     176              :                 m_vFinalizeObservers.clear();
     177              :                 m_vPreprocessObservers.clear();
     178              :                 m_vPostprocessObservers.clear();
     179              :                 m_vStartObservers.clear();
     180              :                 m_vEndObservers.clear();
     181            0 :         }
     182              : 
     183              : protected:
     184              :         /// Notify all observers for a certain group.
     185              :         template<int tGroup>
     186            0 :         bool notify_group(SmartPtr<grid_function_type> u, int step, number time, number dt)
     187              :         {
     188              :                 process_observer_container_type &observers = m_vProcessObservers[tGroup];
     189              :                 
     190              :                 bool result = true;
     191            0 :                 for (typename process_observer_container_type::iterator it = observers.begin(); it!= observers.end(); ++it)
     192              :                 {
     193            0 :                         result = (*it)->step_process(u, step, time, dt) && result;                                                   
     194              :                 }
     195              : 
     196            0 :                 return result;
     197              :         }
     198              : 
     199              : 
     200              : public:
     201              : 
     202              : #define DECLARE_NOTIFY_STEP(functionName, stageName, stageID, container) \
     203              :         bool notify_##functionName(SmartPtr<grid_function_type> u, int step, number time, number dt)\
     204              :         {\
     205              :                 bool res = notify_group<(stageID)>(u, step, time, dt);\
     206              :                 const size_t numObs = (container).size();\
     207              :                 for (size_t o = 0; o < numObs; ++o)\
     208              :                         res &= (container)[o]->stageName##_action(u, step, time, dt);\
     209              :                 return res;\
     210              :         }
     211              : 
     212              :         /// notify all observers that time step evolution starts
     213            0 :         DECLARE_NOTIFY_STEP(init_step, init, TIO_GROUP_INIT_STEP, m_vInitObservers)
     214              : 
     215              :         /// Notify all observers that time step must be rewinded.
     216            0 :         DECLARE_NOTIFY_STEP(rewind_step, rewind, TIO_GROUP_REWIND_STEP, m_vRewindObservers)
     217              : 
     218              :         /// notify all observers that time step has been evolved (successfully)
     219            0 :         DECLARE_NOTIFY_STEP(finalize_step, finalize, TIO_GROUP_FINALIZE_STEP, m_vFinalizeObservers)
     220              : 
     221              :         /// notify all observers that newton solver is about to start (may happen multiple times per time step)
     222            0 :         DECLARE_NOTIFY_STEP(preprocess_step, preprocess, TIO_GROUP_PREPROCESS_STEP, m_vPreprocessObservers)
     223              : 
     224              :         /// notify all observers that newton solver has finished (may happen multiple times per time step)
     225            0 :         DECLARE_NOTIFY_STEP(postprocess_step, postprocess, TIO_GROUP_POSTPROCESS_STEP, m_vPostprocessObservers)
     226              : 
     227              :         /// notify all observers that the simulation has started
     228            0 :         DECLARE_NOTIFY_STEP(start, start, TIO_GROUP_START, m_vStartObservers)
     229              : 
     230              :         /// notify all observers that the simulation has ended
     231            0 :         DECLARE_NOTIFY_STEP(end, end, TIO_GROUP_END, m_vEndObservers)
     232              : };
     233              : 
     234              : }
     235              : 
     236              : #endif
        

Generated by: LCOV version 2.0-1