* 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 <int dim>
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.
virtual void gradient_list (const vector<Point<dim> > &points,
vector<Point<dim> > &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
*/
int, int,
<< "The vector has size " << arg1 << " but should have "
<< arg2 << " elements.");
+
+ protected:
+ /**
+ * Store the present time.
+ */
+ double time;
};
--- /dev/null
+/*---------------------------- 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 ---------------------------*/
--- /dev/null
+/* $Id$ */
+
+#include <basic/timer.h>
+#include <ctime>
+#include <sys/time.h>
+
+
+
+#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;
+};
+
+