Commit 9b510dbe authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

Added new operators.

parent b2a88ee2
......@@ -81,6 +81,7 @@ namespace AMDiS {
if (adaptInfo->getTime() <= adaptInfo->getStartTime())
problemIteration_->oneIteration(adaptInfo, ESTIMATE);
// increment time
adaptInfo->setTime(adaptInfo->getTime() + adaptInfo->getTimestep());
......
......@@ -72,11 +72,13 @@ namespace AMDiS {
DOFMatrix::~DOFMatrix()
{
FUNCNAME("DOFMatrix::~DOFMatrix()");
if (rowFESpace && rowFESpace->getAdmin())
(const_cast<DOFAdmin*>(rowFESpace->getAdmin()))->removeDOFIndexed(this);
if (boundaryManager) delete boundaryManager;
if (inserter) delete inserter;
if (boundaryManager)
delete boundaryManager;
if (inserter)
delete inserter;
}
void DOFMatrix::print() const
......@@ -135,12 +137,11 @@ namespace AMDiS {
int non_symmetric = !symmetric();
if (non_symmetric) {
if (non_symmetric)
MSG("matrix `%s' not symmetric.\n", name.data());
} else {
else
MSG("matrix `%s' is symmetric.\n", name.data());
}
}
DOFMatrix& DOFMatrix::operator=(const DOFMatrix& rhs)
{
......@@ -154,11 +155,10 @@ namespace AMDiS {
if (rhs.inserter == 0 && inserter == 0)
matrix = rhs.matrix;
if (rhs.boundaryManager) {
if (rhs.boundaryManager)
boundaryManager = new BoundaryManager(*rhs.boundaryManager);
} else {
else
boundaryManager = NULL;
}
nRow = rhs.nRow;
nCol = rhs.nCol;
......@@ -302,9 +302,8 @@ namespace AMDiS {
{
FUNCNAME("DOFMatrix::assemble2()");
if (!op && operators.size() == 0) {
if (!op && operators.size() == 0)
return;
}
set_to_zero(elementMatrix);
......@@ -335,8 +334,7 @@ namespace AMDiS {
{
// call the operatos cleanup procedures
for (std::vector<Operator*>::iterator it = operators.begin();
it != operators.end();
++it)
it != operators.end(); ++it)
(*it)->finishAssembling();
}
......
......@@ -382,6 +382,23 @@ namespace AMDiS {
boundaryManager = bm;
}
/// Calculates the average of non zero entries per row in matrix.
void calculateNnz()
{
nnzPerRow = 0;
if (num_rows(matrix) != 0)
nnzPerRow = int(double(matrix.nnz()) / num_rows(matrix) * 1.2);
if (nnzPerRow < 5)
nnzPerRow= 5;
}
/// Returns \ref nnzPerRow.
int getNnz()
{
return nnzPerRow;
}
private:
template <typename T>
void s_write(::std::ostream &out, const T& value)
......@@ -536,6 +553,13 @@ namespace AMDiS {
*/
std::set<int> applyDBCs;
/* \brief
* Number of non zero entries per row (average). For instationary problems this
* information may be used in the next timestep to accelerate insertion of
* elemnts during assembling.
*/
int nnzPerRow;
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
std::map<DegreeOfFreedom, bool> isRankDOF;
#endif
......
......@@ -970,12 +970,10 @@ namespace AMDiS {
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic, 25000) default(shared) private(i)
#endif
for (i = 0; i < maxI; i++) {
if (!admin->isDOFFree(i)) {
for (i = 0; i < maxI; i++)
if (!admin->isDOFFree(i))
y[i] = alpha * y[i] + x[i];
}
}
}
template<typename T>
inline const DOFVector<T>& mult(double scal,
......@@ -984,12 +982,9 @@ namespace AMDiS {
{
typename DOFVector<T>::Iterator vIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(&v)), USED_DOFS);
typename DOFVector<T>::Iterator rIterator(dynamic_cast<DOFIndexed<T>*>(&result), USED_DOFS);
for(vIterator.reset(), rIterator.reset();
!vIterator.end();
++vIterator, ++rIterator)
{
for (vIterator.reset(), rIterator.reset();
!vIterator.end(); ++vIterator, ++rIterator)
*rIterator = scal * (*vIterator);
};
return result;
}
......@@ -1001,12 +996,10 @@ namespace AMDiS {
{
typename DOFVector<T>::Iterator vIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(&v)), USED_DOFS);
typename DOFVector<T>::Iterator rIterator(dynamic_cast<DOFIndexed<T>*>(&result), USED_DOFS);
for(vIterator.reset(), rIterator.reset();
!vIterator.end();
++vIterator, ++rIterator)
{
for (vIterator.reset(), rIterator.reset();
!vIterator.end(); ++vIterator, ++rIterator)
*rIterator = (*vIterator) + scal;
};
return result;
}
......@@ -1018,20 +1011,18 @@ namespace AMDiS {
typename DOFVector<T>::Iterator v1Iterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(&v1)), USED_DOFS);
typename DOFVector<T>::Iterator v2Iterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(&v2)), USED_DOFS);
typename DOFVector<T>::Iterator rIterator(dynamic_cast<DOFIndexed<T>*>(&result), USED_DOFS);
for(v1Iterator.reset(), v2Iterator.reset(), rIterator.reset();
!v1Iterator.end();
++v1Iterator, ++v2Iterator, ++rIterator)
{
for (v1Iterator.reset(), v2Iterator.reset(), rIterator.reset();
!v1Iterator.end(); ++v1Iterator, ++v2Iterator, ++rIterator)
*rIterator = (*v1Iterator) + (*v2Iterator);
};
return result;
return result;
}
template<typename T>
const T *DOFVectorBase<T>::getLocalVector(const Element *el, T *d) const
{
static T* localVec = NULL;
static int localVecSize = 0;
const DOFAdmin* admin = feSpace->getAdmin();
T *result;
......@@ -1039,8 +1030,14 @@ namespace AMDiS {
if (d) {
result = d;
} else {
if(localVec) delete [] localVec;
if (localVec && nBasFcts > localVecSize) {
delete [] localVec;
localVec = new T[nBasFcts];
}
if (!localVec)
localVec = new T[nBasFcts];
localVecSize = nBasFcts;
result = localVec;
}
......
......@@ -47,8 +47,8 @@ namespace AMDiS {
&standardSubAssemblersGrdPhi);
int myRank = omp_get_thread_num();
std::vector<OperatorTerm*> opTerms
= (type == GRD_PSI) ? op->firstOrderGrdPsi[myRank] : op->firstOrderGrdPhi[myRank];
std::vector<OperatorTerm*> opTerms =
(type == GRD_PSI) ? op->firstOrderGrdPsi[myRank] : op->firstOrderGrdPhi[myRank];
// check if a assembler is needed at all
if (opTerms.size() == 0)
......@@ -103,15 +103,15 @@ namespace AMDiS {
Stand10::Stand10(Operator *op, Assembler *assembler, Quadrature *quad)
: FirstOrderAssembler(op, assembler, quad, false, GRD_PSI)
{}
{
psi = owner->getRowFESpace()->getBasisFcts();
phi = owner->getColFESpace()->getBasisFcts();
}
void Stand10::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix& mat)
{
DimVec<double> grdPsi(dim, DEFAULT_VALUE, 0.0);
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];
......@@ -132,7 +132,7 @@ namespace AMDiS {
for (int i = 0; i < nRow; i++) {
(*(psi->getGrdPhi(i)))(quadrature->getLambda(iq), grdPsi);
for (int j = 0; j < nCol; j++)
mat[i][j] += quadrature->getWeight(iq) * (Lb[iq] * grdPsi) * phival[j];
mat[i][j] += quadrature->getWeight(iq) * phival[j] * (Lb[iq] * grdPsi);
}
}
}
......@@ -140,7 +140,6 @@ 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];
......@@ -189,13 +188,11 @@ namespace AMDiS {
VectorOfFixVecs<DimVec<double> > &Lb = tmpLb[myRank];
Lb.resize(nPoints);
for (int iq = 0; iq < nPoints; iq++) {
for (int iq = 0; iq < nPoints; iq++)
Lb[iq].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<FirstOrderTerm*>((terms[myRank][i])))->getLb(elInfo, nPoints, Lb);
}
for (int iq = 0; iq < nPoints; iq++) {
Lb[iq] *= elInfo->getDet();
......@@ -203,12 +200,11 @@ namespace AMDiS {
const double *phi = phiFast->getPhi(iq);
grdPsi = psiFast->getGradient(iq);
for (int i = 0; i < nRow; i++) {
for (int i = 0; i < nRow; i++)
for (int j = 0; j < nCol; j++)
mat[i][j] += quadrature->getWeight(iq) * (Lb[iq] * (*grdPsi)[i]) * phi[j];
}
}
}
void Quad10::calculateElementVector(const ElInfo *elInfo, ElementVector& vec)
{
......@@ -232,23 +228,19 @@ namespace AMDiS {
VectorOfFixVecs<DimVec<double> > &Lb = tmpLb[myRank];
Lb.resize(nPoints);
for (int iq = 0; iq < nPoints; iq++) {
for (int iq = 0; iq < nPoints; iq++)
Lb[iq].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<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++) {
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)
......@@ -305,13 +297,13 @@ namespace AMDiS {
VectorOfFixVecs<DimVec<double> >
grdPhi(assembler->getRowFESpace()->getMesh()->getDim(), nCol, NO_INIT);
tmpGrdPhi.resize(omp_get_overall_max_threads(), grdPhi);
psi = owner->getRowFESpace()->getBasisFcts();
phi = owner->getColFESpace()->getBasisFcts();
}
void Stand01::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix& mat)
{
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];
......@@ -320,6 +312,7 @@ namespace AMDiS {
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);
......@@ -332,7 +325,7 @@ namespace AMDiS {
for (int i = 0; i < nRow; i++) {
double psival = (*(psi->getPhi(i)))(quadrature->getLambda(iq));
for (int j = 0; j < nCol; j++)
mat[i][j] += quadrature->getWeight(iq) * ((Lb[iq] * psival) * grdPhi[j]);
mat[i][j] += quadrature->getWeight(iq) * psival * (Lb[iq] * grdPhi[j]);
}
}
}
......
......@@ -78,6 +78,9 @@ namespace AMDiS {
/// Implements SubAssembler::calculateElementVector().
void calculateElementVector(const ElInfo *, ElementVector&);
protected:
const BasisFunction *psi, *phi;
};
......@@ -104,6 +107,8 @@ namespace AMDiS {
protected:
std::vector<VectorOfFixVecs<DimVec<double> > > tmpGrdPhi;
const BasisFunction *psi, *phi;
};
......
......@@ -233,17 +233,20 @@ namespace AMDiS {
}
/// Returns the \ref size of this VectorOfFixVecs
inline int getSize() const {
inline int getSize() const
{
return size;
}
/// Returns \ref dim
inline int getDim() const {
inline int getDim() const
{
return dim;
}
/// Returns the size of the contained FixVecs
inline int getSizeOfFixVec() const {
inline int getSizeOfFixVec() const
{
return vec[0]->getSize();
}
......@@ -515,7 +518,8 @@ namespace AMDiS {
/// creates and inits and double array
double *createAndInitArray(int size, ...);
inline WorldVector<double> operator*(const WorldVector<double>& v, double d) {
inline WorldVector<double> operator*(const WorldVector<double>& v, double d)
{
WorldVector<double> result = v;
result *= d;
return result;
......
......@@ -8,20 +8,18 @@ namespace AMDiS {
thisIt != this->end();
thisIt++) {
*thisIt = 0;
for (T* vIt = v.begin(); vIt != v.end(); vIt++, mIt++) {
for (T* vIt = v.begin(); vIt != v.end(); vIt++, mIt++)
*thisIt += *vIt * *mIt;
}
}
}
template<typename T, GeoIndex d>
double absteukl(const FixVec<T,d>& a,const FixVec<T,d>& b)
{
double erg = 0.0;
for (int i = 0; i < a.getSize() ; i++) {
for (int i = 0; i < a.getSize() ; i++)
erg = erg + ((a[i] - b[i]) * (a[i] - b[i]));
}
return sqrt(erg);
}
......@@ -39,11 +37,10 @@ namespace AMDiS {
thisIt++) {
*thisIt = 0;
for (T* vIt = v.begin(); vIt != v.end(); vIt++, mIt++) {
for (T* vIt = v.begin(); vIt != v.end(); vIt++, mIt++)
*thisIt += *vIt * *mIt;
}
}
}
template<typename T>
bool WorldMatrix<T>::isDiagMatrix() const
......@@ -70,10 +67,9 @@ namespace AMDiS {
template<typename T>
void WorldMatrix<T>::setDiag(T value)
{
for (int i = 0; i < this->rows; i++) {
for (int i = 0; i < this->rows; i++)
this->valArray[i * this->cols + i] = value;
}
}
template<typename T>
void WorldMatrix<T>::vecProduct(const WorldVector<T>& v1, const WorldVector<T>& v2)
......@@ -85,19 +81,16 @@ namespace AMDiS {
T *thisIt = this->begin();
for (T* v1It = v1.begin(); v1It != v1.end(); v1It++) {
for (T* v2It = v2.begin(); v2It != v2.end(); v2It++, thisIt++) {
for (T* v1It = v1.begin(); v1It != v1.end(); v1It++)
for (T* v2It = v2.begin(); v2It != v2.end(); v2It++, thisIt++)
*thisIt = *v1It * *v2It;
}
}
}
template<typename T>
const WorldMatrix<T>& operator*=(WorldMatrix<T>& m, T scal)
{
for (T* mIt = m.begin(); mIt != m.end(); mIt++) {
for (T* mIt = m.begin(); mIt != m.end(); mIt++)
*mIt *= scal;
}
return m;
}
......@@ -108,9 +101,8 @@ namespace AMDiS {
T *m1It, *m2It;
for (m1It = m1.begin(), m2It = m2.begin();
m1It != m1.end();
m1It++, m2It++) {
m1It++, m2It++)
*m1It -= *m2It;
}
return m1;
}
......@@ -121,9 +113,8 @@ namespace AMDiS {
T* m1It, *m2It;
for (m1It = m1.begin(), m2It = m2.begin();
m1It != m1.end();
m1It++, m2It++) {
m1It++, m2It++)
*m1It += *m2It;
}
return m1;
}
......
......@@ -921,9 +921,13 @@ namespace AMDiS {
if (indices) {
result = indices;
} else {
if (localVec)
if (localVec && nBasFcts > localVecSize) {
delete [] localVec;
localVec = new DegreeOfFreedom[nBasFcts];
}
if (!localVec)
localVec = new DegreeOfFreedom[nBasFcts];
localVecSize = nBasFcts;
result = localVec;
}
......
......@@ -578,6 +578,94 @@ namespace AMDiS {
}
}
Vec2AndGrad2AtQP_ZOT::Vec2AndGrad2AtQP_ZOT(DOFVectorBase<double> *dv1,
DOFVectorBase<double> *dv2,
QuartAbstractFunction<double, double, double, WorldVector<double>,WorldVector<double> > *af)
: ZeroOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), f(af)
{
TEST_EXIT(dv1)("No first vector!\n");
TEST_EXIT(dv2)("No second vector!\n");
auxFESpaces.push_back(dv1->getFESpace());
auxFESpaces.push_back(dv2->getFESpace());
}
void Vec2AndGrad2AtQP_ZOT::initElement(const ElInfo* elInfo,
SubAssembler* subAssembler,
Quadrature *quad)
{
vecAtQPs1 = getVectorAtQPs(vec1, elInfo, subAssembler, quad);
vecAtQPs2 = getVectorAtQPs(vec2, elInfo, subAssembler, quad);
gradAtQPs1 = getGradientsAtQPs(vec1, elInfo, subAssembler, quad);
gradAtQPs2 = getGradientsAtQPs(vec2, elInfo, subAssembler, quad);
}
void Vec2AndGrad2AtQP_ZOT::eval(int nPoints,
const double *uhAtQP,
const WorldVector<double> *grdUhAtQP,
const WorldMatrix<double> *D2UhAtQP,
double *result,
double fac) const
{
for (int iq = 0; iq < nPoints; iq++)
result[iq] +=
fac *
(*f)(vecAtQPs1[iq], vecAtQPs2[iq], gradAtQPs1[iq], gradAtQPs2[iq]) *
uhAtQP[iq];
}
void Vec2AndGrad2AtQP_ZOT::getC(const ElInfo *, int nPoints,
std::vector<double> &C) const
{
for (int iq = 0; iq < nPoints; iq++)
C[iq] += (*f)(vecAtQPs1[iq], vecAtQPs2[iq], gradAtQPs1[iq], gradAtQPs2[iq]);
}
Vec2AndGradVecAtQP_ZOT::Vec2AndGradVecAtQP_ZOT(DOFVectorBase<double> *dv1,
DOFVectorBase<double> *dv2,
DOFVectorBase<double> *dGrd,
TertiaryAbstractFunction<double, double,double, WorldVector<double> > *af)
: ZeroOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), vecGrd(dGrd), f(af)
{
TEST_EXIT(dv1)("No vector!\n");
TEST_EXIT(dv2)("No vector!\n");
TEST_EXIT(dGrd)("No gradient vector!\n");
auxFESpaces.push_back(dv1->getFESpace());
auxFESpaces.push_back(dv2->getFESpace());
auxFESpaces.push_back(dGrd->getFESpace());
}
void Vec2AndGradVecAtQP_ZOT::initElement(const ElInfo* elInfo,
SubAssembler* subAssembler,
Quadrature *quad)
{
vec1AtQPs = getVectorAtQPs(vec1, elInfo, subAssembler, quad);
vec2AtQPs = getVectorAtQPs(vec2, elInfo, subAssembler, quad);
gradAtQPs = getGradientsAtQPs(vecGrd, elInfo, subAssembler, quad);
}
void Vec2AndGradVecAtQP_ZOT::getC(const ElInfo *, int nPoints,
std::vector<double> &C) const
{
for (int iq = 0; iq < nPoints; iq++)
C[iq] += (*f)(vec1AtQPs[iq], vec2AtQPs[iq], gradAtQPs[iq]);
}
void Vec2AndGradVecAtQP_ZOT::eval(int nPoints,
const double *uhAtQP,
const WorldVector<double> *grdUhAtQP,
const WorldMatrix<double> *D2UhAtQP,
double *result,
double fac) const
{
for (int iq = 0; iq < nPoints; iq++)
result[iq] +=
fac * (*f)(vec1AtQPs[iq], vec2AtQPs[iq], gradAtQPs[iq]) * uhAtQP[iq];
}
General_ZOT::General_ZOT(std::vector<DOFVectorBase<double>*> vecs,
std::vector<DOFVectorBase<double>*> grads,
TertiaryAbstractFunction<double, WorldVector<double>, std::vector<double>, std::vector<WorldVector<double> > > *af)
......@@ -663,6 +751,181 @@ namespace AMDiS {
auxFESpaces.push_back(dv2->getFESpace());
}
Vec2AndGradAtQP_FOT::Vec2AndGradAtQP_FOT(DOFVectorBase<double> *dv1,
DOFVectorBase<double> *dv2,
TertiaryAbstractFunction<double, double, double, WorldVector<double> > *f_, WorldVector<double> *b_)
: FirstOrderTerm(8),
vec1(dv1),
vec2(dv2),
f(f_),