// ============================================================================
// == ==
// == AMDiS - Adaptive multidimensional simulations ==
// == ==
// ============================================================================
// == ==
// == crystal growth group ==
// == ==
// == Stiftung caesar ==
// == Ludwig-Erhard-Allee 2 ==
// == 53175 Bonn ==
// == germany ==
// == ==
// ============================================================================
// == ==
// == http://www.caesar.de/cg/AMDiS ==
// == ==
// ============================================================================
/** \file Assembler.h */
/**
* \defgroup Assembler Assembler module
*
* \brief
* Contains the operator and assembler classes:
* @{
@}
*/
#ifndef AMDIS_ASSEMBLER_H
#define AMDIS_ASSEMBLER_H
#include
#include "FixVec.h"
#include "MemoryManager.h"
#include "ZeroOrderAssembler.h"
#include "FirstOrderAssembler.h"
#include "SecondOrderAssembler.h"
#include "ElInfo.h"
#include "OpenMP.h"
namespace AMDiS {
class Element;
class Quadrature;
class ElementMatrix;
class ElementVector;
class Operator;
/**
* \ingroup Assembler
*
* \brief
* Assembles element matrices and vectors for a given Operator. Uses
* one SubAssembler for all second order terms of the Operator, one for all
* first order terms, and one for all zero order terms.
*/
class Assembler
{
public:
MEMORY_MANAGED(Assembler);
/// Constructor
Assembler(Operator *op,
const FiniteElemSpace *rowFESpace,
const FiniteElemSpace *colFESpace = NULL);
/// Destructor
~Assembler();
void initElementMatrix(ElementMatrix *elMat,
const ElInfo *rowElInfo,
const ElInfo *colElInfo = NULL);
void initElementVector(ElementVector *elVec,
const ElInfo *elInfo);
/// Assembles the element matrix for the given ElInfo
void calculateElementMatrix(const ElInfo *elInfo,
ElementMatrix *userMat,
double factor = 1.0);
void calculateElementMatrix(const ElInfo *rowElInfo,
const ElInfo *colElInfo,
const ElInfo *smallElInfo,
const ElInfo *largeElInfo,
ElementMatrix *userMat,
double factor = 1.0);
/// Assembles the element vector for the given ElInfo
void calculateElementVector(const ElInfo *elInfo,
ElementVector *userVec,
double factor = 1.0);
void calculateElementVector(const ElInfo *mainElInfo,
const ElInfo *auxElInfo,
const ElInfo *smallElInfo,
const ElInfo *largeElInfo,
ElementVector *userVec,
double factor = 1.0);
/// Returns \ref rowFESpace.
inline const FiniteElemSpace* getRowFESpace() {
return rowFESpace;
}
/// Returns \ref colFESpace.
inline const FiniteElemSpace* getColFESpace() {
return colFESpace;
}
/// Returns \ref nRow.
inline int getNRow() {
return nRow;
}
/// Returns \ref nCol.
inline int getNCol() {
return nCol;
}
/// Sets \ref rememberElMat.
inline void rememberElementMatrix(bool rem) {
rememberElMat = rem;
}
/// Sets \ref rememberElVec.
inline void rememberElementVector(bool rem) {
rememberElVec = rem;
}
/// Returns \ref zeroOrderAssembler.
inline ZeroOrderAssembler* getZeroOrderAssembler() {
return zeroOrderAssembler;
}
/** \brief
* Returns \ref firstOrderAssemblerGrdPsi or \ref firstOrderAssemblerGrdPhi
* depending on type.
*/
inline FirstOrderAssembler* getFirstOrderAssembler(FirstOrderType type = GRD_PSI)
{
return (type == GRD_PSI) ?
firstOrderAssemblerGrdPsi :
firstOrderAssemblerGrdPhi;
}
/// Returns \ref secondOrderAssembler.
inline SecondOrderAssembler* getSecondOrderAssembler() {
return secondOrderAssembler;
}
/// Returns \ref operat;
inline Operator* getOperator() {
return operat;
}
/// Initialisation for the given ElInfo. The call is deligated to the sub assemblers.
void initElement(const ElInfo *smallElInfo,
const ElInfo *largeElInfo = NULL,
Quadrature *quad = NULL);
/// Sets quadratures of all sub assemblers.
void setQuadratures(Quadrature *quad2,
Quadrature *quad1GrdPsi,
Quadrature *quad1GrdPhi,
Quadrature *quad0)
{
if (secondOrderAssembler) {
TEST_EXIT(!secondOrderAssembler->getQuadrature())
("quadrature already existing\n");
secondOrderAssembler->setQuadrature(quad2);
}
if (firstOrderAssemblerGrdPsi) {
TEST_EXIT(!firstOrderAssemblerGrdPsi->getQuadrature())
("quadrature already existing\n");
firstOrderAssemblerGrdPsi->setQuadrature(quad1GrdPsi);
}
if (firstOrderAssemblerGrdPhi) {
TEST_EXIT(!firstOrderAssemblerGrdPhi->getQuadrature())
("quadrature already existing\n");
firstOrderAssemblerGrdPhi->setQuadrature(quad1GrdPhi);
}
if (zeroOrderAssembler) {
TEST_EXIT(!zeroOrderAssembler->getQuadrature())
("quadrature already existing\n");
zeroOrderAssembler->setQuadrature(quad0);
}
}
/// That function must be called after one assembling cycle has been finished.
void finishAssembling();
protected:
/** \brief
* Vector assembling by element matrix-vector multiplication.
* Usefull if an element matrix was already calculated.
*/
void matVecAssemble(const ElInfo *elInfo, ElementVector *vec);
///
void matVecAssemble(const ElInfo *mainElInfo, const ElInfo *auxElInfo,
const ElInfo *smallElInfo, const ElInfo *largeElInfo,
ElementVector *vec);
/** \brief
* Checks whether quadratures for subassemblers are already set.
* If not they will be created.
*/
void checkQuadratures();
protected:
/// Operator this Assembler belongs to.
Operator *operat;
/// Row FiniteElemSpace.
const FiniteElemSpace *rowFESpace;
/// Column FiniteElemSpace.
const FiniteElemSpace *colFESpace;
/// Number of rows.
int nRow;
/// Number of columns.
int nCol;
/// SubAssembler for the second order terms
SecondOrderAssembler *secondOrderAssembler;
/// SubAssembler for the first order terms (grdPsi)
FirstOrderAssembler *firstOrderAssemblerGrdPsi;
/// SubAssembler for the first order terms (grdPhi)
FirstOrderAssembler *firstOrderAssemblerGrdPhi;
/// SubAssembler for the zero order terms
ZeroOrderAssembler *zeroOrderAssembler;
///
bool remember;
/// Determines whether the element matrix should be stored locally.
bool rememberElMat;
/// Determines whether the element vector should be stored locally.
bool rememberElVec;
/// Locally stored element matrix
ElementMatrix* elementMatrix;
/// Locally stored element vector
ElementVector* elementVector;
/** \brief
* Used to check whether \ref initElement() must be called, because
* a new Element is visited.
*/
Element* lastMatEl;
/** \brief
* Used to check whether \ref initElement() must be called, because
* a new Element is visited.
*/
Element* lastVecEl;
/// Used to check for new traverse.
int lastTraverseId;
friend class SubAssembler;
friend class ZeroOrderAssembler;
friend class FirstOrderAssembler;
friend class SecondOrderAssembler;
};
// ============================================================================
// ===== class StandardAssembler =============================================
// ============================================================================
/**
* \ingroup Assembler
*
* \brief
* Assembler using non optimized sub assemblers.
*/
class StandardAssembler : public Assembler
{
public:
MEMORY_MANAGED(StandardAssembler);
/// Constructor
StandardAssembler(Operator *op,
Quadrature *quad2,
Quadrature *quad1GrdPsi,
Quadrature *quad1GrdPhi,
Quadrature *quad0,
const FiniteElemSpace *rowFESpace,
const FiniteElemSpace *colFESpace = NULL);
};
// ============================================================================
// ===== class OptimizedAssembler =============================================
// ============================================================================
/**
* \ingroup Assembler
*
* \brief
* Assembler using optimized sub assemblers.
*/
class OptimizedAssembler : public Assembler
{
public:
MEMORY_MANAGED(OptimizedAssembler);
/// Constructor
OptimizedAssembler(Operator *op,
Quadrature *quad2,
Quadrature *quad1GrdPsi,
Quadrature *quad1GrdPhi,
Quadrature *quad0,
const FiniteElemSpace *rowFESpace,
const FiniteElemSpace *colFESpace = NULL);
};
}
#endif // AMDIS_ASSEMBLER_H