Commit 6577015f authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

* Bugfix and small changes to make it a little bit faster

parent 86fe284b
......@@ -24,7 +24,11 @@ namespace AMDiS {
bool optimized,
FirstOrderType type)
: SubAssembler(op, assembler, quad, 1, optimized, type)
{}
{
VectorOfFixVecs<DimVec<double> >
Lb(assembler->getRowFESpace()->getMesh()->getDim(), 1, NO_INIT);
tmpLb.resize(omp_get_overall_max_threads(), Lb);
}
FirstOrderAssembler*
FirstOrderAssembler::getSubAssembler(Operator* op,
......@@ -95,8 +99,8 @@ namespace AMDiS {
} else {
newAssembler =
(type == GRD_PSI) ?
dynamic_cast<FirstOrderAssembler*>( NEW Quad10(op, assembler, quad)) :
dynamic_cast<FirstOrderAssembler*>( NEW Quad01(op, assembler, quad));
dynamic_cast<FirstOrderAssembler*>(NEW Quad10(op, assembler, quad)) :
dynamic_cast<FirstOrderAssembler*>(NEW Quad01(op, assembler, quad));
}
}
......@@ -108,23 +112,22 @@ namespace AMDiS {
: FirstOrderAssembler(op, assembler, quad, false, GRD_PSI)
{}
void Stand10::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat)
{
DimVec<double> grdPsi(dim, DEFAULT_VALUE, 0.0);
double *phival = GET_MEMORY(double, nCol);
const BasisFunction *psi = owner->getRowFESpace()->getBasisFcts();
const BasisFunction *phi = owner->getColFESpace()->getBasisFcts();
int nPoints = quadrature->getNumPoints();
int myRank = omp_get_thread_num();
VectorOfFixVecs<DimVec<double> > &Lb = tmpLb[myRank];
Lb.resize(nPoints);
std::vector<double> phival(nCol);
VectorOfFixVecs<DimVec<double> > Lb(dim, nPoints, NO_INIT);
for (int iq = 0; iq < nPoints; iq++) {
Lb[iq].set(0.0);
}
int myRank = omp_get_thread_num();
for (int i = 0; i < static_cast<int>(terms[myRank].size()); i++) {
(static_cast<FirstOrderTerm*>((terms[myRank][i])))->getLb(elInfo, nPoints, Lb);
}
......@@ -143,7 +146,6 @@ namespace AMDiS {
}
}
}
FREE_MEMORY(phival, double, nCol);
}
void Stand10::calculateElementMatrix(const ElInfo *rowElInfo,
......@@ -165,13 +167,14 @@ namespace AMDiS {
TEST_EXIT(m)("No subElemCoordsMat!\n");
int nPoints = quadrature->getNumPoints();
int myRank = omp_get_thread_num();
VectorOfFixVecs<DimVec<double> > &Lb = tmpLb[myRank];
Lb.resize(nPoints);
VectorOfFixVecs<DimVec<double> > Lb(dim, nPoints, NO_INIT);
for (int iq = 0; iq < nPoints; iq++) {
Lb[iq].set(0.0);
}
int myRank = omp_get_thread_num();
for (int i = 0; i < static_cast<int>(terms[myRank].size()); i++) {
(static_cast<FirstOrderTerm*>((terms[myRank][i])))->
getLb(smallElInfo, nPoints, Lb);
......@@ -202,17 +205,41 @@ namespace AMDiS {
}
}
void Stand10::calculateElementVector(const ElInfo *elInfo, ElementVector *vec)
{
DimVec<double> grdPsi(dim, DEFAULT_VALUE, 0.0);
const BasisFunction *psi = owner->getRowFESpace()->getBasisFcts();
int nPoints = quadrature->getNumPoints();
int myRank = omp_get_thread_num();
VectorOfFixVecs<DimVec<double> > &Lb = tmpLb[myRank];
Lb.resize(nPoints);
for (int iq = 0; iq < nPoints; iq++) {
Lb[iq].set(0.0);
}
for (int i = 0; i < static_cast<int>(terms[myRank].size()); i++) {
(static_cast<FirstOrderTerm*>((terms[myRank][i])))->getLb(elInfo, nPoints, Lb);
}
for (int iq = 0; iq < nPoints; iq++) {
Lb[iq] *= elInfo->getDet();
for (int i = 0; i < nRow; i++) {
(*(psi->getGrdPhi(i)))(quadrature->getLambda(iq), grdPsi);
(*vec)[i] += quadrature->getWeight(iq) * (Lb[iq] * grdPsi);
}
}
}
Quad10::Quad10(Operator *op, Assembler *assembler, Quadrature *quad)
: FirstOrderAssembler(op, assembler, quad, true, GRD_PSI)
{
}
{}
void Quad10::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat)
{
VectorOfFixVecs<DimVec<double> > *grdPsi;
const double *phi;
if (firstCall) {
#ifdef _OPENMP
......@@ -228,13 +255,14 @@ namespace AMDiS {
}
int nPoints = quadrature->getNumPoints();
int myRank = omp_get_thread_num();
VectorOfFixVecs<DimVec<double> > &Lb = tmpLb[myRank];
Lb.resize(nPoints);
VectorOfFixVecs<DimVec<double> > Lb(dim,nPoints,NO_INIT);
for (int iq = 0; iq < nPoints; iq++) {
Lb[iq].set(0.0);
}
int myRank = omp_get_thread_num();
for (int i = 0; i < static_cast<int>(terms[myRank].size()); i++) {
(static_cast<FirstOrderTerm*>((terms[myRank][i])))->getLb(elInfo, nPoints, Lb);
}
......@@ -242,7 +270,7 @@ namespace AMDiS {
for (int iq = 0; iq < nPoints; iq++) {
Lb[iq] *= elInfo->getDet();
phi = phiFast->getPhi(iq);
const double *phi = phiFast->getPhi(iq);
grdPsi = psiFast->getGradient(iq);
for (int i = 0; i < nRow; i++) {
......@@ -252,6 +280,45 @@ namespace AMDiS {
}
}
void Quad10::calculateElementVector(const ElInfo *elInfo, ElementVector *vec)
{
VectorOfFixVecs<DimVec<double> > *grdPsi;
if (firstCall) {
#ifdef _OPENMP
#pragma omp critical
#endif
{
const BasisFunction *basFcts = owner->getRowFESpace()->getBasisFcts();
psiFast = updateFastQuadrature(psiFast, basFcts, INIT_GRD_PHI);
basFcts = owner->getColFESpace()->getBasisFcts();
phiFast = updateFastQuadrature(phiFast, basFcts, INIT_PHI);
firstCall = false;
}
}
int nPoints = quadrature->getNumPoints();
int myRank = omp_get_thread_num();
VectorOfFixVecs<DimVec<double> > &Lb = tmpLb[myRank];
Lb.resize(nPoints);
for (int iq = 0; iq < nPoints; iq++) {
Lb[iq].set(0.0);
}
for (int i = 0; i < static_cast<int>(terms[myRank].size()); i++) {
(static_cast<FirstOrderTerm*>((terms[myRank][i])))->getLb(elInfo, nPoints, Lb);
}
for (int iq = 0; iq < nPoints; iq++) {
Lb[iq] *= elInfo->getDet();
grdPsi = psiFast->getGradient(iq);
for (int i = 0; i < nRow; i++) {
(*vec)[i] += quadrature->getWeight(iq) * (Lb[iq] * (*grdPsi)[i]);
}
}
}
Pre10::Pre10(Operator *op, Assembler *assembler, Quadrature *quad)
: FirstOrderAssembler(op, assembler, quad, true, GRD_PSI)
......@@ -261,7 +328,6 @@ namespace AMDiS {
void Pre10::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat)
{
VectorOfFixVecs<DimVec<double> > Lb(dim, 1, NO_INIT);
const int *k;
const double *values;
......@@ -281,6 +347,8 @@ namespace AMDiS {
const int **nEntries = q10->getNumberEntries();
int myRank = omp_get_thread_num();
// Do not need do resize Lb, because it's size is always at least one.
VectorOfFixVecs<DimVec<double> > &Lb = tmpLb[myRank];
Lb[0].set(0.0);
for (int i = 0; i < static_cast<int>( terms[myRank].size()); i++) {
......@@ -307,7 +375,6 @@ namespace AMDiS {
: FirstOrderAssembler(op, assembler, quad, false, GRD_PHI)
{}
void Stand01::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat)
{
VectorOfFixVecs<DimVec<double> > grdPhi(dim, nCol, NO_INIT);
......@@ -316,8 +383,9 @@ namespace AMDiS {
const BasisFunction *phi = owner->getColFESpace()->getBasisFcts();
int nPoints = quadrature->getNumPoints();
VectorOfFixVecs<DimVec<double> > Lb(dim, nPoints, NO_INIT);
int myRank = omp_get_thread_num();
VectorOfFixVecs<DimVec<double> > &Lb = tmpLb[myRank];
Lb.resize(nPoints);
for (int iq = 0; iq < nPoints; iq++) {
Lb[iq].set(0.0);
......@@ -347,7 +415,7 @@ namespace AMDiS {
const ElInfo *largeElInfo,
ElementMatrix *mat)
{
FUNCNAME("Stand10::calculateElementMatrix()");
FUNCNAME("Stand01::calculateElementMatrix()");
TEST_EXIT((nRow <= 3) && (nCol <= 3))("not yet!\n");
......@@ -360,13 +428,14 @@ namespace AMDiS {
TEST_EXIT(m)("No subElemCoordsMat!\n");
int nPoints = quadrature->getNumPoints();
int myRank = omp_get_thread_num();
VectorOfFixVecs<DimVec<double> > &Lb = tmpLb[myRank];
Lb.resize(nPoints);
VectorOfFixVecs<DimVec<double> > Lb(dim, nPoints, NO_INIT);
for (int iq = 0; iq < nPoints; iq++) {
Lb[iq].set(0.0);
}
int myRank = omp_get_thread_num();
for (int i = 0; i < static_cast<int>(terms[myRank].size()); i++) {
(static_cast<FirstOrderTerm*>((terms[myRank][i])))->
getLb(smallElInfo, nPoints, Lb);
......@@ -396,35 +465,9 @@ namespace AMDiS {
}
}
void Stand10::calculateElementVector(const ElInfo *elInfo, ElementVector *vec)
{
DimVec<double> grdPsi(dim, DEFAULT_VALUE, 0.0);
const BasisFunction *psi = owner->getRowFESpace()->getBasisFcts();
int nPoints = quadrature->getNumPoints();
VectorOfFixVecs<DimVec<double> > Lb(dim,nPoints,NO_INIT);
int myRank = omp_get_thread_num();
for (int iq = 0; iq < nPoints; iq++) {
Lb[iq].set(0.0);
}
for (int i = 0; i < static_cast<int>(terms[myRank].size()); i++) {
(static_cast<FirstOrderTerm*>((terms[myRank][i])))->getLb(elInfo, nPoints, Lb);
}
for (int iq = 0; iq < nPoints; iq++) {
Lb[iq] *= elInfo->getDet();
for (int i = 0; i < nRow; i++) {
(*(psi->getGrdPhi(i)))(quadrature->getLambda(iq), grdPsi);
(*vec)[i] += quadrature->getWeight(iq) * (Lb[iq] * grdPsi);
}
}
}
Quad01::Quad01(Operator *op, Assembler *assembler, Quadrature *quad)
: FirstOrderAssembler(op, assembler, quad, true, GRD_PHI)
{
}
{}
void Quad01::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat)
{
......@@ -444,8 +487,9 @@ namespace AMDiS {
}
int nPoints = quadrature->getNumPoints();
VectorOfFixVecs<DimVec<double> > Lb(dim,nPoints,NO_INIT);
int myRank = omp_get_thread_num();
VectorOfFixVecs<DimVec<double> > &Lb = tmpLb[myRank];
Lb.resize(nPoints);
for (int iq = 0; iq < nPoints; iq++) {
Lb[iq].set(0.0);
......@@ -467,45 +511,6 @@ namespace AMDiS {
}
}
void Quad10::calculateElementVector(const ElInfo *elInfo, ElementVector *vec)
{
VectorOfFixVecs<DimVec<double> > *grdPsi;
if (firstCall) {
#ifdef _OPENMP
#pragma omp critical
#endif
{
const BasisFunction *basFcts = owner->getRowFESpace()->getBasisFcts();
psiFast = updateFastQuadrature(psiFast, basFcts, INIT_GRD_PHI);
basFcts = owner->getColFESpace()->getBasisFcts();
phiFast = updateFastQuadrature(phiFast, basFcts, INIT_PHI);
firstCall = false;
}
}
int nPoints = quadrature->getNumPoints();
VectorOfFixVecs<DimVec<double> > Lb(dim,nPoints,NO_INIT);
int myRank = omp_get_thread_num();
for (int iq = 0; iq < nPoints; iq++) {
Lb[iq].set(0.0);
}
for (int i = 0; i < static_cast<int>(terms[myRank].size()); i++) {
(static_cast<FirstOrderTerm*>((terms[myRank][i])))->getLb(elInfo, nPoints, Lb);
}
for (int iq = 0; iq < nPoints; iq++) {
Lb[iq] *= elInfo->getDet();
grdPsi = psiFast->getGradient(iq);
for (int i = 0; i < nRow; i++) {
(*vec)[i] += quadrature->getWeight(iq) * (Lb[iq] * (*grdPsi)[i]);
}
}
}
Pre01::Pre01(Operator *op, Assembler *assembler, Quadrature *quad)
: FirstOrderAssembler(op, assembler, quad, true, GRD_PHI)
{
......@@ -513,8 +518,6 @@ namespace AMDiS {
void Pre01::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat)
{
VectorOfFixVecs<DimVec<double> > Lb(dim,1,NO_INIT);
const int *l;
const double *values;
......@@ -534,6 +537,8 @@ namespace AMDiS {
const int **nEntries = q01->getNumberEntries();
int myRank = omp_get_thread_num();
// Do not need to resize Lb, because it's size is always at least one!
VectorOfFixVecs<DimVec<double> > &Lb = tmpLb[myRank];
Lb[0].set(0.0);
for (int i = 0; i < static_cast<int>( terms[myRank].size()); i++) {
......@@ -557,8 +562,6 @@ namespace AMDiS {
void Pre10::calculateElementVector(const ElInfo *elInfo, ElementVector *vec)
{
VectorOfFixVecs<DimVec<double> > Lb(dim,1,NO_INIT);
const int *k;
const double *values;
......@@ -578,6 +581,8 @@ namespace AMDiS {
const int *nEntries = q1->getNumberEntries();
int myRank = omp_get_thread_num();
// Do not need to resize Lb, because it's size is always at least one!
VectorOfFixVecs<DimVec<double> > &Lb = tmpLb[myRank];
Lb[0].set(0.0);
for (int i = 0; i < static_cast<int>(terms[myRank].size()); i++) {
......
......@@ -46,6 +46,12 @@ namespace AMDiS {
protected:
/** \brief
* Thread safe temporary vector of DimMats for calculation in
* function calculateElementMatrix().
*/
std::vector<VectorOfFixVecs<DimVec<double> > > tmpLb;
/// List of all yet created optimized zero order assemblers for grdPsi.
static std::vector<SubAssembler*> optimizedSubAssemblersGrdPsi;
......@@ -71,7 +77,7 @@ namespace AMDiS {
public:
MEMORY_MANAGED(Stand10);
/// Constructor.
/// Constructor
Stand10(Operator *op, Assembler *assembler, Quadrature *quad);
/// Implements SubAssembler::calculateElementMatrix().
......
......@@ -108,33 +108,23 @@ namespace AMDiS {
this->set(ini);
}
/** \brief
* Initialisation for dim.
*/
inline void init(int dim)
{
/// Initialisation for dim.
inline void init(int dim) {
this->resize(calcSize(dim));
}
/** \brief
* Initialisation for size
*/
inline void initSize(int size)
{
/// Initialisation for size
inline void initSize(int size) {
this->resize(size);
}
/** \brief
* Returns the \ref size_ of the FixVec.
*/
/// Returns the \ref size_ of the FixVec.
inline int size() const {
return this->getSize();
}
protected:
/** \brief
* Determines needed vector size.
*/
/// Determines needed vector size.
static int calcSize(int dim) {
if (dim < 0) {
return Global::getGeo(WORLD);
......@@ -172,15 +162,15 @@ namespace AMDiS {
* FixVec's constructors. size_ is the number of contained FixVecs. initType
* must be NO_INIT.
*/
VectorOfFixVecs(int dim, int size, InitType initType)
: size_(size)
VectorOfFixVecs(int d, int s, InitType initType)
: size(s),
dim(d)
{
TEST_EXIT_DBG(initType == NO_INIT)("wrong initType or wrong initializer\n");
vec = GET_MEMORY(FixVecType*, size_);
for (FixVecType** i = &vec[0]; i < &vec[size_]; i++) {
*i = NEW FixVecType(dim, NO_INIT);
}
vec.resize(size);
for (int i = 0; i < size; i++)
vec[i] = NEW FixVecType(dim, NO_INIT);
}
/** \brief
......@@ -188,15 +178,15 @@ namespace AMDiS {
* FixVec's constructors. size_ is the number of contained FixVecs. initType
* must be VALUE_LIST. ini contains the initialisation values.
*/
VectorOfFixVecs(int dim, int s, InitType initType, const FixVecType* ini)
: size_(s)
VectorOfFixVecs(int d, int s, InitType initType, const FixVecType* ini)
: size(s),
dim(d)
{
TEST_EXIT_DBG(initType == VALUE_LIST)("wrong initType or wrong initializer\n");
vec = GET_MEMORY(FixVecType*, size_);
for (FixVecType** i = &vec[0]; i < &vec[size_]; i++) {
*i = NEW FixVecType(ini[i]);
}
vec.resize(size);
for (int i = 0; i < size; i++)
vec[i] = NEW FixVecType(ini[i]);
}
/** \brief
......@@ -204,100 +194,96 @@ namespace AMDiS {
* FixVec's constructors. size_ is the number of contained FixVecs. initType
* must be DEFAULT_VALUE. All entries are set to ini.
*/
VectorOfFixVecs(int /*dim*/, int s, InitType initType, const FixVecType& ini)
: size_(s)
VectorOfFixVecs(int d, int s, InitType initType, const FixVecType& ini)
: size(s),
dim(d)
{
TEST_EXIT_DBG(initType == DEFAULT_VALUE)
("wrong initType or wrong initializer\n");
vec = GET_MEMORY(FixVecType*, size_);
for (FixVecType** i = &vec[0]; i < &vec[size_]; i++) {
*i = NEW FixVecType(ini);
}
TEST_EXIT_DBG(initType == DEFAULT_VALUE)("wrong initType or wrong initializer\n");
vec.resize(size);
for (int i = 0; i < size; i++)
vec[i] = NEW FixVecType(ini);
}
/** \brief
* copy constructor
*/
/// Copy constructor
VectorOfFixVecs(const VectorOfFixVecs<FixVecType>& rhs)
{
size_ = rhs.getSize();
vec = GET_MEMORY(FixVecType*, size_);
size = rhs.getSize();
dim = rhs.getDim();
for (int i = 0; i < size_; i++) {
vec.resize(size);
for (int i = 0; i < size; i++)
vec[i] = NEW FixVecType(*(rhs.vec[i]));
}
};
}
/** \brief
* destructor
*/
/// Destructor
virtual ~VectorOfFixVecs()
{
for (FixVecType** i = &vec[0]; i<&vec[size_]; i++) {
DELETE *i;
}
FREE_MEMORY(vec, FixVecType*, size_);
//delete [] vec;
};
for (int i = 0; i < size; i++)
DELETE vec[i];
/** \brief
* Allows the access like in a normal array via []. Used for const objects.
*/
vec.clear();
}
/// Allows the access like in a normal array via []. Used for const objects.
inline const FixVecType& operator[](int index) const
{
TEST_EXIT_DBG(index >= 0 && index < size_)("invalid index\n");
TEST_EXIT_DBG(index >= 0 && index < size)("invalid index\n");
return *(vec[index]);
};
}
/** \brief
* Allows the access like in a normal array via [].
*/
/// Allows the access like in a normal array via [].
inline FixVecType& operator[](int index)
{
TEST_EXIT_DBG(index >= 0 && index < size_)("invalid index\n");
TEST_EXIT_DBG(index >= 0 && index < size)("invalid index\n");
return *(vec[index]);
};
}
/** \brief
* assignment operator
*/
/// Assignment operator
VectorOfFixVecs<FixVecType>&
operator=(const VectorOfFixVecs<FixVecType>& rhs)
{
TEST_EXIT_DBG(size_ == rhs.size_)("vectors of different size\n");
if (this!=&rhs) {
FixVecType **i, **j;
for(i=&vec[0], j=&(rhs.vec[0]); i < &vec[size_]; i++, j++) {
**i = **j;
}
TEST_EXIT_DBG(size == rhs.size)("vectors of different size\n");
if (this != &rhs) {
for (int i = 0; i < size; i++)
*(vec[i]) = *(rhs.vec[i]);
}
return *this;
};
}
/** \brief
* Returns the \ref size of this VectorOfFixVecs
*/
/// Resize the vector
inline void resize(int newsize)
{
vec.resize(newsize);
for (int i = size; i < newsize; i++)
vec[i] = NEW FixVecType(dim, NO_INIT);
size = newsize;
}
/// Returns the \ref size of this VectorOfFixVecs
inline int getSize() const {
return size_;
};
return size;