Commit acf241d9 authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

* Some more optimization stuff

parent 8ff1b66a
...@@ -1100,32 +1100,41 @@ namespace AMDiS { ...@@ -1100,32 +1100,41 @@ namespace AMDiS {
Pre2::Pre2(Operator *op, Assembler *assembler, Quadrature *quad) Pre2::Pre2(Operator *op, Assembler *assembler, Quadrature *quad)
: SecondOrderAssembler(op, assembler, quad, true) : SecondOrderAssembler(op, assembler, quad, true)
{} {
q11 = Q11PsiPhi::provideQ11PsiPhi(owner->getRowFESpace()->getBasisFcts(),
owner->getColFESpace()->getBasisFcts(),
quadrature);
tmpLALt.resize(omp_get_max_threads());
for (int i = 0; i < omp_get_max_threads(); i++) {
tmpLALt[i] = NEW DimMat<double>*;
*(tmpLALt[i]) = NEW DimMat<double>(dim, NO_INIT);
}
}
Pre2::~Pre2()
{
for (int i = 0; i < static_cast<int>(tmpLALt.size()); i++) {
DELETE *(tmpLALt[i]);
DELETE tmpLALt[i];
}
}
void Pre2::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat) void Pre2::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat)
{ {
DimMat<double> **LALt = NEW DimMat<double>*;
*LALt=NEW DimMat<double>(dim, NO_INIT);
const int **nEntries; const int **nEntries;
const int *k, *l; const int *k, *l;
const double *values; const double *values;
double val;
if (firstCall) {
q11 = Q11PsiPhi::provideQ11PsiPhi(owner->getRowFESpace()->getBasisFcts(),
owner->getColFESpace()->getBasisFcts(),
quadrature);
firstCall = false;
}
LALt[0]->set(0.0);
int myRank = omp_get_thread_num(); int myRank = omp_get_thread_num();
DimMat<double> **LALt = tmpLALt[myRank];
DimMat<double> &tmpMat = *LALt[0];
tmpMat.set(0.0);
for (int i = 0; i < static_cast<int>( terms[myRank].size()); i++) { for (int i = 0; i < static_cast<int>( terms[myRank].size()); i++) {
(static_cast<SecondOrderTerm*>(terms[myRank][i]))->getLALt(elInfo, 1, LALt); (static_cast<SecondOrderTerm*>(terms[myRank][i]))->getLALt(elInfo, 1, LALt);
} }
(*LALt[0]) *= elInfo->getDet(); tmpMat *= elInfo->getDet();
nEntries = q11->getNumberEntries(); nEntries = q11->getNumberEntries();
...@@ -1134,9 +1143,9 @@ namespace AMDiS { ...@@ -1134,9 +1143,9 @@ namespace AMDiS {
k = q11->getKVec(i, i); k = q11->getKVec(i, i);
l = q11->getLVec(i, i); l = q11->getLVec(i, i);
values = q11->getValVec(i, i); values = q11->getValVec(i, i);
val = 0.0; double val = 0.0;
for (int m = 0; m < nEntries[i][i]; m++) { for (int m = 0; m < nEntries[i][i]; m++) {
val += values[m] * (*LALt[0])[k[m]][l[m]]; val += values[m] * tmpMat[k[m]][l[m]];
} }
(*mat)[i][i] += val; (*mat)[i][i] += val;
...@@ -1146,7 +1155,7 @@ namespace AMDiS { ...@@ -1146,7 +1155,7 @@ namespace AMDiS {
values = q11->getValVec(i, j); values = q11->getValVec(i, j);
val = 0.0; val = 0.0;
for (int m = 0; m < nEntries[i][j]; m++) { for (int m = 0; m < nEntries[i][j]; m++) {
val += values[m] * (*LALt[0])[k[m]][l[m]]; val += values[m] * tmpMat[k[m]][l[m]];
} }
(*mat)[i][j] += val; (*mat)[i][j] += val;
(*mat)[j][i] += val; (*mat)[j][i] += val;
...@@ -1158,17 +1167,14 @@ namespace AMDiS { ...@@ -1158,17 +1167,14 @@ namespace AMDiS {
k = q11->getKVec(i, j); k = q11->getKVec(i, j);
l = q11->getLVec(i, j); l = q11->getLVec(i, j);
values = q11->getValVec(i, j); values = q11->getValVec(i, j);
val = 0.0; double val = 0.0;
for (int m = 0; m < nEntries[i][j]; m++) { for (int m = 0; m < nEntries[i][j]; m++) {
val += values[m] * (*LALt[0])[k[m]][l[m]]; val += values[m] * tmpMat[k[m]][l[m]];
} }
(*mat)[i][j] += val; (*mat)[i][j] += val;
} }
} }
} }
DELETE *LALt;
DELETE LALt;
} }
Quad2::Quad2(Operator *op, Assembler *assembler, Quadrature *quad) Quad2::Quad2(Operator *op, Assembler *assembler, Quadrature *quad)
......
...@@ -859,6 +859,11 @@ namespace AMDiS { ...@@ -859,6 +859,11 @@ namespace AMDiS {
*/ */
Pre2(Operator *op, Assembler *assembler, Quadrature *quad); Pre2(Operator *op, Assembler *assembler, Quadrature *quad);
/** \brief
* Destructor.
*/
~Pre2();
/** \brief /** \brief
* Implements SubAssembler::calculateElementMatrix(). * Implements SubAssembler::calculateElementMatrix().
*/ */
...@@ -867,7 +872,7 @@ namespace AMDiS { ...@@ -867,7 +872,7 @@ namespace AMDiS {
/** \brief /** \brief
* Implements SubAssembler::calculateElementVector(). * Implements SubAssembler::calculateElementVector().
*/ */
void calculateElementVector(const ElInfo *, ElementVector */*vec*/) { void calculateElementVector(const ElInfo *, ElementVector *) {
ERROR_EXIT("should not be called\n"); ERROR_EXIT("should not be called\n");
}; };
...@@ -878,6 +883,11 @@ namespace AMDiS { ...@@ -878,6 +883,11 @@ namespace AMDiS {
*/ */
const Q11PsiPhi *q11; const Q11PsiPhi *q11;
/** \brief
* Thread safe temporary vector of DimMats for calculation in calculateElementMatrix().
*/
::std::vector< DimMat<double>** > tmpLALt;
friend class SecondOrderAssembler; friend class SecondOrderAssembler;
}; };
......
...@@ -298,33 +298,33 @@ namespace AMDiS { ...@@ -298,33 +298,33 @@ namespace AMDiS {
if (j!=static_cast<int>(matrix[a].size())) matrix[a][j].col=c; if (j!=static_cast<int>(matrix[a].size())) matrix[a][j].col=c;
} }
double *DOFMatrix::addSparseDOFEntry(double sign, int irow, void DOFMatrix::addSparseDOFEntry(double sign, int irow,
int jcol, double entry, int jcol, double entry,
bool add) bool add)
{ {
FUNCNAME("DOFMatrix::addSparseDOFEntry()"); FUNCNAME("DOFMatrix::addSparseDOFEntry()");
MatrixRow *row = &(matrix[irow]); MatrixRow *row = &(matrix[irow]);
if (add && !entry) if (add && !entry)
return NULL; return;
double *result = NULL;
int i, freeCol = -1, rowSize = static_cast<int>( row->size()); int freeCol = -1;
int rowSize = static_cast<int>( row->size());
TEST_EXIT_DBG(jcol >= 0 && TEST_EXIT_DBG(jcol >= 0 &&
jcol < colFESpace->getAdmin()->getUsedSize()) jcol < colFESpace->getAdmin()->getUsedSize())
("Column index %d out of range 0-%d\n", jcol, colFESpace->getAdmin()->getUsedSize() - 1); ("Column index %d out of range 0-%d\n", jcol, colFESpace->getAdmin()->getUsedSize() - 1);
// first entry is diagonal entry // first entry is diagonal entry
if (rowFESpace==colFESpace) if (rowFESpace == colFESpace)
if (rowSize == 0) { if (rowSize == 0) {
MatEntry newEntry = {irow, 0.0}; MatEntry newEntry = {irow, 0.0};
row->push_back(newEntry); row->push_back(newEntry);
rowSize = 1; rowSize = 1;
} }
int i;
// search jcol // search jcol
for (i = 0; i < rowSize; i++) { for (i = 0; i < rowSize; i++) {
// jcol found ? // jcol found ?
...@@ -350,22 +350,17 @@ namespace AMDiS { ...@@ -350,22 +350,17 @@ namespace AMDiS {
if (!add) if (!add)
(*row)[i].entry = 0.0; (*row)[i].entry = 0.0;
(*row)[i].entry += sign * entry; (*row)[i].entry += sign * entry;
result = &((*row)[i].entry);
} else { } else {
if(freeCol == -1) { if (freeCol == -1) {
MatEntry newEntry = {jcol, sign * entry}; MatEntry newEntry = {jcol, sign * entry};
row->push_back(newEntry); row->push_back(newEntry);
result = &((*row)[row->size() - 1].entry);
} else { } else {
(*row)[freeCol].col = jcol; (*row)[freeCol].col = jcol;
if (!add) if (!add)
(*row)[freeCol].entry = 0.0; (*row)[freeCol].entry = 0.0;
(*row)[freeCol].entry += sign * entry; (*row)[freeCol].entry += sign * entry;
result = &((*row)[freeCol].entry);
} }
} }
return result;
} }
void DOFMatrix::addMatEntry(int row, MatEntry entry) void DOFMatrix::addMatEntry(int row, MatEntry entry)
...@@ -527,7 +522,7 @@ namespace AMDiS { ...@@ -527,7 +522,7 @@ namespace AMDiS {
entry += a[rowIndex][j].entry * b[logIndex][physIndex].entry; entry += a[rowIndex][j].entry * b[logIndex][physIndex].entry;
} }
} }
if(entry != 0.0) { if (entry != 0.0) {
addSparseDOFEntry(1.0, rowIndex, i, entry); addSparseDOFEntry(1.0, rowIndex, i, entry);
} }
} }
...@@ -552,7 +547,7 @@ namespace AMDiS { ...@@ -552,7 +547,7 @@ namespace AMDiS {
double entry = aRowIt->entry * bRowIt->entry; double entry = aRowIt->entry * bRowIt->entry;
if(entry != 0.0) { if (entry != 0.0) {
addSparseDOFEntry(1.0, aCol, bCol, entry); addSparseDOFEntry(1.0, aCol, bCol, entry);
} }
} }
...@@ -592,14 +587,14 @@ namespace AMDiS { ...@@ -592,14 +587,14 @@ namespace AMDiS {
// add x contributions to this row // add x contributions to this row
for(i=0; i < static_cast<int>((*xIterator).size()); i++) { for(i=0; i < static_cast<int>((*xIterator).size()); i++) {
colIndex = (*xIterator)[i].col; colIndex = (*xIterator)[i].col;
if(colIndex >= 0) { if (colIndex >= 0) {
addSparseDOFEntry(a, rowIndex, colIndex, (*xIterator)[i].entry); addSparseDOFEntry(a, rowIndex, colIndex, (*xIterator)[i].entry);
} }
} }
// add y contributions to this row // add y contributions to this row
for(i=0; i < static_cast<int>((*yIterator).size()); i++) { for(i=0; i < static_cast<int>((*yIterator).size()); i++) {
colIndex = (*yIterator)[i].col; colIndex = (*yIterator)[i].col;
if(colIndex >= 0) { if (colIndex >= 0) {
addSparseDOFEntry(1.0, rowIndex, colIndex, (*yIterator)[i].entry); addSparseDOFEntry(1.0, rowIndex, colIndex, (*yIterator)[i].entry);
} }
} }
......
...@@ -515,9 +515,9 @@ namespace AMDiS { ...@@ -515,9 +515,9 @@ namespace AMDiS {
* Creates an entry with logical indices irow, icol if there is no entry * Creates an entry with logical indices irow, icol if there is no entry
* yet. Than sign * entry is added to the value at this logical indices * yet. Than sign * entry is added to the value at this logical indices
*/ */
double *addSparseDOFEntry(double sign, void addSparseDOFEntry(double sign,
int irow, int jcol, double entry, int irow, int jcol, double entry,
bool add = true); bool add = true);
inline double *hasSparseDOFEntry(int irow, int jcol) { inline double *hasSparseDOFEntry(int irow, int jcol) {
::std::vector<MatEntry>::iterator it; ::std::vector<MatEntry>::iterator it;
......
...@@ -178,7 +178,7 @@ namespace AMDiS { ...@@ -178,7 +178,7 @@ namespace AMDiS {
int dim = mesh_->getDim(); int dim = mesh_->getDim();
int posIndex = DIM_OF_INDEX(pos, dim); int posIndex = DIM_OF_INDEX(pos, dim);
int offset = indexOffset[dim - 1][posIndex]; int offset = indexOffset[dim - 1][posIndex];
return boundary_[offset + i]; return boundary_[offset + i];
} }
......
...@@ -190,7 +190,7 @@ namespace AMDiS { ...@@ -190,7 +190,7 @@ namespace AMDiS {
/** \brief /** \brief
* Get ElInfo's \ref boundary_[i] * Get ElInfo's \ref boundary_[i]
*/ */
virtual BoundaryType getBoundary(int i) const { inline BoundaryType getBoundary(int i) const {
return boundary_[i]; return boundary_[i];
}; };
......
...@@ -314,8 +314,6 @@ namespace AMDiS { ...@@ -314,8 +314,6 @@ namespace AMDiS {
double det = 0.0; double det = 0.0;
int myRank = omp_get_thread_num();
WorldVector<double> *e0 = &tmpWorldVecs[0]; WorldVector<double> *e0 = &tmpWorldVecs[0];
WorldVector<double> *e1 = &tmpWorldVecs[1]; WorldVector<double> *e1 = &tmpWorldVecs[1];
WorldVector<double> *e2 = &tmpWorldVecs[2]; WorldVector<double> *e2 = &tmpWorldVecs[2];
...@@ -362,13 +360,10 @@ namespace AMDiS { ...@@ -362,13 +360,10 @@ namespace AMDiS {
const int (*cvg)[4] = NULL; /* cvg = child_vertex[el_type] */ const int (*cvg)[4] = NULL; /* cvg = child_vertex[el_type] */
int *ce; /* ce = child_edge[el_type][ichild] */ int *ce; /* ce = child_edge[el_type][ichild] */
Element *nb, *nbk; Element *nb, *nbk;
const FixVec<Element*, NEIGH> *neigh_old;
Element *el_old = elinfo_old->element_; Element *el_old = elinfo_old->element_;
Flag fillFlag__local = elinfo_old->fillFlag_; Flag fillFlag__local = elinfo_old->fillFlag_;
DegreeOfFreedom *dof; DegreeOfFreedom *dof;
int ov = -1; int ov = -1;
FixVec<Element*, NEIGH> *neigh_local;
Flag fill_opp_coords;
Mesh *mesh = elinfo_old->getMesh(); Mesh *mesh = elinfo_old->getMesh();
TEST_EXIT_DBG(el_old->getChild(0))("missing child?\n"); TEST_EXIT_DBG(el_old->getChild(0))("missing child?\n");
...@@ -378,7 +373,7 @@ namespace AMDiS { ...@@ -378,7 +373,7 @@ namespace AMDiS {
fillFlag_ = fillFlag__local; fillFlag_ = fillFlag__local;
parent_ = el_old; parent_ = el_old;
level_ = elinfo_old->level_ + 1; level_ = elinfo_old->level_ + 1;
int el_type_local = ( dynamic_cast<ElInfo3d*>(const_cast<ElInfo*>( elinfo_old)))->getType(); int el_type_local = (dynamic_cast<const ElInfo3d*>(elinfo_old))->getType();
el_type = (el_type_local + 1) % 3; el_type = (el_type_local + 1) % 3;
TEST_EXIT_DBG(element_)("missing child %d?\n", ichild); TEST_EXIT_DBG(element_)("missing child %d?\n", ichild);
...@@ -409,8 +404,10 @@ namespace AMDiS { ...@@ -409,8 +404,10 @@ namespace AMDiS {
if (fillFlag__local.isSet(Mesh::FILL_NEIGH) || if (fillFlag__local.isSet(Mesh::FILL_NEIGH) ||
fillFlag_.isSet(Mesh::FILL_OPP_COORDS)) { fillFlag_.isSet(Mesh::FILL_OPP_COORDS)) {
neigh_local = &neighbour_; FixVec<Element*, NEIGH> *neigh_local = &neighbour_;
neigh_old = &elinfo_old->neighbour_; const FixVec<Element*, NEIGH> *neigh_old = &elinfo_old->neighbour_;
Flag fill_opp_coords;
fill_opp_coords.setFlags(fillFlag__local & Mesh::FILL_OPP_COORDS); fill_opp_coords.setFlags(fillFlag__local & Mesh::FILL_OPP_COORDS);
/*----- nb[0] is other child --------------------------------------------*/ /*----- nb[0] is other child --------------------------------------------*/
......
...@@ -110,22 +110,21 @@ namespace AMDiS { ...@@ -110,22 +110,21 @@ namespace AMDiS {
/** \brief /** \brief
* Returns \ref child[0] * Returns \ref child[0]
*/ */
virtual Element* getFirstChild() const { inline Element* getFirstChild() const {
return child[0]; return child[0];
}; };
/** \brief /** \brief
* Returns \ref child[1] * Returns \ref child[1]
*/ */
virtual Element* getSecondChild() const { inline Element* getSecondChild() const {
return child[1]; return child[1];
}; };
/** \brief /** \brief
* Returns \ref child[i], i=0,1 * Returns \ref child[i], i=0,1
*/ */
virtual Element* getChild(int i) const { inline Element* getChild(int i) const {
FUNCNAME("Element::getChild()");
TEST_EXIT_DBG(i==0 || i==1)("i must be 0 or 1\n"); TEST_EXIT_DBG(i==0 || i==1)("i must be 0 or 1\n");
return child[i]; return child[i];
}; };
......
...@@ -790,26 +790,23 @@ namespace AMDiS { ...@@ -790,26 +790,23 @@ namespace AMDiS {
el_info->testFlag(Mesh::FILL_BOUND); el_info->testFlag(Mesh::FILL_BOUND);
DimVec<int> parts(dim, NO_INIT);
for (int i = 0; i < dim + 1; i++)
parts[i] = Global::getGeo(INDEX_OF_DIM(i, dim), dim);
int index = 0;
// boundaries // boundaries
int index = 0;
int offset = 0; int offset = 0;
BoundaryType boundaryType; BoundaryType boundaryType;
for (int i = dim - 1; i > 0; i--) for (int i = dim - 1; i > 0; i--)
offset += parts[i]; offset += Global::getGeo(INDEX_OF_DIM(i, dim), dim);
for (int i = 0; i < dim; i++) { for (int i = 0; i < dim; i++) {
for (int j = offset; j < offset + parts[i]; j++) { int jto = offset + Global::getGeo(INDEX_OF_DIM(i, dim), dim);
for (int j = offset; j < jto; j++) {
boundaryType = el_info->getBoundary(j); boundaryType = el_info->getBoundary(j);
for (int k = 0; k < (*nDOF)[INDEX_OF_DIM(i, dim)]; k++) { int kto = (*nDOF)[INDEX_OF_DIM(i, dim)];
for (int k = 0; k < kto; k++) {
result[index++] = boundaryType; result[index++] = boundaryType;
} }
} }
offset -= parts[i+1]; offset -= Global::getGeo(INDEX_OF_DIM(i + 1, dim), dim);
} }
// interior nodes in the center // interior nodes in the center
......
...@@ -96,7 +96,7 @@ namespace AMDiS { ...@@ -96,7 +96,7 @@ namespace AMDiS {
} }
if (res <= tolerance) { if (res <= tolerance) {
INFO(info,6)("finished successfully with %d iterations\n", iter); INFO(info,6)("finished successfully with %d iterations\n");
return(1); return(1);
} }
......
...@@ -122,22 +122,23 @@ namespace AMDiS { ...@@ -122,22 +122,23 @@ namespace AMDiS {
} }
void OperatorTerm::l1lt(const DimVec<WorldVector<double> >& Lambda, void OperatorTerm::l1lt(const DimVec<WorldVector<double> >& Lambda,
DimMat<double>& LALt, DimMat<double>& LALt,
double factor) double factor)
{ {
int i, j, k; static const int dimOfWorld = Global::getGeo(WORLD);
static const int dimOfWorld = Global::getGeo(WORLD); int dim = LALt.getNumRows() - 1;
int dim = LALt.getNumRows() - 1;
double val = 0.0; double val = 0.0;
for (i = 0; i <= dim; i++) { for (int i = 0; i <= dim; i++) {
for (val = k = 0; k < dimOfWorld; k++) val = 0.0;
for (int k = 0; k < dimOfWorld; k++)
val += Lambda[i][k] * Lambda[i][k]; val += Lambda[i][k] * Lambda[i][k];
val *= factor; val *= factor;
LALt[i][i] += val; LALt[i][i] += val;
for (j = i+1; j <= dim; j++) { for (int j = i + 1; j <= dim; j++) {
for (val = k = 0; k < dimOfWorld; k++) val = 0.0;
for (int k = 0; k < dimOfWorld; k++)
val += Lambda[i][k] * Lambda[j][k]; val += Lambda[i][k] * Lambda[j][k];
val *= factor; val *= factor;
LALt[i][j] += val; LALt[i][j] += val;
......
...@@ -209,9 +209,8 @@ namespace AMDiS { ...@@ -209,9 +209,8 @@ namespace AMDiS {
TEST_EXIT_DBG(matrix)("no matrix\n"); TEST_EXIT_DBG(matrix)("no matrix\n");
if (matrix == masterMatrix_) { if (matrix == masterMatrix_) {
const BasisFunction *basFcts = rowFESpace->getBasisFcts(); FREE_MEMORY(neighIndices_, DegreeOfFreedom,
int num = basFcts->getNumber(); rowFESpace->getBasisFcts()->getNumber());
FREE_MEMORY(neighIndices_, DegreeOfFreedom, num);
masterMatrix_ = NULL; masterMatrix_ = NULL;
} }
...@@ -221,13 +220,15 @@ namespace AMDiS { ...@@ -221,13 +220,15 @@ namespace AMDiS {
int row