// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2005, 2006, 2009 by the deal.II authors
+// Copyright (C) 2004, 2005, 2006, 2009, 2010 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
#include <base/polynomial.h>
#include <base/polynomial_space.h>
#include <base/table.h>
+#include <base/thread_management.h>
#include <vector>
* <dt> In 2D:
* <dd> The 2D-curl of the functions <i>x<sup>k+1</sup>y</i>
* and <i>xy<sup>k+1</sup></i>.
- * <dt>In 3D:
+ * <dt>In 3D:
* <dd> For any <i>i=0,...,k</i> the curls of
* <i>(0,0,xy<sup>i+1</sup>z<sup>k-i</sup>)</i>,
* <i>(x<sup>k-i</sup>yz<sup>i+1</sup>,0,0)</i> and
void compute (const Point<dim> &unit_point,
std::vector<Tensor<1,dim> > &values,
std::vector<Tensor<2,dim> > &grads,
- std::vector<Tensor<3,dim> > &grad_grads) const;
-
+ std::vector<Tensor<3,dim> > &grad_grads) const;
+
/**
* Returns the number of BDM polynomials.
*/
unsigned int n () const;
-
+
/**
* Returns the degree of the BDM
* space, which is one less than
* the highest polynomial degree.
*/
unsigned int degree () const;
-
+
/**
* Return the number of
* polynomials in the space
* classes.
*/
static unsigned int compute_n_pols(unsigned int degree);
-
+
private:
/**
* An object representing the
* degree zero to <i>k</i>.
*/
std::vector<Polynomials::Polynomial<double> > monomials;
-
+
/**
* Number of BDM
* polynomials.
*/
unsigned int n_pols;
-
+
+ /**
+ * A mutex that guards the
+ * following scratch arrays.
+ */
+ mutable Threads::Mutex mutex;
+
/**
* Auxiliary memory.
*/
mutable std::vector<double> p_values;
-
+
/**
* Auxiliary memory.
*/
mutable std::vector<Tensor<1,dim> > p_grads;
-
+
/**
* Auxiliary memory.
*/
// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 by the deal.II authors
+// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
ExcDimensionMismatch(grad_grads.size(), n_pols));
const unsigned int n_sub = polynomial_space.n();
- p_values.resize((values.size() == 0) ? 0 : n_sub);
- p_grads.resize((grads.size() == 0) ? 0 : n_sub);
- p_grad_grads.resize((grad_grads.size() == 0) ? 0 : n_sub);
-
- // Compute values of complete space
- // and insert into tensors. Result
- // will have first all polynomials
- // in the x-component, then y and
- // z.
- polynomial_space.compute (unit_point, p_values, p_grads, p_grad_grads);
-
- std::fill(values.begin(), values.end(), Tensor<1,dim>());
- for (unsigned int i=0;i<p_values.size();++i)
- {
+
+ // guard access to the scratch
+ // arrays in the following block
+ // using a mutex to make sure they
+ // are not used by multiple threads
+ // at once
+ {
+ Threads::Mutex::ScopedLock lock(mutex);
+
+ p_values.resize((values.size() == 0) ? 0 : n_sub);
+ p_grads.resize((grads.size() == 0) ? 0 : n_sub);
+ p_grad_grads.resize((grad_grads.size() == 0) ? 0 : n_sub);
+
+ // Compute values of complete space
+ // and insert into tensors. Result
+ // will have first all polynomials
+ // in the x-component, then y and
+ // z.
+ polynomial_space.compute (unit_point, p_values, p_grads, p_grad_grads);
+
+ std::fill(values.begin(), values.end(), Tensor<1,dim>());
+ for (unsigned int i=0;i<p_values.size();++i)
for (unsigned int j=0;j<dim;++j)
- {
- values[i+j*n_sub][j] = p_values[i];
- }
-
- }
-
- std::fill(grads.begin(), grads.end(), Tensor<2,dim>());
- for (unsigned int i=0;i<p_grads.size();++i)
- {
+ values[i+j*n_sub][j] = p_values[i];
+
+ std::fill(grads.begin(), grads.end(), Tensor<2,dim>());
+ for (unsigned int i=0;i<p_grads.size();++i)
for (unsigned int j=0;j<dim;++j)
grads[i+j*n_sub][j] = p_grads[i];
- }
-
- std::fill(grad_grads.begin(), grad_grads.end(), Tensor<3,dim>());
- for (unsigned int i=0;i<p_grad_grads.size();++i)
- {
+
+ std::fill(grad_grads.begin(), grad_grads.end(), Tensor<3,dim>());
+ for (unsigned int i=0;i<p_grad_grads.size();++i)
for (unsigned int j=0;j<dim;++j)
grad_grads[i+j*n_sub][j] = p_grad_grads[i];
- }
+ }
// This is the first polynomial not
// covered by the P_k subspace
// derivatives
std::vector<std::vector<double> > monovali(dim, std::vector<double>(4));
std::vector<std::vector<double> > monovalk(dim, std::vector<double>(4));
-
+
if (dim == 2)
{
for (unsigned int d=0;d<dim;++d)
double orientation = 1.;
if ((face==0) || (face==3))
orientation = -1.;
-
+
for (unsigned int k=0;k<qface.size();++k)
{
const double w = qface.weight(k) * orientation;
p(0) = 1.;
case 3:
p(1) = x;
- break;
+ break;
}
// std::cerr << p
// << '\t' << moment_weight[0].value(x)
// << '\t' << moment_weight[1].value(x)
// ;
-
+
compute (p, values, grads, grad_grads);
-
+
for (unsigned int i=0;i<n();++i)
{
// std::cerr << '\t' << std::setw(6) << values[i][1-face%2];
// std::cerr << std::endl;
}
}
-
+
// Volume integrals are missing
//
// This degree is one larger