#include <fe/fe.h>
#include <fe/fe_values.h>
+#ifdef DEAL_II_USE_MT
+#include <base/thread_manager.h>
+#endif
template <int dim>
DataOut_DoFData<dim>::DataEntry::DataEntry (const Vector<double> *data,
names(names)
{};
-
-
-
template <int dim>
DataOut_DoFData<dim>::DataOut_DoFData () :
dofs(0)
{};
-
-
template <int dim>
DataOut_DoFData<dim>::~DataOut_DoFData ()
{
clear ();
};
-
-
template <int dim>
void DataOut_DoFData<dim>::attach_dof_handler (const DoFHandler<dim> &d)
{
dofs->subscribe ();
};
-
-
template <int dim>
void DataOut_DoFData<dim>::add_data_vector (const Vector<double> &vec,
const vector<string> &names)
};
-
-
-
-
template <int dim>
-void DataOut<dim>::build_patches (const unsigned int n_subdivisions)
+void * DataOut<dim>::build_some_patches (Data data)
{
- Assert (dofs != 0, ExcNoDoFHandlerSelected());
-
- const unsigned int n_components = dofs->get_fe().n_components();
- const unsigned int n_datasets = dof_data.size() * n_components +
- cell_data.size();
-
- // clear the patches array
- if (true)
- {
- vector<DataOutBase::Patch<dim> > dummy;
- patches.swap (dummy);
- };
+ QTrapez<1> q_trapez;
+ QIterated<dim> patch_points (q_trapez, data.n_subdivisions);
+ FEValues<dim> fe_patch_values(dofs->get_fe(),
+ patch_points,
+ update_default);
- // first count the cells we want to
- // create patches of and make sure
- // there is enough memory for that
- unsigned int n_patches = 0;
- for (DoFHandler<dim>::cell_iterator cell=first_cell();
- cell != dofs->end();
- cell = next_cell(cell))
- ++n_patches;
-
-
- // before we start the loop:
- // create a quadrature rule that
- // actually has the points on this
- // patch, and an object that
- // extracts the data on each
- // cell to these points
- QTrapez<1> q_trapez;
- QIterated<dim> patch_points (q_trapez, n_subdivisions);
- FEValues<dim> fe_patch_values (dofs->get_fe(),
- patch_points,
- update_default);
const unsigned int n_q_points = patch_points.n_quadrature_points;
- vector<double> patch_values (n_q_points);
- vector<Vector<double> > patch_values_system (n_q_points,
- Vector<double>(n_components));
- DataOutBase::Patch<dim> default_patch;
- default_patch.n_subdivisions = n_subdivisions;
- default_patch.data.reinit (n_datasets, n_q_points);
- patches.insert (patches.end(), n_patches, default_patch);
+ unsigned int cell_number = 0;
+ vector<DataOutBase::Patch<dim> >::iterator patch = patches.begin();
+ DoFHandler<dim>::cell_iterator cell=first_cell();
- // now loop over all cells and
+ // get first cell in this thread
+ for (unsigned int i=0;i<data.this_thread;++i,++patch,++cell_number,
+ cell=next_cell(cell));
+
+ // now loop over all cells and
// actually create the patches
- vector<DataOutBase::Patch<dim> >::iterator patch = patches.begin();
- unsigned int cell_number = 0;
- for (DoFHandler<dim>::cell_iterator cell=first_cell();
- cell != dofs->end(); cell=next_cell(cell), ++patch, ++cell_number)
+ for (;cell != dofs->end();)
{
Assert (patch != patches.end(), ExcInternalError());
for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
patch->vertices[vertex] = cell->vertex(vertex);
-
- if (n_datasets > 0)
+
+ if (data.n_datasets > 0)
{
fe_patch_values.reinit (cell);
// first fill dof_data
for (unsigned int dataset=0; dataset<dof_data.size(); ++dataset)
{
- if (n_components == 1)
+ if (data.n_components == 1)
{
fe_patch_values.get_function_values (*dof_data[dataset].data,
- patch_values);
+ data.patch_values);
for (unsigned int q=0; q<n_q_points; ++q)
- patch->data(dataset,q) = patch_values[q];
+ patch->data(dataset,q) = data.patch_values[q];
}
else
// system of components
{
fe_patch_values.get_function_values (*dof_data[dataset].data,
- patch_values_system);
- for (unsigned int component=0; component<n_components; ++component)
+ data.patch_values_system);
+ for (unsigned int component=0; component<data.n_components;
+ ++component)
for (unsigned int q=0; q<n_q_points; ++q)
- patch->data(dataset*n_components+component,q) = patch_values_system[q](component);
+ patch->data(dataset*data.n_components+component,q) =
+ data.patch_values_system[q](component);
};
};
{
const double value = (*cell_data[dataset].data)(cell_number);
for (unsigned int q=0; q<n_q_points; ++q)
- patch->data(dataset+dof_data.size()*n_components,q) = value;
+ patch->data(dataset+dof_data.size()*data.n_components,q) =
+ value;
};
};
+ // next cell (patch) in this thread
+ for (unsigned int i=0;((i<data.n_threads)&&(cell != dofs->end()));
+ ++i,++patch,++cell_number,cell=next_cell(cell));
+
+ };
+
+ return 0;
+}
+
+
+
+
+template <int dim>
+void DataOut<dim>::build_patches (const unsigned int n_subdivisions,
+ const unsigned int n_threads_)
+{
+ unsigned int n_threads = n_threads_;
+
+ Assert (dofs != 0, ExcNoDoFHandlerSelected());
+
+ // if not in multithread mode
+ // set nr of threads to one
+#ifndef DEAL_II_USE_MT
+ n_threads = 1;
+#endif
+
+
+ // before we start the loop:
+ // create a quadrature rule that
+ // actually has the points on this
+ // patch
+ QTrapez<1> q_trapez;
+ QIterated<dim> patch_points (q_trapez, n_subdivisions);
+
+ const unsigned int n_q_points = patch_points.n_quadrature_points;
+ const unsigned int n_components = dofs->get_fe().n_components();
+ const unsigned int n_datasets = dof_data.size() * n_components +
+ cell_data.size();
+
+ // clear the patches array
+ if (true)
+ {
+ vector<DataOutBase::Patch<dim> > dummy;
+ patches.swap (dummy);
};
+
+ // first count the cells we want to
+ // create patches of and make sure
+ // there is enough memory for that
+ unsigned int n_patches = 0;
+ for (DoFHandler<dim>::cell_iterator cell=first_cell();
+ cell != dofs->end();
+ cell = next_cell(cell))
+ ++n_patches;
+
+ vector<Data> thread_data(n_threads);
+
+ // init data for the threads
+ for (unsigned int i=0;i<n_threads;++i)
+ {
+ thread_data[i].n_threads = n_threads;
+ thread_data[i].this_thread = i;
+ thread_data[i].n_components = n_components;
+ thread_data[i].n_datasets = n_datasets;
+ thread_data[i].n_subdivisions = n_subdivisions;
+ thread_data[i].patch_values.resize(n_q_points);
+ thread_data[i].patch_values_system.resize(n_q_points);
+
+ for (unsigned int k=0;k<n_components;++k)
+ thread_data[i].patch_values_system[k].reinit(n_components);
+ }
+
+ // create the patches with
+ // default values
+ DataOutBase::Patch<dim> default_patch;
+ default_patch.n_subdivisions = n_subdivisions;
+ default_patch.data.reinit (n_datasets, n_q_points);
+ patches.insert (patches.end(), n_patches, default_patch);
+
+#ifdef DEAL_II_USE_MT
+
+ ThreadManager thread_manager;
+
+ typedef ThreadManager::Mem_Fun_Data1
+ <DataOut<dim>, Data > MemFunData;
+
+ // One struct of this type for every thread
+ vector<MemFunData> mem_fun_data (n_threads,
+ MemFunData (this,
+ thread_data[0],
+ &DataOut<dim>::build_some_patches));
+
+ // get start cells for each thread
+ for (unsigned int l=0;l<n_threads;++l)
+ {
+ mem_fun_data[l].arg=thread_data[l];
+ thread_manager.spawn(&mem_fun_data[l],THR_SCOPE_SYSTEM | THR_DETACHED);
+ };
+ // wait for all threads to return
+ thread_manager.wait();
+
+ // just one thread
+#else
+ build_some_patches(thread_data[0]);
+#endif
};