LCOV - code coverage report
Current view: top level - /builds/ug4-project/ugcore/ug4-new/plugins/Limex/time_disc - time_integrator.hpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 75 0
Test Date: 2026-06-01 23:54:59 Functions: 0.0 % 237 0

            Line data    Source code
       1              : /*
       2              :  * SPDX-FileCopyrightText: Copyright (c) 2014:  G-CSC, Goethe University Frankfurt
       3              :  * SPDX-License-Identifier: LicenseRef-UG4-LGPL-3.0
       4              :  *
       5              :  * Author: Arne Naegel, Andreas Kreienbuehl
       6              :  *
       7              :  * This file is part of UG4.
       8              :  *
       9              :  * UG4 is free software: you can redistribute it and/or modify it under the
      10              :  * terms of the GNU Lesser General Public License version 3 (as published by the
      11              :  * Free Software Foundation) with the following additional attribution
      12              :  * requirements (according to LGPL/GPL v3 §7):
      13              :  *
      14              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      15              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      16              :  *
      17              :  * (2) The following notice must be displayed at a prominent place in the
      18              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      19              :  *
      20              :  * (3) The following bibliography is recommended for citation and must be
      21              :  * preserved in all covered files:
      22              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      23              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      24              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      25              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      26              :  *   flexible software system for simulating pde based models on high performance
      27              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      28              :  *
      29              :  * This program is distributed in the hope that it will be useful,
      30              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      31              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      32              :  * GNU Lesser General Public License for more details.
      33              :  */
      34              : 
      35              : #ifndef __H__LIMEX__TIME_INTEGRATOR_HPP__
      36              : #define __H__LIMEX__TIME_INTEGRATOR_HPP__
      37              : 
      38              : #if __cplusplus >= 201103L
      39              : #define OVERRIDE override
      40              : #else
      41              : #define OVERRIDE
      42              : #endif
      43              : 
      44              : // std headers.
      45              : #include <string>
      46              : 
      47              : // UG4 headers
      48              : #include "lib_algebra/operator/interface/operator.h"
      49              : #include "lib_algebra/operator/interface/operator_inverse.h"
      50              : #include "lib_algebra/operator/linear_solver/linear_solver.h"
      51              : #include "lib_disc/function_spaces/grid_function.h"
      52              : #include "lib_disc/assemble_interface.h" // TODO: missing IAssemble in following file:
      53              : #include "lib_disc/operator/linear_operator/assembled_linear_operator.h"
      54              : #include "lib_disc/operator/non_linear_operator/assembled_non_linear_operator.h"
      55              : #include "lib_disc/spatial_disc/domain_disc.h"
      56              : #include "lib_disc/time_disc/time_disc_interface.h"
      57              : #include "lib_disc/time_disc/theta_time_step.h"
      58              : #include "lib_disc/time_disc/solution_time_series.h"
      59              : #include "lib_disc/time_disc/time_integrator_subject.hpp"
      60              : #include "lib_disc/time_disc/time_integrator_observers/time_integrator_observer_interface.h"
      61              : #include "lib_disc/function_spaces/grid_function_util.h" // SaveVectorForConnectionViewer
      62              : #include "lib_disc/function_spaces/interpolate.h" //Interpolate
      63              : #include "lib_disc/function_spaces/integrate.h" //Integral
      64              : #include "lib_disc/function_spaces/grid_function.h" //GridFunction
      65              : 
      66              : 
      67              : // Plugin headers
      68              : #include "time_extrapolation.h"
      69              : #include "../limex_tools.h"
      70              : 
      71              : namespace ug {
      72              : 
      73              : /// Integrates over a given time interval [a,b] with step size dt
      74              : template<class TDomain, class TAlgebra>
      75              : class ITimeIntegrator
      76              :                 :       public IOperator< GridFunction<TDomain, TAlgebra> >,
      77              :                         public TimeIntegratorSubject<TDomain, TAlgebra>
      78              : {
      79              :         public:
      80              : 
      81              :                 typedef TAlgebra algebra_type;
      82              :                 typedef typename TAlgebra::vector_type vector_type;
      83              :                 typedef typename TAlgebra::matrix_type matrix_type;
      84              : 
      85              : 
      86              :                 typedef TDomain domain_type;
      87              :                 typedef GridFunction<TDomain, TAlgebra> grid_function_type;
      88              : 
      89              :         protected:
      90              :                 double m_dt;
      91              :                 double m_lower_tim;
      92              :                 double m_upper_tim;
      93              : 
      94              :                 double m_precisionBound;
      95              : 
      96              :                 bool m_bNoLogOut;
      97              : 
      98              : 
      99              :         public:
     100              :                 // constructor
     101            0 :                 ITimeIntegrator()
     102            0 :                 : m_dt(1.0), m_lower_tim(0.0), m_upper_tim(0.0), m_precisionBound(1e-10), m_bNoLogOut(false)
     103              :                  {}
     104              : 
     105              :                 /// virtual     destructor
     106            0 :                 virtual ~ITimeIntegrator() {};
     107              : 
     108              :         ///     init operator depending on a function u
     109              :         /**
     110              :          * This method initializes the operator. Once initialized the 'apply'-method
     111              :          * can be called. The function u is passed here, since the linear operator
     112              :          * may be the linearization of some non-linear operator. Thus, the operator
     113              :          * depends on the linearization point.
     114              :          * If the operator is not a linearization, this method can be implemented
     115              :          * by simply calling init() and forgetting about the linearization point.
     116              :          *
     117              :          * \param[in]   u               function (linearization point)
     118              :          * \returns     bool    success flag
     119              :          */
     120            0 :          virtual void init(grid_function_type const& u)
     121              :          {
     122              :          //     UG_ASSERT(m_spDomainDisc.valid(), "TimeIntegrator<TDomain, TAlgebra>::init: m_spDomainDisc invalid.");
     123              :          //     m_spTimeDisc = make_sp(new time_disc_type(m_spDomainDisc, m_theta));
     124            0 :          }
     125              : 
     126              : 
     127              :         ///     init operator
     128              :         /**
     129              :          * This method initializes the operator. Once initialized the 'apply'-method
     130              :          * can be called.
     131              :          * \returns     bool    success flag
     132              :          */
     133            0 :           void init()
     134            0 :           { UG_THROW("Please init with grid function!"); }
     135              : 
     136              :         ///     prepares functions for application
     137              : 
     138              :         /*      This method is used to prepare the in- and output vector used later in apply.
     139              :          * It can be called, after the init method has been called at least once.
     140              :          * The prepare method is e.g. used to set dirichlet values.
     141              :          */
     142            0 :         void prepare(grid_function_type& u) {}
     143              : 
     144              :         //! Apply operator
     145              :         /*! This method applies the operator, i.e, advances the time step*/
     146            0 :         void apply(grid_function_type& u1, const grid_function_type& u0)
     147            0 :         { UG_THROW("Fix interfaces!"); }
     148              : 
     149              :     virtual bool apply(SmartPtr<grid_function_type> u1, number t1, ConstSmartPtr<grid_function_type> u0, number t0) = 0;
     150              : 
     151              :         //! Set initial time step
     152            0 :         void set_time_step(double dt)
     153            0 :         { m_dt = dt; }
     154              : 
     155              :         double get_time_step()
     156            0 :         { return m_dt; }
     157              : 
     158            0 :         void set_precision_bound(double precisionBound)
     159            0 :         { m_precisionBound = precisionBound; return; }
     160              : 
     161            0 :         void set_no_log_out(bool bNoLogOut)
     162            0 :         { m_bNoLogOut = bNoLogOut; return; }
     163              : 
     164              : };
     165              : 
     166              : 
     167              : /// Integration of linear systems
     168              : template<class TDomain, class TAlgebra>
     169              : class ILinearTimeIntegrator : public ITimeIntegrator<TDomain, TAlgebra>
     170              : {
     171              : 
     172              : public:
     173              :         typedef ITimeIntegrator<TDomain, TAlgebra> base_type;
     174              :         typedef typename base_type::vector_type vector_type;
     175              :         typedef ILinearOperatorInverse<vector_type> linear_solver_type;
     176              :         typedef AssembledLinearOperator<TAlgebra> assembled_operator_type;
     177              : 
     178              :         // forward constructor
     179            0 :         ILinearTimeIntegrator()
     180            0 :         : base_type() {}
     181              : 
     182            0 :         ILinearTimeIntegrator(SmartPtr<linear_solver_type> lSolver)
     183            0 :         : base_type(),  m_spLinearSolver(lSolver)
     184            0 :         {}
     185              : 
     186              : 
     187            0 :         void set_linear_solver(SmartPtr<linear_solver_type> lSolver)
     188            0 :         { m_spLinearSolver=lSolver;}
     189              : 
     190              : protected:
     191              :         SmartPtr<linear_solver_type> m_spLinearSolver;
     192              : 
     193              : };
     194              : 
     195              : 
     196              : /// ITimeDiscDependentObject
     197              : template<class TAlgebra>
     198            0 : class ITimeDiscDependentObject
     199              : {
     200              : public:
     201              :         typedef ITimeDiscretization<TAlgebra> time_disc_type;
     202              : 
     203              :         ITimeDiscDependentObject(SmartPtr<time_disc_type> spTimeDisc) :
     204              :                 m_spTimeDisc(spTimeDisc)
     205              :         {}
     206              : 
     207            0 :         SmartPtr<time_disc_type> get_time_disc() {return m_spTimeDisc;}
     208              : protected:
     209              :         SmartPtr<time_disc_type> m_spTimeDisc;
     210              : };
     211              : 
     212              : 
     213              : /// Integrate over a given time interval (for a linear problem)
     214              : template<class TDomain, class TAlgebra>
     215              : class LinearTimeIntegrator :
     216              :         public ILinearTimeIntegrator<TDomain, TAlgebra>,
     217              :         public ITimeDiscDependentObject<TAlgebra>
     218              : 
     219              : {
     220              : private:
     221              : 
     222              : protected:
     223              :         typedef ITimeDiscDependentObject<TAlgebra> tdisc_dep_type;
     224              : public:
     225              :         typedef ILinearTimeIntegrator<TDomain, TAlgebra> base_type;
     226              :         typedef ITimeDiscretization<TAlgebra> time_disc_type;
     227              :         typedef typename base_type::grid_function_type grid_function_type;
     228              :         typedef VectorTimeSeries<typename base_type::vector_type> vector_time_series_type;
     229              : 
     230              :         // constructor
     231            0 :         LinearTimeIntegrator (SmartPtr< time_disc_type> tDisc)
     232            0 :         : base_type(), ITimeDiscDependentObject<TAlgebra>(tDisc) {}
     233              : 
     234              :         LinearTimeIntegrator (SmartPtr< time_disc_type> tDisc,    SmartPtr<typename base_type::linear_solver_type> lSolver)
     235              :         : base_type(lSolver), ITimeDiscDependentObject<TAlgebra>(tDisc) {}
     236              : 
     237              :         bool apply(SmartPtr<grid_function_type> u1, number t1, ConstSmartPtr<grid_function_type> u0, number t0);
     238              : };
     239              : 
     240              : 
     241              : /// Integrate over a given time interval (for a linear problem)
     242              : template<class TDomain, class TAlgebra>
     243              : class ConstStepLinearTimeIntegrator :
     244              :         public ILinearTimeIntegrator<TDomain, TAlgebra>,
     245              :         public ITimeDiscDependentObject<TAlgebra>
     246              : {
     247              : protected:
     248              :         typedef ITimeDiscDependentObject<TAlgebra> tdisc_dep_type;
     249              : public:
     250              :         typedef ILinearTimeIntegrator<TDomain, TAlgebra> base_type;
     251              :         typedef ITimeDiscretization<TAlgebra> time_disc_type;
     252              :         typedef typename base_type::linear_solver_type linear_solver_type;
     253              :         typedef typename base_type::grid_function_type grid_function_type;
     254              :         typedef VectorTimeSeries<typename base_type::vector_type> vector_time_series_type;
     255              : 
     256              : private:
     257              : 
     258              : protected:
     259              : 
     260              :         int m_numSteps;
     261              : public:
     262              : 
     263              :         // constructor
     264            0 :         ConstStepLinearTimeIntegrator (SmartPtr<time_disc_type> tDisc)
     265            0 :         : base_type(), ITimeDiscDependentObject<TAlgebra>(tDisc), m_numSteps(1) {}
     266              : 
     267            0 :         ConstStepLinearTimeIntegrator (SmartPtr<time_disc_type> tDisc, SmartPtr<typename base_type::linear_solver_type> lSolver)
     268            0 :         : base_type(lSolver), ITimeDiscDependentObject<TAlgebra>(tDisc), m_numSteps(1) {}
     269              : 
     270            0 :         void set_num_steps(int steps) {m_numSteps = steps;}
     271              : 
     272              :         bool apply(SmartPtr<grid_function_type> u1, number t1, ConstSmartPtr<grid_function_type> u0, number t0);
     273              : };
     274              : 
     275              : 
     276              : /// Integrate over a given time interval (for a linear problem)
     277              : template<class TDomain, class TAlgebra>
     278              : class TimeIntegratorLinearAdaptive :
     279              :         public ILinearTimeIntegrator<TDomain, TAlgebra>,
     280              :         public ITimeDiscDependentObject<TAlgebra>
     281              : {
     282              : protected:
     283              :         typedef ITimeDiscDependentObject<TAlgebra> tdisc_dep_type;
     284              :         
     285              : public:
     286              :         typedef ILinearTimeIntegrator<TDomain, TAlgebra> base_type;
     287              :         typedef ITimeDiscretization<TAlgebra> time_disc_type;
     288              :         typedef typename base_type::grid_function_type grid_function_type;
     289              :         typedef VectorTimeSeries<typename base_type::vector_type> vector_time_series_type;
     290              : 
     291              : protected:
     292              : 
     293              :         SmartPtr<time_disc_type> m_spTimeDisc2;        // set during init
     294              : 
     295              :         double m_tol, m_dtmin, m_dtmax;
     296              : 
     297              : 
     298              : public:
     299            0 :   TimeIntegratorLinearAdaptive (SmartPtr<time_disc_type> tDisc1, SmartPtr<time_disc_type> tDisc2)
     300            0 :         : base_type(), ITimeDiscDependentObject<TAlgebra>(tDisc1), m_tol(1e-2), m_dtmin(-1.0), m_dtmax(-1.0)
     301              :         {
     302            0 :                 m_spTimeDisc2 = tDisc2;
     303            0 :         }
     304              : 
     305            0 :         void init(grid_function_type const& u)
     306              :         {
     307              :                 // call base
     308              :                 base_type::init(u);
     309              :                 //m_spTimeDisc2 = make_sp(new typename base_type::time_disc_type(base_type::m_spDomainDisc, base_type::m_theta));
     310            0 :         }
     311              :         
     312              :         bool apply(SmartPtr<grid_function_type> u1, number t1, ConstSmartPtr<grid_function_type> u0, number t0);
     313              : 
     314            0 :     void set_tol(double tol) {m_tol = tol;}
     315            0 :     void set_time_step_min(number dt) {m_dtmin = dt;}
     316            0 :     void set_time_step_max(number dt) {m_dtmax = dt;}
     317              : };
     318              : 
     319              : 
     320              : class TimeStepBounds
     321              : {
     322              : public:
     323              :         TimeStepBounds()
     324            0 :         : m_dtMin(0.0), m_dtMax(std::numeric_limits<double>::max()),  m_redFac(1.0), m_incFac(1.0)
     325              :         {}
     326              : 
     327            0 :         void set_dt_min(double min) { m_dtMin = min; }
     328            0 :         double get_dt_min() { return m_dtMin; }
     329              : 
     330            0 :         void set_dt_max(double max) { m_dtMax = max; }
     331            0 :         double get_dt_max() { return m_dtMax; }
     332              : 
     333            0 :         void set_reduction_factor(double dec) { m_redFac = dec; }
     334            0 :         double get_reduction_factor() { return m_redFac; }
     335              : 
     336            0 :         void set_increase_factor(double inc) { m_incFac = inc; }
     337            0 :         double get_increase_factor() { return m_incFac; }
     338              : 
     339              :         void rescale(double alpha)
     340              :         { m_dtMin*= alpha; m_dtMax*= alpha;}
     341              : 
     342              : protected:
     343              :         double m_dtMin, m_dtMax;
     344              :         double m_redFac, m_incFac;
     345              : };
     346              : 
     347              : /// Integration of non-linear systems (with bounds on dt)
     348              : template<class TDomain, class TAlgebra>
     349            0 : class INonlinearTimeIntegrator
     350              : : public ITimeIntegrator<TDomain, TAlgebra>
     351              : {
     352              : public:
     353              :         typedef ITimeIntegrator<TDomain, TAlgebra> base_type;
     354              :         typedef typename base_type::vector_type vector_type;
     355              :         typedef IOperatorInverse<vector_type> solver_type;
     356              :         typedef AssembledOperator<TAlgebra> assembled_operator_type;
     357              : 
     358            0 :         INonlinearTimeIntegrator()
     359            0 :         : m_dtBounds() {}
     360              : 
     361            0 :         void set_solver(SmartPtr<solver_type> solver)
     362            0 :         { m_spSolver=solver;}
     363              : 
     364              :         ConstSmartPtr<solver_type> get_solver() const
     365              :         { return m_spSolver;}
     366              : 
     367              :         SmartPtr<solver_type> get_solver()
     368              :         { return m_spSolver;}
     369              : 
     370            0 :         void set_dt_min(double min) { m_dtBounds.set_dt_min(min); }
     371              :         double get_dt_min() { return m_dtBounds. get_dt_min(); }
     372              : 
     373            0 :         void set_dt_max(double max) { m_dtBounds.set_dt_max(max); }
     374              :         double get_dt_max() { return m_dtBounds.get_dt_max(); }
     375              : 
     376            0 :         void set_reduction_factor(double dec) { m_dtBounds.set_reduction_factor(dec); }
     377              :         double get_reduction_factor() { return m_dtBounds.get_reduction_factor(); }
     378              : 
     379            0 :         void set_increase_factor(double inc) { m_dtBounds.set_increase_factor(inc); }
     380              :         double get_increase_factor() { return m_dtBounds.get_increase_factor(); }
     381              : 
     382              : protected:
     383              :         SmartPtr<solver_type> m_spSolver;
     384              :         TimeStepBounds m_dtBounds;
     385              : 
     386              : };
     387              : 
     388              : 
     389              : //! This class integrates (t0, t1] with stops at intermediate points tk.
     390              : template<class TDomain, class TAlgebra>
     391              : class DiscontinuityIntegrator :
     392              :                 public INonlinearTimeIntegrator<TDomain, TAlgebra>
     393              : {
     394              : public:
     395              : 
     396              :         typedef INonlinearTimeIntegrator<TDomain, TAlgebra> base_type;
     397              :         typedef typename base_type::grid_function_type grid_function_type;
     398              : 
     399            0 :         DiscontinuityIntegrator(SmartPtr<base_type> baseIntegrator) :
     400            0 :                 base_type(), m_wrappedIntegrator(baseIntegrator), m_timePoints() {};
     401              : 
     402            0 :         bool apply(SmartPtr<grid_function_type> u1, number t1, ConstSmartPtr<grid_function_type> u0, number t0)
     403              :         {
     404              :                 int dstep = 0;
     405              :                 auto tpoint = m_timePoints.begin();
     406            0 :                 double tcurr = (tpoint == m_timePoints.end()) ? t1 : (*tpoint);
     407              :                 double eps = 1e-8;
     408              : 
     409              :                 // Perform first step.
     410              :                 //this->notify_init_step(u0, dstep, t0,  tcurr-t0);
     411            0 :                 bool status = m_wrappedIntegrator->apply(u1, tcurr*(1.0-eps), u0, t0);
     412            0 :                 this->notify_finalize_step(u1, dstep++, tcurr, tcurr-t0);
     413              : 
     414              :                 // Repeat for all intermediate points.
     415            0 :                 while (tpoint != m_timePoints.end())
     416              :                 {
     417              :                         tpoint++;
     418            0 :                         double tnext = (tpoint == m_timePoints.end()) ? t1 : (*tpoint);
     419              : 
     420              :                         // Perform step.
     421              :                         //this->notify_init_step(u1, dstep, tcurr, tnext-tcurr);
     422            0 :                         status = status && m_wrappedIntegrator->apply(u1, tnext*(1.0-eps), u1, tcurr);
     423            0 :                         this->notify_finalize_step(u1, dstep++, tnext, tnext-tcurr);
     424              : 
     425              :                         tcurr = tnext;
     426              :                 }
     427            0 :                 this->notify_end(u1, dstep, t1, 0.0);
     428            0 :                 return status;
     429              :         }
     430              : 
     431            0 :         void insert_points (std::vector<double> points)
     432              :         {
     433            0 :                 m_timePoints = points;
     434            0 :         }
     435              : protected:
     436              :         SmartPtr<base_type> m_wrappedIntegrator;
     437              :         std::vector<double> m_timePoints;
     438              : };
     439              : 
     440              : } // namespace ug
     441              : 
     442              : #include "time_integrator_impl.hpp"
     443              : 
     444              : #endif /* __H__LIMEX__TIME_INTEGRATOR_HPP__ */
        

Generated by: LCOV version 2.0-1