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

Generic reimplementation of getVectorAtQPs().

parent d5e25a2a
......@@ -107,8 +107,8 @@ namespace AMDiS {
{
name = "standard first order assembler";
psi = owner->getRowFeSpace()->getBasisFcts();
phi = owner->getColFeSpace()->getBasisFcts();
psi = rowFeSpace->getBasisFcts();
phi = colFeSpace->getBasisFcts();
}
......@@ -182,9 +182,9 @@ namespace AMDiS {
#pragma omp critical
#endif
{
const BasisFunction *basFcts = owner->getRowFeSpace()->getBasisFcts();
const BasisFunction *basFcts = rowFeSpace->getBasisFcts();
psiFast = updateFastQuadrature(psiFast, basFcts, INIT_GRD_PHI);
basFcts = owner->getColFeSpace()->getBasisFcts();
basFcts = colFeSpace->getBasisFcts();
phiFast = updateFastQuadrature(phiFast, basFcts, INIT_PHI);
firstCall = false;
}
......@@ -225,9 +225,9 @@ namespace AMDiS {
#pragma omp critical
#endif
{
const BasisFunction *basFcts = owner->getRowFeSpace()->getBasisFcts();
const BasisFunction *basFcts = rowFeSpace->getBasisFcts();
psiFast = updateFastQuadrature(psiFast, basFcts, INIT_GRD_PHI);
basFcts = owner->getColFeSpace()->getBasisFcts();
basFcts = colFeSpace->getBasisFcts();
phiFast = updateFastQuadrature(phiFast, basFcts, INIT_PHI);
firstCall = false;
}
......@@ -270,11 +270,10 @@ namespace AMDiS {
#pragma omp critical
#endif
{
q10 = Q10PsiPhi::provideQ10PsiPhi(owner->getRowFeSpace()->getBasisFcts(),
owner->getColFeSpace()->getBasisFcts(),
q10 = Q10PsiPhi::provideQ10PsiPhi(rowFeSpace->getBasisFcts(),
colFeSpace->getBasisFcts(),
quadrature);
q1 = Q1Psi::provideQ1Psi(owner->getRowFeSpace()->getBasisFcts(),
quadrature);
q1 = Q1Psi::provideQ1Psi(rowFeSpace->getBasisFcts(), quadrature);
firstCall = false;
}
}
......@@ -309,8 +308,8 @@ namespace AMDiS {
grdPhi(assembler->getRowFeSpace()->getMesh()->getDim(), nCol, NO_INIT);
tmpGrdPhi.resize(omp_get_overall_max_threads(), grdPhi);
psi = owner->getRowFeSpace()->getBasisFcts();
phi = owner->getColFeSpace()->getBasisFcts();
psi = rowFeSpace->getBasisFcts();
phi = colFeSpace->getBasisFcts();
}
void Stand01::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix& mat)
......@@ -356,9 +355,9 @@ namespace AMDiS {
#pragma omp critical
#endif
{
const BasisFunction *basFcts = owner->getRowFeSpace()->getBasisFcts();
const BasisFunction *basFcts = rowFeSpace->getBasisFcts();
psiFast = updateFastQuadrature(psiFast, basFcts, INIT_PHI);
basFcts = owner->getColFeSpace()->getBasisFcts();
basFcts = colFeSpace->getBasisFcts();
phiFast = updateFastQuadrature(phiFast, basFcts, INIT_GRD_PHI);
firstCall = false;
}
......@@ -406,11 +405,10 @@ namespace AMDiS {
#pragma omp critical
#endif
{
q01 = Q01PsiPhi::provideQ01PsiPhi(owner->getRowFeSpace()->getBasisFcts(),
owner->getColFeSpace()->getBasisFcts(),
q01 = Q01PsiPhi::provideQ01PsiPhi(rowFeSpace->getBasisFcts(),
colFeSpace->getBasisFcts(),
quadrature);
q1 = Q1Psi::provideQ1Psi(owner->getRowFeSpace()->getBasisFcts(),
quadrature);
q1 = Q1Psi::provideQ1Psi(rowFeSpace->getBasisFcts(), quadrature);
firstCall = false;
}
}
......@@ -451,11 +449,10 @@ namespace AMDiS {
#pragma omp critical
#endif
{
q10 = Q10PsiPhi::provideQ10PsiPhi(owner->getRowFeSpace()->getBasisFcts(),
owner->getColFeSpace()->getBasisFcts(),
q10 = Q10PsiPhi::provideQ10PsiPhi(rowFeSpace->getBasisFcts(),
colFeSpace->getBasisFcts(),
quadrature);
q1 = Q1Psi::provideQ1Psi(owner->getRowFeSpace()->getBasisFcts(),
quadrature);
q1 = Q1Psi::provideQ1Psi(rowFeSpace->getBasisFcts(), quadrature);
firstCall = false;
}
}
......@@ -466,9 +463,8 @@ namespace AMDiS {
VectorOfFixVecs<DimVec<double> > &Lb = tmpLb[myRank];
Lb[0].set(0.0);
for (int i = 0; i < static_cast<int>(terms[myRank].size()); i++) {
(static_cast<FirstOrderTerm*>(terms[myRank][i]))->getLb(elInfo, 1, Lb);
}
for (int i = 0; i < static_cast<int>(terms[myRank].size()); i++)
(static_cast<FirstOrderTerm*>(terms[myRank][i]))->getLb(elInfo, 1, Lb);
Lb[0] *= elInfo->getDet();
......
......@@ -833,7 +833,7 @@ namespace AMDiS {
if (no <= 0 || no > getNumber()) {
ERROR("something is wrong, doing nothing\n");
rvec[0] = 0.0;
return(const_cast<const double *>( rvec));
return(const_cast<const double *>(rvec));
}
for (int i = 0; i < no; i++) {
......@@ -857,8 +857,10 @@ namespace AMDiS {
return(const_cast<const double *>( rvec));
}
const WorldVector<double>*
Lagrange::interpol(const ElInfo *el_info, int no,
Lagrange::interpol(const ElInfo *el_info,
int no,
const int *b_no,
AbstractFunction<WorldVector<double>, WorldVector<double> > *f,
WorldVector<double> *vec)
......
......@@ -23,55 +23,6 @@ namespace AMDiS {
}
double *OperatorTerm::getVectorAtQPs(DOFVectorBase<double>* vec,
const ElInfo* elInfo,
SubAssembler* subAssembler,
Quadrature *quad)
{
FUNCNAME("OperatorTerm::getVectorAtQPs()");
TEST_EXIT_DBG(elInfo->getMesh() == vec->getFeSpace()->getMesh())
("There is something wrong!\n");
return subAssembler->getVectorAtQPs(vec, elInfo, quad);
}
double *OperatorTerm::getVectorAtQPs(DOFVectorBase<double>* vec,
const ElInfo* smallElInfo,
const ElInfo* largeElInfo,
SubAssembler* subAssembler,
Quadrature *quad)
{
FUNCNAME("OperatorTerm::getVectorAtQPs()");
TEST_EXIT(smallElInfo->getMesh() == vec->getFeSpace()->getMesh() ||
largeElInfo->getMesh() == vec->getFeSpace()->getMesh())
("There is something wrong!\n");
if (smallElInfo->getLevel() == largeElInfo->getLevel()) {
// Both elements have the same size, so we can use the simple procedure
// to determine the vecAtQPs.
if (vec->getFeSpace()->getMesh() == smallElInfo->getMesh())
return subAssembler->getVectorAtQPs(vec, smallElInfo, quad);
else
return subAssembler->getVectorAtQPs(vec, largeElInfo, quad);
} else {
// The two elements are different. If the vector is defined on the mesh of the
// small element, we can still use the simple procedure to determine the vecAtQPs.
if (vec->getFeSpace()->getMesh() == largeElInfo->getMesh())
return subAssembler->getVectorAtQPs(vec, smallElInfo, largeElInfo, quad);
else
return subAssembler->getVectorAtQPs(vec, smallElInfo, quad);
}
}
WorldVector<double>* OperatorTerm::getGradientsAtQPs(DOFVectorBase<double>* vec,
const ElInfo* elInfo,
SubAssembler* subAssembler,
......
......@@ -110,10 +110,11 @@ namespace AMDiS {
* Determines the value of a dof vector at the quadrature points of a given
* element. It is used by all VecAtQP like operator terms.
*/
double *getVectorAtQPs(DOFVectorBase<double>* vec,
const ElInfo* elInfo,
SubAssembler* subAssembler,
Quadrature *quad);
template<typename T>
T* getVectorAtQPs(DOFVectorBase<T>* vec,
const ElInfo* elInfo,
SubAssembler* subAssembler,
Quadrature *quad);
/** \brief
* Determines the value of a dof vector at the quadrature points of a given
......@@ -121,11 +122,12 @@ namespace AMDiS {
* meshes using the dual traverse. The element, i.e. the small or the large one,
* is choosen, which corresponds to the mesh the dof vector is defined on.
*/
double *getVectorAtQPs(DOFVectorBase<double>* vec,
const ElInfo* smallElInfo,
const ElInfo* largeElInfo,
SubAssembler* subAssembler,
Quadrature *quad);
template<typename T>
T* getVectorAtQPs(DOFVectorBase<T>* vec,
const ElInfo* smallElInfo,
const ElInfo* largeElInfo,
SubAssembler* subAssembler,
Quadrature *quad);
///
WorldVector<double>* getGradientsAtQPs(DOFVectorBase<double>* vec,
......@@ -180,4 +182,6 @@ namespace AMDiS {
}
#endif
#include "OperatorTerm.hh"
#endif // AMDIS_OPERATORTERM_H
#include "ElInfo.h"
namespace AMDiS {
template<typename T>
T* OperatorTerm::getVectorAtQPs(DOFVectorBase<T>* vec,
const ElInfo* elInfo,
SubAssembler* subAssembler,
Quadrature *quad)
{
FUNCNAME("OperatorTerm::getVectorAtQPs()");
TEST_EXIT_DBG(elInfo->getMesh() == vec->getFeSpace()->getMesh())
("There is something wrong!\n");
return subAssembler->getVectorAtQPs(vec, elInfo, quad);
}
template<typename T>
T* OperatorTerm::getVectorAtQPs(DOFVectorBase<T>* vec,
const ElInfo* smallElInfo,
const ElInfo* largeElInfo,
SubAssembler* subAssembler,
Quadrature *quad)
{
FUNCNAME("OperatorTerm::getVectorAtQPs()");
TEST_EXIT(smallElInfo->getMesh() == vec->getFeSpace()->getMesh() ||
largeElInfo->getMesh() == vec->getFeSpace()->getMesh())
("There is something wrong!\n");
if (smallElInfo->getLevel() == largeElInfo->getLevel()) {
// Both elements have the same size, so we can use the simple procedure
// to determine the vecAtQPs.
if (vec->getFeSpace()->getMesh() == smallElInfo->getMesh())
return subAssembler->getVectorAtQPs(vec, smallElInfo, quad);
else
return subAssembler->getVectorAtQPs(vec, largeElInfo, quad);
} else {
// The two elements are different. If the vector is defined on the mesh of the
// small element, we can still use the simple procedure to determine the vecAtQPs.
if (vec->getFeSpace()->getMesh() == largeElInfo->getMesh())
return subAssembler->getVectorAtQPs(vec, smallElInfo, largeElInfo, quad);
else
return subAssembler->getVectorAtQPs(vec, smallElInfo, quad);
}
}
}
......@@ -84,8 +84,8 @@ namespace AMDiS {
{
name = "precalculated second order assembler";
q11 = Q11PsiPhi::provideQ11PsiPhi(owner->getRowFeSpace()->getBasisFcts(),
owner->getColFeSpace()->getBasisFcts(),
q11 = Q11PsiPhi::provideQ11PsiPhi(rowFeSpace->getBasisFcts(),
colFeSpace->getBasisFcts(),
quadrature);
tmpLALt.resize(omp_get_overall_max_threads());
for (int i = 0; i < omp_get_overall_max_threads(); i++) {
......@@ -203,10 +203,10 @@ namespace AMDiS {
#pragma omp critical
#endif
{
psiFast = updateFastQuadrature(psiFast, owner->getRowFeSpace()->getBasisFcts(),
INIT_GRD_PHI);
phiFast = updateFastQuadrature(phiFast, owner->getRowFeSpace()->getBasisFcts(),
INIT_GRD_PHI);
psiFast =
updateFastQuadrature(psiFast, rowFeSpace->getBasisFcts(), INIT_GRD_PHI);
phiFast =
updateFastQuadrature(phiFast, rowFeSpace->getBasisFcts(), INIT_GRD_PHI);
}
firstCall = false;
}
......@@ -270,8 +270,8 @@ namespace AMDiS {
DimVec<double> grdPsi(dim, NO_INIT);
VectorOfFixVecs<DimVec<double> > grdPhi(dim, nCol, NO_INIT);
const BasisFunction *psi = owner->getRowFeSpace()->getBasisFcts();
const BasisFunction *phi = owner->getColFeSpace()->getBasisFcts();
const BasisFunction *psi = rowFeSpace->getBasisFcts();
const BasisFunction *phi = colFeSpace->getBasisFcts();
int nPoints = quadrature->getNumPoints();
......
......@@ -16,21 +16,27 @@ namespace AMDiS {
int order,
bool optimized,
FirstOrderType type)
: nRow(0),
: rowFeSpace(assembler->rowFeSpace),
colFeSpace(assembler->colFeSpace),
nRow(0),
nCol(0),
coordsAtQPs(NULL),
coordsNumAllocated(0),
quadrature(quadrat),
psiFast(NULL),
phiFast(NULL),
owner(assembler),
symmetric(true),
opt(optimized),
firstCall(true),
name("")
{
const BasisFunction *psi = assembler->rowFeSpace->getBasisFcts();
const BasisFunction *phi = assembler->colFeSpace->getBasisFcts();
FUNCNAME("SubAssembler::SubAssembler()");
TEST_EXIT(rowFeSpace)("No row FE space defined!\n");
TEST_EXIT(colFeSpace)("No col FE space defined!\n");
const BasisFunction *psi = rowFeSpace->getBasisFcts();
const BasisFunction *phi = colFeSpace->getBasisFcts();
nRow = psi->getNumber();
nCol = phi->getNumber();
......@@ -69,7 +75,7 @@ namespace AMDiS {
symmetric = false;
}
dim = assembler->rowFeSpace->getMesh()->getDim();
dim = rowFeSpace->getMesh()->getDim();
}
......@@ -151,97 +157,13 @@ namespace AMDiS {
}
double* SubAssembler::getVectorAtQPs(DOFVectorBase<double>* dv,
const ElInfo* elInfo,
Quadrature *quad)
{
FUNCNAME("SubAssembler::getVectorAtQPs()");
const DOFVectorBase<double>* vec = dv ? dv : owner->operat->getUhOld();
TEST_EXIT_DBG(vec)("no dof vector!\n");
TEST_EXIT_DBG(elInfo->getMesh() == vec->getFeSpace()->getMesh())
("Vector and fe space do not fit together!\n");
Quadrature *localQuad = quad ? quad : quadrature;
if (valuesAtQPs[vec] && valuesAtQPs[vec]->valid)
return &(valuesAtQPs[vec]->values[0]);
if (!valuesAtQPs[vec])
valuesAtQPs[vec] = new ValuesAtQPs;
valuesAtQPs[vec]->values.resize(localQuad->getNumPoints());
double *values = &(valuesAtQPs[vec]->values[0]);
bool sameFeSpaces =
(vec->getFeSpace() == owner->rowFeSpace) ||
(vec->getFeSpace() == owner->colFeSpace);
if (opt && !quad && sameFeSpaces) {
const BasisFunction *psi = owner->rowFeSpace->getBasisFcts();
const BasisFunction *phi = owner->colFeSpace->getBasisFcts();
if (vec->getFeSpace()->getBasisFcts() == psi)
psiFast = updateFastQuadrature(psiFast, psi, INIT_PHI);
else if(vec->getFeSpace()->getBasisFcts() == phi)
phiFast = updateFastQuadrature(phiFast, phi, INIT_PHI);
}
// calculate new values
const BasisFunction *basFcts = vec->getFeSpace()->getBasisFcts();
if (opt && !quad && sameFeSpaces) {
if (psiFast->getBasisFunctions() == basFcts) {
vec->getVecAtQPs(elInfo, NULL, psiFast, values);
} else if (phiFast->getBasisFunctions() == basFcts) {
vec->getVecAtQPs(elInfo, NULL, phiFast, values);
} else {
vec->getVecAtQPs(elInfo, localQuad, NULL, values);
}
} else {
vec->getVecAtQPs(elInfo, localQuad, NULL, values);
}
valuesAtQPs[vec]->valid = true;
return values;
}
double* SubAssembler::getVectorAtQPs(DOFVectorBase<double>* dv,
const ElInfo* smallElInfo,
const ElInfo* largeElInfo,
Quadrature *quad)
{
FUNCNAME("SubAssembler::getVectorAtQPs()");
const DOFVectorBase<double>* vec = dv ? dv : owner->operat->getUhOld();
TEST_EXIT_DBG(vec)("no dof vector!\n");
Quadrature *localQuad = quad ? quad : quadrature;
if (!valuesAtQPs[vec])
valuesAtQPs[vec] = new ValuesAtQPs;
valuesAtQPs[vec]->values.resize(localQuad->getNumPoints());
double *values = &(valuesAtQPs[vec]->values[0]);
valuesAtQPs[vec]->valid = true;
vec->getVecAtQPs(smallElInfo, largeElInfo, localQuad, NULL, values);
return values;
}
WorldVector<double>* SubAssembler::getGradientsAtQPs(DOFVectorBase<double>* dv,
WorldVector<double>* SubAssembler::getGradientsAtQPs(DOFVectorBase<double>* vec,
const ElInfo* elInfo,
Quadrature *quad)
{
FUNCNAME("SubAssembler::getGradientsAtQPs()");
const DOFVectorBase<double>* vec = dv ? dv : owner->operat->getUhOld();
TEST_EXIT_DBG(vec)("no dof vector!\n");
TEST_EXIT_DBG(vec)("No DOF vector!\n");
if (gradientsAtQPs[vec] && gradientsAtQPs[vec]->valid)
return &(gradientsAtQPs[vec]->values[0]);
......@@ -255,12 +177,11 @@ namespace AMDiS {
WorldVector<double> *values = &(gradientsAtQPs[vec]->values[0]);
const BasisFunction *psi = owner->rowFeSpace->getBasisFcts();
const BasisFunction *phi = owner->colFeSpace->getBasisFcts();
const BasisFunction *psi = rowFeSpace->getBasisFcts();
const BasisFunction *phi = colFeSpace->getBasisFcts();
bool sameFeSpaces =
(vec->getFeSpace() == owner->rowFeSpace) ||
(vec->getFeSpace() == owner->colFeSpace);
vec->getFeSpace() == rowFeSpace || vec->getFeSpace() == colFeSpace;
if (opt && !quad && sameFeSpaces) {
if (vec->getFeSpace()->getBasisFcts() == psi)
......@@ -287,16 +208,14 @@ namespace AMDiS {
}
WorldVector<double>* SubAssembler::getGradientsAtQPs(DOFVectorBase<double>* dv,
WorldVector<double>* SubAssembler::getGradientsAtQPs(DOFVectorBase<double>* vec,
const ElInfo* smallElInfo,
const ElInfo* largeElInfo,
Quadrature *quad)
{
FUNCNAME("SubAssembler::getGradientsAtQPs()");
const DOFVectorBase<double>* vec = dv ? dv : owner->operat->getUhOld();
TEST_EXIT_DBG(vec)("no dof vector!\n");
TEST_EXIT_DBG(vec)("No DOF vector!\n");
if (gradientsAtQPs[vec] && gradientsAtQPs[vec]->valid)
return &(gradientsAtQPs[vec]->values[0]);
......
......@@ -86,15 +86,17 @@ namespace AMDiS {
* DOFVector dv evaluated at quadrature points.
* Used by \ref OperatorTerm::initElement().
*/
double* getVectorAtQPs(DOFVectorBase<double>* dv,
const ElInfo* elInfo,
Quadrature *quad = NULL);
template<typename T>
T* getVectorAtQPs(DOFVectorBase<T>* dv,
const ElInfo* elInfo,
Quadrature *quad = NULL);
///
double* getVectorAtQPs(DOFVectorBase<double>* dv,
const ElInfo* smallElInfo,
const ElInfo* largeElInfo,
Quadrature *quad = NULL);
template<typename T>
T* getVectorAtQPs(DOFVectorBase<T>* dv,
const ElInfo* smallElInfo,
const ElInfo* largeElInfo,
Quadrature *quad = NULL);
/** \brief
* Gradients of DOFVector dv evaluated at quadrature points.
......@@ -147,6 +149,12 @@ namespace AMDiS {
/// Problem dimension
int dim;
/// Row FiniteElemSpace.
const FiniteElemSpace *rowFeSpace;
/// Column FiniteElemSpace.
const FiniteElemSpace *colFeSpace;
/** \brief
* Number of rows of the element matrix and length of the element
* vector. Is equal to the number of row basis functions
......@@ -210,9 +218,6 @@ namespace AMDiS {
/// FastQuadrature for column basis functions
FastQuadrature *phiFast;
/// Corresponding Assembler
Assembler* owner;
/// Flag that specifies whether the element matrix is symmetric.
bool symmetric;
......@@ -233,4 +238,6 @@ namespace AMDiS {
}
#include "SubAssembler.hh"
#endif // AMDSIS_SUB_ASSEMBLER_H
#include "Quadrature.h"
#include "FiniteElemSpace.h"
namespace AMDiS {
template<typename T>
T* SubAssembler::getVectorAtQPs(DOFVectorBase<T>* vec,
const ElInfo* elInfo,
Quadrature *quad)
{
FUNCNAME("SubAssembler::getVectorAtQPs()");
TEST_EXIT_DBG(vec)("No DOF vector!\n");
TEST_EXIT_DBG(elInfo->getMesh() == vec->getFeSpace()->getMesh())
("Vector and FE space do not fit together!\n");
Quadrature *localQuad = quad ? quad : quadrature;
if (valuesAtQPs[vec] && valuesAtQPs[vec]->valid)
return &(valuesAtQPs[vec]->values[0]);
if (!valuesAtQPs[vec])
valuesAtQPs[vec] = new ValuesAtQPs;
valuesAtQPs[vec]->values.resize(localQuad->getNumPoints());
T *values = &(valuesAtQPs[vec]->values[0]);
bool sameFeSpaces =
vec->getFeSpace() == rowFeSpace || vec->getFeSpace() == colFeSpace;
if (opt && !quad && sameFeSpaces) {
const BasisFunction *psi = rowFeSpace->getBasisFcts();
const BasisFunction *phi = colFeSpace->getBasisFcts();
if (vec->getFeSpace()->getBasisFcts() == psi)
psiFast = updateFastQuadrature(psiFast, psi, INIT_PHI);
else if(vec->getFeSpace()->getBasisFcts() == phi)
phiFast = updateFastQuadrature(phiFast, phi, INIT_PHI);
}
// calculate new values
const BasisFunction *basFcts = vec->getFeSpace()->getBasisFcts();
if (opt && !quad && sameFeSpaces) {
if (psiFast->getBasisFunctions() == basFcts) {
vec->getVecAtQPs(elInfo, NULL, psiFast, values);
} else if (phiFast->getBasisFunctions() == basFcts) {
vec->getVecAtQPs(elInfo, NULL, phiFast, values);
} else {
vec->getVecAtQPs(elInfo, localQuad, NULL, values);
}
} else {
vec->getVecAtQPs(elInfo, localQuad, NULL, values);
}
valuesAtQPs[vec]->valid = true;</