-
Thomas Witkowski authoredThomas Witkowski authored
Assembler.h 8.04 KiB
// ============================================================================
// == ==
// == AMDiS - Adaptive multidimensional simulations ==
// == ==
// == http://www.amdis-fem.org ==
// == ==
// ============================================================================
//
// Software License for AMDiS
//
// Copyright (c) 2010 Dresden University of Technology
// All rights reserved.
// Authors: Simon Vey, Thomas Witkowski et al.
//
// This file is part of AMDiS
//
// See also license.opensource.txt in the distribution.
/** \file Assembler.h */
/**
* \defgroup Assembler Assembler module
*
* \brief
* Contains the operator and assembler classes:
* @{ <img src="assembler.png"> @}
*/
#ifndef AMDIS_ASSEMBLER_H
#define AMDIS_ASSEMBLER_H
#include <vector>
#include "AMDiS_fwd.h"
#include "FixVec.h"
#include "ZeroOrderAssembler.h"
#include "FirstOrderAssembler.h"
#include "SecondOrderAssembler.h"
#include "ElInfo.h"
namespace AMDiS {
/**
* \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:
/// Constructor
Assembler(Operator *op,
const FiniteElemSpace *rowFeSpace,
const FiniteElemSpace *colFeSpace = NULL);
/// Destructor
~Assembler();
/// 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,
bool rowColFeSpaceEqual,
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;
///
ElementMatrix tmpMat;
/** \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;
};
/**
* \ingroup Assembler
*
* \brief
* Assembler using non optimized sub assemblers.
*/
class StandardAssembler : public Assembler
{
public:
/// Constructor
StandardAssembler(Operator *op,
Quadrature *quad2,
Quadrature *quad1GrdPsi,
Quadrature *quad1GrdPhi,
Quadrature *quad0,
const FiniteElemSpace *rowFeSpace,
const FiniteElemSpace *colFeSpace = NULL);
};
/**
* \ingroup Assembler
*
* \brief
* Assembler using optimized sub assemblers.
*/
class OptimizedAssembler : public Assembler
{
public:
/// Constructor
OptimizedAssembler(Operator *op,
Quadrature *quad2,
Quadrature *quad1GrdPsi,
Quadrature *quad1GrdPhi,
Quadrature *quad0,
const FiniteElemSpace *rowFeSpace,
const FiniteElemSpace *colFeSpace = NULL);
};
}
#endif // AMDIS_ASSEMBLER_H