Commit 561814e2 authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

* This and that

parent 145602ce
...@@ -149,12 +149,12 @@ namespace AMDiS { ...@@ -149,12 +149,12 @@ namespace AMDiS {
DOFVector<WorldVector<double> > *result = grad; DOFVector<WorldVector<double> > *result = grad;
if(!result) { if (!result) {
if(vec && vec->getFESpace() != feSpace) { if (vec && vec->getFESpace() != feSpace) {
DELETE vec; DELETE vec;
vec = NULL; vec = NULL;
} }
if(!vec) { if (!vec) {
vec = NEW DOFVector<WorldVector<double> >(feSpace, "gradient"); vec = NEW DOFVector<WorldVector<double> >(feSpace, "gradient");
} }
result = vec; result = vec;
...@@ -165,36 +165,27 @@ namespace AMDiS { ...@@ -165,36 +165,27 @@ namespace AMDiS {
DOFVector<double> volume(feSpace, "volume"); DOFVector<double> volume(feSpace, "volume");
volume.set(0.0); volume.set(0.0);
Mesh *mesh = feSpace->getMesh();
int dim = mesh->getDim();
const BasisFunction *basFcts = feSpace->getBasisFcts(); const BasisFunction *basFcts = feSpace->getBasisFcts();
int nPreDOFs = feSpace->getAdmin()->getNumberOfPreDOFs(0);
DOFAdmin *admin = feSpace->getAdmin();
int numPreDOFs = admin->getNumberOfPreDOFs(0);
DimVec<double> bary(dim, DEFAULT_VALUE, (1.0 / (dim + 1.0))); DimVec<double> bary(dim, DEFAULT_VALUE, (1.0 / (dim + 1.0)));
WorldVector<double> grd;
// traverse mesh // traverse mesh
Mesh *mesh = feSpace->getMesh();
TraverseStack stack; TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(mesh, -1,
Flag fillFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_DET |
Mesh::CALL_LEAF_EL | Mesh::FILL_DET | Mesh::FILL_GRD_LAMBDA | Mesh::FILL_COORDS; Mesh::FILL_GRD_LAMBDA | Mesh::FILL_COORDS);
ElInfo *elInfo = stack.traverseFirst(mesh, -1, fillFlag);
while (elInfo) { while (elInfo) {
double det = elInfo->getDet(); double det = elInfo->getDet();
const DegreeOfFreedom **dof = elInfo->getElement()->getDOF(); const DegreeOfFreedom **dof = elInfo->getElement()->getDOF();
const double *localUh = getLocalVector(elInfo->getElement(), NULL); const double *localUh = getLocalVector(elInfo->getElement(), NULL);
const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda(); const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda();
WorldVector<double> grd;
basFcts->evalGrdUh(bary, grdLambda, localUh, &grd); basFcts->evalGrdUh(bary, grdLambda, localUh, &grd);
for (int i = 0; i < dim + 1; i++) { for (int i = 0; i < dim + 1; i++) {
DegreeOfFreedom dofIndex = dof[i][numPreDOFs]; DegreeOfFreedom dofIndex = dof[i][nPreDOFs];
(*result)[dofIndex] += grd * det; (*result)[dofIndex] += grd * det;
volume[dofIndex] += det; volume[dofIndex] += det;
} }
...@@ -207,7 +198,7 @@ namespace AMDiS { ...@@ -207,7 +198,7 @@ namespace AMDiS {
for (volIt.reset(), grdIt.reset(); !volIt.end(); ++volIt, ++grdIt) { for (volIt.reset(), grdIt.reset(); !volIt.end(); ++volIt, ++grdIt) {
if (*volIt != 0.0) { if (*volIt != 0.0) {
*grdIt *= 1.0/(*volIt); *grdIt *= 1.0 / (*volIt);
} }
} }
...@@ -232,12 +223,9 @@ namespace AMDiS { ...@@ -232,12 +223,9 @@ namespace AMDiS {
TEST_EXIT_DBG(!quadFast || quadFast->getBasisFunctions() == feSpace->getBasisFcts()) TEST_EXIT_DBG(!quadFast || quadFast->getBasisFunctions() == feSpace->getBasisFcts())
("invalid basis functions"); ("invalid basis functions");
Element *el = elInfo->getElement();
int dim = elInfo->getMesh()->getDim();
int dow = Global::getGeo(WORLD); int dow = Global::getGeo(WORLD);
const Quadrature *quadrature = quadFast ? quadFast->getQuadrature() : quad; int myRank = omp_get_thread_num();
const BasisFunction *basFcts = feSpace->getBasisFcts(); int nPoints = quadFast ? quadFast->getQuadrature()->getNumPoints() : quad->getNumPoints();
int numPoints = quadrature->getNumPoints();
static WorldVector<double> *grd = NULL; static WorldVector<double> *grd = NULL;
WorldVector<double> *result; WorldVector<double> *result;
...@@ -247,22 +235,22 @@ namespace AMDiS { ...@@ -247,22 +235,22 @@ namespace AMDiS {
if (grd) if (grd)
delete [] grd; delete [] grd;
grd = new WorldVector<double>[numPoints]; grd = new WorldVector<double>[nPoints];
for (int i = 0; i < numPoints; i++) { for (int i = 0; i < nPoints; i++) {
grd[i].set(0.0); grd[i].set(0.0);
} }
result = grd; result = grd;
} }
double *localVec = new double[nBasFcts]; double *localVec = localVectors[myRank];
getLocalVector(el, localVec); getLocalVector(elInfo->getElement(), localVec);
DimVec<double> grd1(dim, NO_INIT); DimVec<double> &grd1 = *grdTmp[myRank];
int parts = Global::getGeo(PARTS, dim); int parts = Global::getGeo(PARTS, dim);
const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda(); const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda();
if (quadFast) { if (quadFast) {
for (int i = 0; i < numPoints; i++) { for (int i = 0; i < nPoints; i++) {
for (int j = 0; j < dim + 1; j++) { for (int j = 0; j < dim + 1; j++) {
grd1[j] = 0.0; grd1[j] = 0.0;
} }
...@@ -281,10 +269,10 @@ namespace AMDiS { ...@@ -281,10 +269,10 @@ namespace AMDiS {
} }
} }
} else { } else {
// DimVec<double> grdPhi(dim, DEFAULT_VALUE, 0.0); const BasisFunction *basFcts = feSpace->getBasisFcts();
DimVec<double>* grdPhi = grdPhis[omp_get_thread_num()]; DimVec<double>* grdPhi = grdPhis[myRank];
for (int i = 0; i < numPoints; i++) { for (int i = 0; i < nPoints; i++) {
for (int j = 0; j < dim + 1; j++) { for (int j = 0; j < dim + 1; j++) {
grd1[j] = 0.0; grd1[j] = 0.0;
} }
...@@ -305,8 +293,6 @@ namespace AMDiS { ...@@ -305,8 +293,6 @@ namespace AMDiS {
} }
} }
delete [] localVec;
return const_cast<const WorldVector<double>*>(result); return const_cast<const WorldVector<double>*>(result);
} }
...@@ -330,31 +316,25 @@ namespace AMDiS { ...@@ -330,31 +316,25 @@ namespace AMDiS {
Element *el = elInfo->getElement(); Element *el = elInfo->getElement();
int dim = elInfo->getMesh()->getDim(); int myRank = omp_get_thread_num();
int dow = Global::getGeo(WORLD); int dow = Global::getGeo(WORLD);
int nPoints = quadFast ? quadFast->getQuadrature()->getNumPoints() : quad->getNumPoints();
const Quadrature *quadrature = quadFast ? quadFast->getQuadrature() : quad;
const BasisFunction *basFcts = feSpace->getBasisFcts();
int numPoints = quadrature->getNumPoints();
int i, j, k, l, iq;
static WorldMatrix<double> *vec = NULL; static WorldMatrix<double> *vec = NULL;
WorldMatrix<double> *result; WorldMatrix<double> *result;
if (d2AtQPs) { if (d2AtQPs) {
result = d2AtQPs; result = d2AtQPs;
} else { } else {
if(vec) delete [] vec; if(vec) delete [] vec;
vec = new WorldMatrix<double>[numPoints]; vec = new WorldMatrix<double>[nPoints];
for(i = 0; i < numPoints; i++) { for (int i = 0; i < nPoints; i++) {
vec[i].set(0.0); vec[i].set(0.0);
} }
result = vec; result = vec;
} }
double *localVec = new double[nBasFcts]; double *localVec = localVectors[myRank];
getLocalVector(el, localVec); getLocalVector(el, localVec);
DimMat<double> D2Tmp(dim, DEFAULT_VALUE, 0.0); DimMat<double> D2Tmp(dim, DEFAULT_VALUE, 0.0);
...@@ -362,56 +342,53 @@ namespace AMDiS { ...@@ -362,56 +342,53 @@ namespace AMDiS {
const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda(); const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda();
if (quadFast) { if (quadFast) {
for (iq = 0; iq < numPoints; iq++) { for (int iq = 0; iq < nPoints; iq++) {
for (k = 0; k < parts; k++) for (int k = 0; k < parts; k++)
for (l = 0; l < parts; l++) for (int l = 0; l < parts; l++)
D2Tmp[k][l] = 0.0; D2Tmp[k][l] = 0.0;
for (i = 0; i < nBasFcts; i++) { for (int i = 0; i < nBasFcts; i++) {
for (k = 0; k < parts; k++) for (int k = 0; k < parts; k++)
for (l = 0; l < parts; l++) for (int l = 0; l < parts; l++)
D2Tmp[k][l] += localVec[i]* quadFast->getSecDer(iq, i, k, l); D2Tmp[k][l] += localVec[i] * quadFast->getSecDer(iq, i, k, l);
} }
for (i = 0; i < dow; i++) for (int i = 0; i < dow; i++)
for (j = 0; j < dow; j++) { for (int j = 0; j < dow; j++) {
result[iq][i][j] = 0.0; result[iq][i][j] = 0.0;
for (k = 0; k < parts; k++) for (int k = 0; k < parts; k++)
for (l = 0; l < parts; l++) for (int l = 0; l < parts; l++)
result[iq][i][j] += grdLambda[k][i]*grdLambda[l][j]*D2Tmp[k][l]; result[iq][i][j] += grdLambda[k][i]*grdLambda[l][j]*D2Tmp[k][l];
} }
} }
} else { } else {
// DimMat<double> D2Phi(dim, NO_INIT); const BasisFunction *basFcts = feSpace->getBasisFcts();
DimMat<double>* D2Phi = D2Phis[omp_get_thread_num()]; DimMat<double>* D2Phi = D2Phis[omp_get_thread_num()];
for (iq = 0; iq < numPoints; iq++) { for (int iq = 0; iq < nPoints; iq++) {
for (k = 0; k < parts; k++) for (int k = 0; k < parts; k++)
for (l = 0; l < parts; l++) for (int l = 0; l < parts; l++)
D2Tmp[k][l] = 0.0; D2Tmp[k][l] = 0.0;
for (i = 0; i < nBasFcts; i++) { for (int i = 0; i < nBasFcts; i++) {
WARNING("not tested after index correction\n"); WARNING("not tested after index correction\n");
(*(basFcts->getD2Phi(i)))(quad->getLambda(iq), *D2Phi); (*(basFcts->getD2Phi(i)))(quad->getLambda(iq), *D2Phi);
for (k = 0; k < parts; k++) for (int k = 0; k < parts; k++)
for (l = 0; l < parts; l++) for (int l = 0; l < parts; l++)
D2Tmp[k][l] += localVec[i] * (*D2Phi)[k][l]; D2Tmp[k][l] += localVec[i] * (*D2Phi)[k][l];
} }
for (i = 0; i < dow; i++) for (int i = 0; i < dow; i++)
for (j = 0; j < dow; j++) { for (int j = 0; j < dow; j++) {
result[iq][i][j] = 0.0; result[iq][i][j] = 0.0;
for (k = 0; k < parts; k++) for (int k = 0; k < parts; k++)
for (l = 0; l < parts; l++) for (int l = 0; l < parts; l++)
result[iq][i][j] += grdLambda[k][i] * grdLambda[l][j] * D2Tmp[k][l]; result[iq][i][j] += grdLambda[k][i] * grdLambda[l][j] * D2Tmp[k][l];
} }
} }
} }
delete [] localVec;
return const_cast<const WorldMatrix<double>*>(result); return const_cast<const WorldMatrix<double>*>(result);
} }
......
...@@ -231,6 +231,17 @@ namespace AMDiS { ...@@ -231,6 +231,17 @@ namespace AMDiS {
*/ */
std::vector<DegreeOfFreedom*> localIndices; std::vector<DegreeOfFreedom*> localIndices;
/** \brief
* Are used to store temporary local values of an element.
* Thread safe.
*/
std::vector<T*> localVectors;
/** \brief
* Temporarly used in \ref getGrdAtQPs. Thread safe.
*/
std::vector<DimVec<double>*> grdTmp;
/** \brief /** \brief
* Temporarly used in \ref getGrdAtQPs. Thread safe. * Temporarly used in \ref getGrdAtQPs. Thread safe.
*/ */
...@@ -240,6 +251,11 @@ namespace AMDiS { ...@@ -240,6 +251,11 @@ namespace AMDiS {
* Temporarly used in \ref getD2AtQPs. Thread safe. * Temporarly used in \ref getD2AtQPs. Thread safe.
*/ */
std::vector<DimMat<double>*> D2Phis; std::vector<DimMat<double>*> D2Phis;
/** \brief
* Dimension of the mesh this DOFVectorBase belongs to
*/
int dim;
}; };
......
...@@ -29,15 +29,19 @@ namespace AMDiS { ...@@ -29,15 +29,19 @@ namespace AMDiS {
boundaryManager(NULL) boundaryManager(NULL)
{ {
nBasFcts = feSpace->getBasisFcts()->getNumber(); nBasFcts = feSpace->getBasisFcts()->getNumber();
int dim = feSpace->getMesh()->getDim(); dim = feSpace->getMesh()->getDim();
localIndices.resize(omp_get_overall_max_threads()); localIndices.resize(omp_get_overall_max_threads());
localVectors.resize(omp_get_overall_max_threads());
grdPhis.resize(omp_get_overall_max_threads()); grdPhis.resize(omp_get_overall_max_threads());
grdTmp.resize(omp_get_overall_max_threads());
D2Phis.resize(omp_get_overall_max_threads()); D2Phis.resize(omp_get_overall_max_threads());
for (int i = 0; i < omp_get_overall_max_threads(); i++) { for (int i = 0; i < omp_get_overall_max_threads(); i++) {
localIndices[i] = GET_MEMORY(DegreeOfFreedom, this->nBasFcts); localIndices[i] = GET_MEMORY(DegreeOfFreedom, this->nBasFcts);
localVectors[i] = GET_MEMORY(T, this->nBasFcts);
grdPhis[i] = NEW DimVec<double>(dim, DEFAULT_VALUE, 0.0); grdPhis[i] = NEW DimVec<double>(dim, DEFAULT_VALUE, 0.0);
grdTmp[i] = NEW DimVec<double>(dim, DEFAULT_VALUE, 0.0);
D2Phis[i] = NEW DimMat<double>(dim, NO_INIT); D2Phis[i] = NEW DimMat<double>(dim, NO_INIT);
} }
} }
...@@ -47,7 +51,9 @@ namespace AMDiS { ...@@ -47,7 +51,9 @@ namespace AMDiS {
{ {
for (int i = 0; i < static_cast<int>(localIndices.size()); i++) { for (int i = 0; i < static_cast<int>(localIndices.size()); i++) {
FREE_MEMORY(localIndices[i], DegreeOfFreedom, this->nBasFcts); FREE_MEMORY(localIndices[i], DegreeOfFreedom, this->nBasFcts);
FREE_MEMORY(localVectors[i], T, this->nBasFcts);
DELETE grdPhis[i]; DELETE grdPhis[i];
DELETE grdTmp[i];
DELETE D2Phis[i]; DELETE D2Phis[i];
} }
} }
...@@ -540,26 +546,19 @@ namespace AMDiS { ...@@ -540,26 +546,19 @@ namespace AMDiS {
return 0; return 0;
} }
// das hat Andreas eingefuegt: Integral...
template<typename T> template<typename T>
double DOFVector<T>::Int(Quadrature* q) const double DOFVector<T>::Int(Quadrature* q) const
{ {
FUNCNAME("DOFVector::Int"); FUNCNAME("DOFVector::Int()");
Mesh* mesh = feSpace->getMesh(); Mesh* mesh = feSpace->getMesh();
int deg; if (!q) {
dim = mesh->getDim(); int deg = 2 * feSpace->getBasisFcts()->getDegree();
q = Quadrature::provideQuadrature(this->dim, deg);
if (!q)
{
deg = 2*feSpace->getBasisFcts()->getDegree();
q = Quadrature::provideQuadrature(dim, deg);
} }
quad_fast = FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(), *q, INIT_PHI); quad_fast = FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(), *q, INIT_PHI);
norm = 0.0; norm = 0.0;
traverseVector = const_cast<DOFVector<T>*>(this); traverseVector = const_cast<DOFVector<T>*>(this);
...@@ -591,28 +590,20 @@ namespace AMDiS { ...@@ -591,28 +590,20 @@ namespace AMDiS {
return 0; return 0;
} }
// ... und die L1-Norm ...
template<typename T> template<typename T>
double DOFVector<T>::L1Norm(Quadrature* q) const double DOFVector<T>::L1Norm(Quadrature* q) const
{ {
FUNCNAME("DOFVector::L1Norm"); FUNCNAME("DOFVector::L1Norm()");
Mesh* mesh = feSpace->getMesh(); if (!q) {
int deg = 2 * feSpace->getBasisFcts()->getDegree();
int deg; q = Quadrature::provideQuadrature(this->dim, deg);
dim = mesh->getDim();
if (!q)
{
deg = 2*feSpace->getBasisFcts()->getDegree();
q = Quadrature::provideQuadrature(dim, deg);
} }
quad_fast = FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(),*q,INIT_PHI); quad_fast = FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(),*q,INIT_PHI);
norm = 0.0; norm = 0.0;
traverseVector = const_cast<DOFVector<T>*>(this); traverseVector = const_cast<DOFVector<T>*>(this);
Mesh* mesh = feSpace->getMesh();
mesh->traverse(-1, mesh->traverse(-1,
Mesh::CALL_LEAF_EL| Mesh::CALL_LEAF_EL|
...@@ -643,22 +634,14 @@ namespace AMDiS { ...@@ -643,22 +634,14 @@ namespace AMDiS {
} }
// bis hierhin gehen Andreas Ergaenzungen...
template<typename T> template<typename T>
double DOFVector<T>::L2NormSquare(Quadrature* q) const double DOFVector<T>::L2NormSquare(Quadrature* q) const
{ {
FUNCNAME("DOFVector::L2NormSquare"); FUNCNAME("DOFVector::L2NormSquare()");
Mesh* mesh = feSpace->getMesh();
int deg;
dim = mesh->getDim();
if (!q) if (!q) {
{ int deg = 2 * feSpace->getBasisFcts()->getDegree();
deg = 2*feSpace->getBasisFcts()->getDegree(); q = Quadrature::provideQuadrature(this->dim, deg);
q = Quadrature::provideQuadrature(dim, deg);
} }
quad_fast = FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(), quad_fast = FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(),
...@@ -667,8 +650,8 @@ namespace AMDiS { ...@@ -667,8 +650,8 @@ namespace AMDiS {
norm = 0.0; norm = 0.0;
traverseVector = const_cast<DOFVector<T>*>(this); traverseVector = const_cast<DOFVector<T>*>(this);
Mesh* mesh = feSpace->getMesh();
mesh->traverse(-1, Mesh::CALL_LEAF_EL|Mesh::FILL_COORDS|Mesh::FILL_DET, L2Norm_fct); mesh->traverse(-1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET, L2Norm_fct);
return norm; return norm;
} }
...@@ -722,24 +705,19 @@ namespace AMDiS { ...@@ -722,24 +705,19 @@ namespace AMDiS {
template<typename T> template<typename T>
double DOFVector<T>::H1NormSquare(Quadrature *q) const double DOFVector<T>::H1NormSquare(Quadrature *q) const
{ {
FUNCNAME("DOFVector::H1NormSquare"); FUNCNAME("DOFVector::H1NormSquare()");
int deg;
Mesh *mesh = feSpace->getMesh(); if (!q) {
dim = mesh->getDim(); int deg = 2 * feSpace->getBasisFcts()->getDegree() - 2;
q = Quadrature::provideQuadrature(this->dim, deg);
if (!q)
{
deg = 2*feSpace->getBasisFcts()->getDegree()-2;
q = Quadrature::provideQuadrature(dim, deg);
} }
quad_fast =
FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(), quad_fast = FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(),
*q, *q, INIT_GRD_PHI);
INIT_GRD_PHI);
norm = 0.0; norm = 0.0;
traverseVector = const_cast<DOFVector<T>*>(this); traverseVector = const_cast<DOFVector<T>*>(this);
Mesh *mesh = feSpace->getMesh();
mesh->traverse(-1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | mesh->traverse(-1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS |
Mesh::FILL_DET | Mesh::FILL_GRD_LAMBDA, Mesh::FILL_DET | Mesh::FILL_GRD_LAMBDA,
...@@ -752,10 +730,9 @@ namespace AMDiS { ...@@ -752,10 +730,9 @@ namespace AMDiS {
void DOFVector<T>::compressDOFIndexed(int first, int last,