-
Naumann, Andreas authoredNaumann, Andreas authored
SystemVector.h 11.43 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 SystemVector.h */
#ifndef AMDIS_SYSTEMVECTOR_H
#define AMDIS_SYSTEMVECTOR_H
#include "MatrixVector.h"
#include "DOFVector.h"
#include "CreatorInterface.h"
#include "Serializable.h"
#include "Serializer.h"
namespace AMDiS {
/// A system vector is a vector of dof vectors used for vector valued problems.
class SystemVector : public Serializable
{
public:
/// Constructor.
SystemVector(std::string name_,
std::vector<FiniteElemSpace*> feSpace_,
int size)
: name(name_),
feSpace(feSpace_),
vectors(size)
{
vectors.set(NULL);
}
/// Copy Constructor.
SystemVector(const SystemVector& rhs)
: name(rhs.name),
feSpace(rhs.feSpace),
vectors(rhs.vectors.getSize())
{
for (int i = 0; i < vectors.getSize(); i++)
vectors[i] = new DOFVector<double>(*rhs.vectors[i]);
}
~SystemVector()
{
for (int i = 0; i < vectors.getSize(); i++)
delete vectors[i];
}
void createNewDOFVectors(std::string name)
{
for (int i = 0; i < vectors.getSize(); i++)
vectors[i] = new DOFVector<double>(feSpace[i], "tmp");
}
/// Sets \ref vectors[index] = vec.
inline void setDOFVector(int index, DOFVector<double> *vec)
{
TEST_EXIT_DBG(index < vectors.getSize())("invalid index\n");
vectors[index] = vec;
}
/// Returns \ref vectors[index].
inline DOFVector<double> *getDOFVector(int index)
{
TEST_EXIT_DBG(index < vectors.getSize())("invalid index\n");
return vectors[index];
}
/// Returns \ref vectors[index].
inline const DOFVector<double> *getDOFVector(int index) const
{
TEST_EXIT_DBG(index < vectors.getSize())("invalid index\n");
return vectors[index];
}
/// Returns sum of used vector sizes.
inline int getUsedSize() const
{
int totalSize = 0;
int size = vectors.getSize();
for (int i = 0; i < size; i++)
totalSize += vectors[i]->getUsedSize();
return totalSize;
}
/// Returns number of contained vectors.
inline int getNumVectors() const
{
return vectors.getSize();
}
inline int getSize() const
{
return vectors.getSize();
}
/// Returns the fe space for a given component.
inline FiniteElemSpace *getFeSpace(int i) const
{
return feSpace[i];
}
/// Returns the fe spaces for all components.
inline std::vector<FiniteElemSpace*> getFeSpaces() const
{
return feSpace;
}
/** \brief
* Here the system vector is interpreted as one large vector. The given
* is used as a global index which indicates a local vector number and
* a local index on this vector. The operator returns this local vector
* at the local index.
*/
inline double& operator[](int index)
{
int localIndex = index;
int vectorIndex = 0;
while (localIndex >= vectors[vectorIndex]->getUsedSize()) {
localIndex -= vectors[vectorIndex++]->getUsedSize();
}
return (*(vectors[vectorIndex]))[localIndex];
}
/// For const access.
inline double operator[](int index) const
{
int localIndex = index;
int vectorIndex = 0;
while (localIndex >= vectors[vectorIndex]->getUsedSize()) {
localIndex -= vectors[vectorIndex++]->getUsedSize();
}
return (*(vectors[vectorIndex]))[localIndex];
}
/// Sets all entries in all vectors to value.
inline void set(double value)
{
int size = vectors.getSize();
for (int i = 0; i < size; i++)
vectors[i]->set(value);
}
inline void setCoarsenOperation(CoarsenOperation op)
{
for (int i = 0; i < static_cast<int>(vectors.getSize()); i++)
vectors[i]->setCoarsenOperation(op);
}
/// Sets all entries in all vectors to value.
inline SystemVector& operator=(double value)
{
int size = vectors.getSize();
for (int i = 0; i < size; i++)
(*(vectors[i])) = value;
return *this;
}
/// Assignement operator.
inline SystemVector& operator=(const SystemVector& rhs)
{
TEST_EXIT_DBG(rhs.vectors.getSize() == vectors.getSize())("invalied sizes\n");
int size = vectors.getSize();
for (int i = 0; i < size; i++)
(*(vectors[i])) = (*(rhs.getDOFVector(i)));
return *this;
}
void serialize(std::ostream &out)
{
int size = vectors.getSize();
SerUtil::serialize(out, size);
for (int i = 0; i < size; i++)
vectors[i]->serialize(out);
}
void deserialize(std::istream &in)
{
int size, oldSize = vectors.getSize();
SerUtil::deserialize(in, size);
vectors.resize(size);
for (int i = oldSize; i < size; i++)
vectors[i] = new DOFVector<double>(feSpace[i], "");
for (int i = 0; i < size; i++)
vectors[i]->deserialize(in);
}
void copy(const SystemVector& rhs)
{
int size = vectors.getSize();
TEST_EXIT_DBG(size == rhs.getNumVectors())("invalid sizes\n");
for (int i = 0; i < size; i++)
vectors[i]->copy(*(const_cast<SystemVector&>(rhs).getDOFVector(i)));
}
void interpol(std::vector<AbstractFunction<double, WorldVector<double> >*> *f)
{
int size = vectors.getSize();
for (int i = 0; i < size; i++)
vectors[i]->interpol((*f)[i]);
}
void interpol(SystemVector *v, double factor)
{
for (int i = 0; i < v->getSize(); i++)
vectors[i]->interpol(v->getDOFVector(i), factor);
}
void print()
{
int size = vectors.getSize();
for (int i = 0; i < size; i++)
vectors[i]->print();
}
int calcMemoryUsage()
{
int result = 0;
for (int i = 0; i < static_cast<int>(vectors.getSize()); i++)
result += vectors[i]->calcMemoryUsage();
result += sizeof(SystemVector);
return result;
}
protected:
/// Name of the system vector
std::string name;
/// Finite element space.
std::vector<FiniteElemSpace*> feSpace;
/// Local dof vectors.
Vector<DOFVector<double>*> vectors;
};
/// multiplication with scalar
inline const SystemVector& operator*=(SystemVector& x, double d)
{
int size = x.getNumVectors();
for (int i = 0; i < size; i++)
*(x.getDOFVector(i)) *= d;
return x;
}
/// scalar product
inline double operator*(SystemVector& x, SystemVector& y)
{
TEST_EXIT_DBG(x.getNumVectors() == y.getNumVectors())("invalid size\n");
double result = 0.0;
int size = x.getNumVectors();
for (int i = 0; i < size; i++)
result += (*x.getDOFVector(i)) * (*y.getDOFVector(i));
return result;
}
/// addition of two system vectors
inline const SystemVector& operator+=(SystemVector& x, const SystemVector& y)
{
TEST_EXIT_DBG(x.getNumVectors() == y.getNumVectors())("invalid size\n");
int size = x.getNumVectors();
for (int i = 0; i < size; i++)
(*(x.getDOFVector(i))) += (*(y.getDOFVector(i)));
return x;
}
/// subtraction of two system vectors.
inline const SystemVector& operator-=(SystemVector& x, SystemVector& y)
{
TEST_EXIT_DBG(x.getNumVectors() == y.getNumVectors())("invalid size\n");
int size = x.getNumVectors();
for (int i = 0; i < size; i++)
(*(x.getDOFVector(i))) -= (*(y.getDOFVector(i)));
return x;
}
/// multiplication with a scalar
inline SystemVector operator*(SystemVector& x, double d)
{
SystemVector result = x;
int size = x.getNumVectors();
for (int i = 0; i < size; i++)
(*(result.getDOFVector(i))) *= d;
return result;
}
/// multiplication with a scalar
inline SystemVector operator*(double d, SystemVector& x)
{
SystemVector result = x;
int size = x.getNumVectors();
for (int i = 0; i < size; i++)
(*(result.getDOFVector(i))) *= d;
return result;
}
/// addition of two system vectors
inline SystemVector operator+(const SystemVector& x, const SystemVector& y)
{
TEST_EXIT_DBG(x.getNumVectors() == y.getNumVectors())("invalid size\n");
SystemVector result = x;
int size = x.getNumVectors();
for (int i = 0; i < size; i++)
(*(result.getDOFVector(i))) += (*(y.getDOFVector(i)));
return result;
}
/// Calls SystemVector::set(). Used for solving.
inline void set(SystemVector& x, double value)
{
x.set(value);
}
/// Calls SystemVector::set(). Used for solving.
inline void setValue(SystemVector& x, double value)
{
x.set(value);
}
/// Norm of system vector.
inline double norm(SystemVector* x)
{
double result = 0.0;
int size = x->getNumVectors();
for (int i = 0; i < size; i++)
result += x->getDOFVector(i)->squareNrm2();
return sqrt(result);
}
/// L2 norm of system vector.
inline double L2Norm(SystemVector* x)
{
double result = 0.0;
int size = x->getNumVectors();
for (int i = 0; i < size; i++)
result += x->getDOFVector(i)->L2NormSquare();
return sqrt(result);
}
/// H1 norm of system vector.
inline double H1Norm(SystemVector* x)
{
double result = 0.0;
int size = x->getNumVectors();
for (int i = 0; i < size; i++)
result += x->getDOFVector(i)->H1NormSquare();
return sqrt(result);
}
inline void mv(Matrix<DOFMatrix*> &matrix,
const SystemVector &x,
SystemVector &result,
bool add = false)
{
FUNCNAME("mv()");
TEST_EXIT(false)("This function is not supported any more.\n");
#if 0
int size = x.getNumVectors();
int i;
TEST_EXIT_DBG(size == result.getNumVectors())("incompatible sizes\n");
TEST_EXIT_DBG(size == matrix.getNumRows())("incompatible sizes\n");
TEST_EXIT_DBG(size == matrix.getNumCols())("incompatible sizes\n");
for (i = 0; i < size; i++) {
if (!add)
result.getDOFVector(i)->set(0.0);
for (int j = 0; j < size; j++)
if (matrix[i][j])
mv<double>(NoTranspose,
*(matrix[i][j]),
*(x.getDOFVector(j)),
*(result.getDOFVector(i)),
true);
}
#endif
}
/// y = a*x + y;
inline void axpy(double a, SystemVector& x, SystemVector& y)
{
TEST_EXIT_DBG(x.getNumVectors() == y.getNumVectors())
("invalid size\n");
int size = x.getNumVectors();
int i;
for (i = 0; i < size; i++)
axpy(a, *(x.getDOFVector(i)), *(y.getDOFVector(i)));
}
/// y = x + a*y
inline void xpay(double a, SystemVector& x, SystemVector& y)
{
TEST_EXIT_DBG(x.getNumVectors() == y.getNumVectors())
("invalid size\n");
int size = x.getNumVectors();
for (int i = 0; i < size; i++)
xpay(a, *(x.getDOFVector(i)), *(y.getDOFVector(i)));
}
/// Returns SystemVector::getUsedSize().
inline int size(SystemVector* vec)
{
return vec->getUsedSize();
}
inline void print(SystemVector* vec)
{
vec->print();
}
}
#endif // AMDIS_SYSTEMVECTOR_H