// ============================================================================ // == == // == 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