virtual void start_sweep (const unsigned int sweep_no);
/**
- * Analogon to the above function,
- * calling #end_sweep# of each time
- * step object.
+ * Analogon to the above
+ * function, calling #end_sweep#
+ * of each time step object. The
+ * same applies with respect to
+ * the #virtual#ness of this
+ * function as for the previous
+ * one.
+ *
+ * This function does not
+ * guarantee that #end_sweep# is
+ * called for successive time
+ * steps, rather the order of
+ * time steps for which the
+ * function is called is
+ * arbitrary. You should
+ * therefore not assume that that
+ * function has been called for
+ * previous time steps
+ * already. If in multithread
+ * mode, the #end_sweep# function
+ * of several time steps is
+ * called at once, so you should
+ * use synchronization
+ * mechanisms, if your program
+ * requires so.
+ *
+ * The parameter denotes the
+ * number of threads that shall
+ * be spawned in parallel. It
+ * defaults to only one thread,
+ * and the value is ignored if
+ * not in multithread mode.
*/
- virtual void end_sweep ();
+ virtual void end_sweep (const unsigned int n_threads = 1);
/**
* Exception.
* for more information.
*/
const TimeSteppingData timestepping_data_postprocess;
-
+
+ private:
+
+ /**
+ * Do the work of #end_sweep()#
+ * for some timesteps only. This
+ * is useful in multithread mode.
+ */
+ void * end_sweep (const unsigned int begin_timestep,
+ const unsigned int end_timestep);
};
#include <grid/tria_iterator.h>
#include <lac/vector.h>
+#ifdef DEAL_II_USE_MT
+# include <base/thread_manager.h>
+# define NTHREADS 4
+#endif
+
#include <functional>
#include <algorithm>
#include <numeric>
-void TimeDependent::end_sweep ()
+void TimeDependent::end_sweep (const unsigned int
+#ifdef DEAL_II_USE_MT
+ n_threads
+#endif
+)
{
- for (unsigned int step=0; step<timesteps.size(); ++step)
+#ifdef DEAL_II_USE_MT
+ // set up the data needed by each
+ // thread
+ typedef ThreadManager::Mem_Fun_Data2<TimeDependent,unsigned int,unsigned int> MemFunData;
+ vector<MemFunData> mem_fun_data (n_threads,
+ MemFunData(this, 0, 0, &end_sweep));
+ const unsigned int stride = timesteps.size() / n_threads;
+ for (unsigned int i=0; i<n_threads; ++i)
+ {
+ mem_fun_data[i].arg1 = i*stride;
+ mem_fun_data[i].arg2 = (i+1)*stride;
+ };
+ mem_fun_data.back().arg2 = timesteps.size();
+
+ // spawn the threads...
+ ThreadManager thread_manager;
+ for (unsigned int i=0; i<n_threads; ++i)
+ thread_manager.spawn (&mem_fun_data[i],
+ THR_SCOPE_SYSTEM | THR_DETACHED);
+
+ // ...and wait for their return
+ thread_manager.wait();
+
+#else
+ end_sweep (0, timesteps.size());
+#endif
+}
+
+
+
+void * TimeDependent::end_sweep (const unsigned int begin,
+ const unsigned int end)
+{
+ for (unsigned int step=begin; step<end; ++step)
timesteps[step]->end_sweep ();
+ return 0;
};