From 0cf5127e6b9f1a8b92dd958226c0ea1af3635975 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Mon, 18 May 1998 16:45:54 +0000 Subject: [PATCH] Take over timer module from the old DEAL library. git-svn-id: https://svn.dealii.org/trunk@309 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/base/include/base/function.h | 74 +++++++++++++++++++++ deal.II/base/include/base/timer.h | 82 ++++++++++++++++++++++++ deal.II/base/source/timer.cc | 96 ++++++++++++++++++++++++++++ 3 files changed, 252 insertions(+) create mode 100644 deal.II/base/include/base/timer.h create mode 100644 deal.II/base/source/timer.cc diff --git a/deal.II/base/include/base/function.h b/deal.II/base/include/base/function.h index adc4fab474..8c530205eb 100644 --- a/deal.II/base/include/base/function.h +++ b/deal.II/base/include/base/function.h @@ -31,10 +31,62 @@ * both those functions returning only one value as well as those returning * a whole array, since the cost of evaluation of a point value is often * less than the virtual function call itself. + * + * + * \subsection{Support for time dependant functions} + * + * The library was also designed for time dependant problems. For this + * purpose, the function objects also contain a field which stores the + * time, as well as functions manipulating them. Time independant problems + * should not access or even abuse them for other purposes, but since one + * normally does not create thousands of function objects, the gain in + * generality weighs out the fact that we need not store the time value + * for not time dependant problems. The second advantage is that the derived + * standard classes like #ZeroFunction#, #ConstantFunction# etc also work + * for time dependant problems. + * + * Access to the time goes through the following functions: + * \begin{verbatim} + * \item #get_time#: return the present value of the time variable. + * \item #set_time#: set the time value to a specific value. + * \item #advance_time#: increase the time by a certain time step. + * \end{verbatim} + * The latter two functions are virtual, so that derived classes can + * perform computations which need only be done once for every new time. + * For example, if a time dependant function had a factor #sin(t)#, then + * it may be a reasonable choice to calculate this factor in a derived + * version of #set_time#, store it in a member variable and use that one + * rather than computing it every time #operator()#, #value_list# or one + * of the other functions is called. + * + * By default, the #advance_time# function calls the #set_time# function + * with the new time, so it is sufficient in most cases to overload only + * #set_time# for computations as sketched out above. + * + * Derived classes should access the time variable directly, which is + * available under the obvious name #time#, rather than calling + * #get_time#. + * + * The constructor of this class takes an initial value for the time + * variable, which defaults to zero. Because a default value is given, + * none of the derived classes needs to take an initial value for the + * time variable if not needed. + * + * Once again the warning: do not use the #time# variable for any other + * purpose than the intended one! This will inevitably lead to confusion. + * + * @author Wolfgang Bangerth, 1998 */ template class Function { public: + /** + * Constructor. May take an initial vakue + * for the time variable, which defaults + * to zero. + */ + Function (const double initial_time = 0.0); + /** * Virtual destructor; absolutely * necessary in this case. @@ -74,7 +126,23 @@ class Function { virtual void gradient_list (const vector > &points, vector > &gradients) const; + /** + * Return the value of the time variable/ + */ + double get_time () const; + + /** + * Set the time to #new_time#, overwriting + * the old value. + */ + virtual void set_time (const double new_time); + /** + * Advance the time by the given + * time step #delta_t#. + */ + virtual void advance_time (const double delta_t); + /** * Exception */ @@ -86,6 +154,12 @@ class Function { int, int, << "The vector has size " << arg1 << " but should have " << arg2 << " elements."); + + protected: + /** + * Store the present time. + */ + double time; }; diff --git a/deal.II/base/include/base/timer.h b/deal.II/base/include/base/timer.h new file mode 100644 index 0000000000..4da6108630 --- /dev/null +++ b/deal.II/base/include/base/timer.h @@ -0,0 +1,82 @@ +/*---------------------------- timer.h ---------------------------*/ +/* $Id$ */ +#ifndef __timer_H +#define __timer_H +/*---------------------------- timer.h ---------------------------*/ + + +/** + * This is a very simple class which provides information about the time + * elapsed since the timer was started last time. Information is retrieved + * from the system on the basis of clock cycles since last time the computer + * was booted. On a SUN workstation, this information is exact to about a + * microsecond. + * + * + * \subsection{Usage} + * + * + * Note: the implementation of this class is system dependant. + * + * @author R. Becker, G. Kanschat, F.-T. Suttmeier, revised by W. Bangerth + */ +class Timer { +public: + /** + * Constructor. Starts the timer at 0 sec. + */ + Timer(); + + /** + * Re-start the timer at the point where + * it was stopped. This way a cumulative + * measurement of time is possible. + */ + void start(); + + /** + * Sets the current time as next starting + * time and return it. + */ + double stop(); + + /** + * Stop the timer if neccessary and reset + * the elapsed time to zero. + */ + void reset(); + + /** + * Access to the current time without + * disturbing time measurement. + */ + // A regular call to this function serves to avoid time overflow + // (which is now nearly every 30 minutes on UNIX machines) in long-time + // measurements. + // + double operator() (); + + private: + + double start_time; + double cumulative_time; + static const double overtime; + unsigned int overflow; + + /** + * Store whether the timer is presently + * running. + */ + bool running; + + double full_time() const; +}; + + + + + +/*---------------------------- timer.h ---------------------------*/ +/* end of #ifndef __timer_H */ +#endif +/*---------------------------- timer.h ---------------------------*/ diff --git a/deal.II/base/source/timer.cc b/deal.II/base/source/timer.cc new file mode 100644 index 0000000000..9f5fb82c4c --- /dev/null +++ b/deal.II/base/source/timer.cc @@ -0,0 +1,96 @@ +/* $Id$ */ + +#include +#include +#include + + + +#if #cpu(transputer) +# define TIMER TimeNowLow() +# define DIVIDE CLK_TCK_LOW +#endif +#ifdef _ARCH_PPC +# if #system(parix) +# define TIMER TimeNow() +# define DIVIDE CLOCK_TICK +# endif +# if #system(aix) +# define DIVIDE CLOCKS_PER_SEC +# endif +#endif +#if #cpu(sparc) +# define DIVIDE 1.e6 +#endif + +#ifndef TIMER +#define TIMER clock(); +#endif + +#ifndef OVER_TIME +#define OVER_TIME 4294967296./DIVIDE +#endif + +#ifndef DIVIDE +#define DIVIDE 1.e6 +#endif + + +const double Timer::overtime = OVER_TIME; + + +Timer::Timer() + : cumulative_time(0.) +{ + start(); +}; + + +void Timer::start () { + running = tru; + overflow = 0; + start_time = TIMER / DIVIDE; +}; + + + +double Timer::stop () { + running = false; + double dtime = TIMER / DIVIDE - start_time; + if (dtime < 0) { + overflow++; + }; + + cumulative_time += dtime; + return full_time (); +}; + + + +double Timer::operator() () { + if (running) { + const double dtime = TIMER / DIVIDE - start_time; + if (dtime < 0) { + overflow++; + }; + + return dtime + full_time(); + }; + + return full_time(); +}; + + + +void Timer::reset () { + cumulative_time = 0.; + running = false; +}; + + + +double Timer::full_time () const { + return cumulative_time + overflow*overtime; +}; + + -- 2.39.5