diff --git a/AMDiS/CMakeLists.txt b/AMDiS/CMakeLists.txt index 3c47732616a876457e1bd1d74d2e9472a59288d7..82db8adeee927bd778e27aaf774280005109abd6 100644 --- a/AMDiS/CMakeLists.txt +++ b/AMDiS/CMakeLists.txt @@ -97,7 +97,7 @@ SET(AMDIS_SRC ${SOURCE_DIR}/AdaptBase.cc ${SOURCE_DIR}/DOFMatrix.cc ${SOURCE_DIR}/DOFVector.cc ${SOURCE_DIR}/Debug.cc -# ${SOURCE_DIR}/DirichletBC.cc + ${SOURCE_DIR}/DirichletBC.cc ${SOURCE_DIR}/DualTraverse.cc ${SOURCE_DIR}/ElInfo.cc ${SOURCE_DIR}/ElInfo1d.cc diff --git a/AMDiS/src/DirichletBC.cc b/AMDiS/src/DirichletBC.cc index 1d331dba4dab8465a8e8acf71684c413b1721fd4..20a3d20c9498e09492eb7cf84a92ae6777b85ce0 100644 --- a/AMDiS/src/DirichletBC.cc +++ b/AMDiS/src/DirichletBC.cc @@ -26,77 +26,89 @@ #include "DOFMatrix.h" namespace AMDiS { - - DirichletBC::DirichletBC(BoundaryType type, - AbstractFunction<double, WorldVector<double> > *fct, - const FiniteElemSpace *rowFeSpace, - const FiniteElemSpace *colFeSpace, - bool apply) - : BoundaryCondition(type, rowFeSpace, colFeSpace), - f(fct), - dofVec(NULL), - applyBC(apply) - {} - - - DirichletBC::DirichletBC(BoundaryType type, - DOFVectorBase<double> *vec, - bool apply) - : BoundaryCondition(type, vec->getFeSpace(), vec->getFeSpace()), - f(NULL), - dofVec(vec), - applyBC(apply) - {} - - - void DirichletBC::fillBoundaryCondition(DOFMatrix* matrix, - ElInfo* elInfo, - const DegreeOfFreedom* dofIndices, - const BoundaryType* localBound, - int nBasFcts) + + namespace detail { + + void DirichletBC::fillBoundaryCondition(DOFMatrix* matrix, + ElInfo* elInfo, + const DegreeOfFreedom* dofIndices, + const BoundaryType* localBound, + int nBasFcts) + { + FUNCNAME_DBG("DirichletBC::fillBoundaryCondition()"); + TEST_EXIT_DBG(matrix->getRowFeSpace() == rowFeSpace)("invalid row fe space\n"); + } + + void DirichletBC::initVector(DOFVectorBase<double>* vec) + { + if (dynamic_cast<DOFVector<double>*>(vec)) + dynamic_cast<DOFVector<double>*>(vec)->getDirichletValues().clear(); + } + } + + + DirichletBC<_value_by_dofvector>::DirichletBC( + BoundaryType type, + DOFVectorBase<double> *vec, + bool apply) + : super(type, vec->getFeSpace(), vec->getFeSpace(), apply), + container(vec) + { } + + + void DirichletBC<_value_by_dofvector>::fillBoundaryCondition( + DOFVectorBase<double>* vector, + ElInfo* elInfo, + const DegreeOfFreedom* dofIndices, + const BoundaryType* localBound, + int nBasFcts) { - FUNCNAME_DBG("DirichletBC::fillBoundaryCondition()"); - TEST_EXIT_DBG(matrix->getRowFeSpace() == rowFeSpace)("invalid row fe space\n"); + for (int i = 0; i < nBasFcts; i++) + if (localBound[i] == boundaryType) { + double value = (*container)[dofIndices[i]]; + vector->setDirichletDofValue(dofIndices[i], value); + (*vector)[dofIndices[i]] = value; + } } - - - void DirichletBC::fillBoundaryCondition(DOFVectorBase<double>* vector, - ElInfo* elInfo, - const DegreeOfFreedom* dofIndices, - const BoundaryType* localBound, - int nBasFcts) + + + // c++11 std::function of lambda-functions + void DirichletBC<_value_by_function>::fillBoundaryCondition( + DOFVectorBase<double>* vector, + ElInfo* elInfo, + const DegreeOfFreedom* dofIndices, + const BoundaryType* localBound, + int nBasFcts) { - FUNCNAME("DirichletBC::fillBoundaryCondition()"); - - TEST_EXIT_DBG(vector->getFeSpace() == rowFeSpace)("invalid row fe space\n"); - + WorldVector<double> worldCoords; const BasisFunction *basFcts = rowFeSpace->getBasisFcts(); - if (f) { - for (int i = 0; i < nBasFcts; i++) - if (localBound[i] == boundaryType) { - elInfo->coordToWorld(*(basFcts->getCoords(i)), worldCoords); - double value = (*f)(worldCoords); - vector->setDirichletDofValue(dofIndices[i], value); - (*vector)[dofIndices[i]] = value; - } - } else if (dofVec) { - for (int i = 0; i < nBasFcts; i++) - if (localBound[i] == boundaryType) { - double value = value = (*dofVec)[dofIndices[i]]; - vector->setDirichletDofValue(dofIndices[i], value); - (*vector)[dofIndices[i]] = value; - } - } else { - ERROR_EXIT("No data provided to assemble DirichletBC!\n"); - } + for (int i = 0; i < nBasFcts; i++) + if (localBound[i] == boundaryType) { + elInfo->coordToWorld(*(basFcts->getCoords(i)), worldCoords); + double value = container(worldCoords); + vector->setDirichletDofValue(dofIndices[i], value); + (*vector)[dofIndices[i]] = value; + } } - - void DirichletBC::initVector(DOFVectorBase<double>* vec) + + void DirichletBC<_value_by_abstractfunction>::fillBoundaryCondition( + DOFVectorBase<double>* vector, + ElInfo* elInfo, + const DegreeOfFreedom* dofIndices, + const BoundaryType* localBound, + int nBasFcts) { - if (dynamic_cast<DOFVector<double>*>(vec)) - dynamic_cast<DOFVector<double>*>(vec)->getDirichletValues().clear(); - } + WorldVector<double> worldCoords; + const BasisFunction *basFcts = rowFeSpace->getBasisFcts(); + for (int i = 0; i < nBasFcts; i++) + if (localBound[i] == boundaryType) { + elInfo->coordToWorld(*(basFcts->getCoords(i)), worldCoords); + double value = container(worldCoords); + vector->setDirichletDofValue(dofIndices[i], value); + (*vector)[dofIndices[i]] = value; + } + } } diff --git a/AMDiS/src/DirichletBC.h b/AMDiS/src/DirichletBC.h index e30a5edb126892d5a67c4c41b6531c55727a4e95..79ae650787f450ca1161dcca5c7ed93dd1f24f80 100644 --- a/AMDiS/src/DirichletBC.h +++ b/AMDiS/src/DirichletBC.h @@ -40,142 +40,155 @@ namespace AMDiS namespace detail { - template <class Tag> - struct ValueContainer {}; + class DirichletBC : public BoundaryCondition + { + public: + + /// Constructor. + DirichletBC(BoundaryType type, + const FiniteElemSpace *rowFeSpace, + const FiniteElemSpace *colFeSpace, + bool apply) + : BoundaryCondition(type, rowFeSpace, colFeSpace), + applyBC(apply) + { } + + /// Implementation of BoundaryCondition::fillBoundaryCondition(). + virtual void fillBoundaryCondition(DOFMatrix* matrix, + ElInfo* elInfo, + const DegreeOfFreedom* dofIndices, + const BoundaryType* localBound, + int nBasFcts) override; + + /// + void initVector(DOFVectorBase<double>* vec); + + /// Implementation of BoundaryCondition::boundResidual(). + double boundResidual(ElInfo*, + DOFMatrix *, + const DOFVectorBase<double>*) + { + return 0.0; + } + + /// Because this is a Dirichlet boundary condition, always return true. + bool isDirichlet() + { + return true; + } + + /// Returns \ref applyBC. + bool applyBoundaryCondition() + { + return applyBC; + } + + protected: + + /// Defines, if the boundary condition must be applied to the matrix. See + /// comment of \ref BoundaryCondition::applyBoundaryCondition. + bool applyBC; + }; + + } // end namespace detail + + + + + /** + * \ingroup Assembler + * + * \brief + * Sub class of BoundaryCondition. Implements Dirichlet boundary conditions. + * A DOFVectors is set to a given value at a Dirichlet dof and in a DOFMatrix + * the row corresponding to a Dirichlet dof is replaced by a row containing + * only a 1.0 in the diagonal. + */ + template <class ValueTag> + class DirichletBC {}; + // specialization for AbstractFunctions as value container template <> - struct ValueContainer<_value_by_abstractfunction> + class DirichletBC<_value_by_abstractfunction> : public detail::DirichletBC { - ValueContainer(AbstractFunction<double, WorldVector<double> > *fct) : value(*fct) {}; - ValueContainer(AbstractFunction<double, WorldVector<double> > &fct) : value(fct) {}; + typedef detail::DirichletBC super; + public: + /// Constructor. + DirichletBC(BoundaryType type, + AbstractFunction<double, WorldVector<double> > *fct, + const FiniteElemSpace *rowFeSpace, + const FiniteElemSpace *colFeSpace = NULL, + bool apply = true) + : super(type, rowFeSpace, colFeSpace, apply), + container(*fct) + { } - AbstractFunction<double, WorldVector<double> > &value; + + /// Implementation of BoundaryCondition::fillBoundaryCondition(). + virtual void fillBoundaryCondition(DOFVectorBase<double>* vector, + ElInfo* elInfo, + const DegreeOfFreedom* dofIndices, + const BoundaryType* localBound, + int nBasFcts) override; + + protected: + AbstractFunction<double, WorldVector<double> > &container; }; + + // specialization for DOFVectors as value container template <> - struct ValueContainer<_value_by_dofvector> + class DirichletBC<_value_by_dofvector> : public detail::DirichletBC { - ValueContainer(DOFVectorBase<double> *vec) : value(vec) {}; - ValueContainer(DOFVectorBase<double> &vec) : value(&vec) {}; + typedef detail::DirichletBC super; + public: + /// Constructor. + DirichletBC(BoundaryType type, + DOFVectorBase<double> *vec, + bool apply = true); - DOFVectorBase<double> *value; + + /// Implementation of BoundaryCondition::fillBoundaryCondition(). + virtual void fillBoundaryCondition(DOFVectorBase<double>* vector, + ElInfo* elInfo, + const DegreeOfFreedom* dofIndices, + const BoundaryType* localBound, + int nBasFcts) override; + + protected: + DOFVectorBase<double> *container; }; + #if __cplusplus > 199711L + // specialization for std::function or lambdas as value container template <> - struct ValueContainer<_value_by_function> + class DirichletBC<_value_by_function> : public detail::DirichletBC { - ValueContainer(std::function<double(WorldVector<double>)> fct) : value(fct) {}; + typedef detail::DirichletBC super; + public: + /// Constructor. + DirichletBC(BoundaryType type, + std::function<double(WorldVector<double>)> fct, + const FiniteElemSpace *rowFeSpace, + const FiniteElemSpace *colFeSpace = NULL, + bool apply = true) + : super(type, rowFeSpace, colFeSpace, apply), + container(fct) + { } - std::function<double(WorldVector<double>)> value; + + /// Implementation of BoundaryCondition::fillBoundaryCondition(). + virtual void fillBoundaryCondition(DOFVectorBase<double>* vector, + ElInfo* elInfo, + const DegreeOfFreedom* dofIndices, + const BoundaryType* localBound, + int nBasFcts) override; + + protected: + std::function<double(WorldVector<double>)> container; }; #endif - - } // end namespace detail - - /** - * \ingroup Assembler - * - * \brief - * Sub class of BoundaryCondition. Implements Dirichlet boundary conditions. - * A DOFVectors is set to a given value at a Dirichlet dof and in a DOFMatrix - * the row corresponding to a Dirichlet dof is replaced by a row containing - * only a 1.0 in the diagonal. - */ - template <class ValueTag> - class DirichletBC : public BoundaryCondition - { - public: - /// Constructor. - DirichletBC(BoundaryType type, - AbstractFunction<double, WorldVector<double> > *fct, - const FiniteElemSpace *rowFeSpace, - const FiniteElemSpace *colFeSpace = NULL, - bool apply = true); - -#if __cplusplus > 199711L - /// Constructor. - DirichletBC(BoundaryType type, - std::function<double(WorldVector<double>)> fct, - const FiniteElemSpace *rowFeSpace, - const FiniteElemSpace *colFeSpace = NULL, - bool apply = true); -#endif - - /// Constructor. - DirichletBC(BoundaryType type, - DOFVectorBase<double> *vec, - bool apply = true); - - /// Implementation of BoundaryCondition::fillBoundaryCondition(). - virtual void fillBoundaryCondition(DOFMatrix* matrix, - ElInfo* elInfo, - const DegreeOfFreedom* dofIndices, - const BoundaryType* localBound, - int nBasFcts) override; - - /// Implementation of BoundaryCondition::fillBoundaryCondition(). - virtual void fillBoundaryCondition(DOFVectorBase<double>* vector, - ElInfo* elInfo, - const DegreeOfFreedom* dofIndices, - const BoundaryType* localBound, - int nBasFcts) override; - - /// - void initVector(DOFVectorBase<double>*); - - /// Implementation of BoundaryCondition::boundResidual(). - double boundResidual(ElInfo*, - DOFMatrix *, - const DOFVectorBase<double>*) - { - return 0.0; - } - - /// Because this is a Dirichlet boundary condition, always return true. - bool isDirichlet() - { - return true; - } - - /// Returns \ref applyBC. - bool applyBoundaryCondition() - { - return applyBC; - } - - protected: - void fillBC(_value_by_abstractfunction, - DOFVectorBase<double>* vector, - ElInfo* elInfo, - const DegreeOfFreedom* dofIndices, - const BoundaryType* localBound, - int nBasFcts); - - void fillBC(_value_by_function, - DOFVectorBase<double>* vector, - ElInfo* elInfo, - const DegreeOfFreedom* dofIndices, - const BoundaryType* localBound, - int nBasFcts); - - void fillBC(_value_by_dofvector, - DOFVectorBase<double>* vector, - ElInfo* elInfo, - const DegreeOfFreedom* dofIndices, - const BoundaryType* localBound, - int nBasFcts); - - protected: - detail::ValueContainer<ValueTag> container; - - /// Defines, if the boundary condition must be applied to the matrix. See - /// comment of \ref BoundaryCondition::applyBoundaryCondition. - bool applyBC; - }; - } -#include "DirichletBC.hh" - #endif diff --git a/AMDiS/src/DirichletBC.hh b/AMDiS/src/DirichletBC.hh deleted file mode 100644 index 103e8782090244367405383ba7e241a4e2b8c8f5..0000000000000000000000000000000000000000 --- a/AMDiS/src/DirichletBC.hh +++ /dev/null @@ -1,156 +0,0 @@ -/****************************************************************************** - * - * AMDiS - Adaptive multidimensional simulations - * - * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. - * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis - * - * Authors: - * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * - * This file is part of AMDiS - * - * See also license.opensource.txt in the distribution. - * - ******************************************************************************/ - - -#include "ElInfo.h" -#include "BasisFunction.h" -#include "DOFVector.h" -#include "DOFMatrix.h" - -namespace AMDiS { - - template <class Tag> - DirichletBC<Tag>::DirichletBC(BoundaryType type, - AbstractFunction<double, WorldVector<double> > *fct, - const FiniteElemSpace *rowFeSpace, - const FiniteElemSpace *colFeSpace, - bool apply) - : BoundaryCondition(type, rowFeSpace, colFeSpace), - container(fct), - applyBC(apply) - {} - -#if __cplusplus > 199711L - template <class Tag> - DirichletBC<Tag>::DirichletBC(BoundaryType type, - std::function<double(WorldVector<double>)> fct, - const FiniteElemSpace *rowFeSpace, - const FiniteElemSpace *colFeSpace, - bool apply) - : BoundaryCondition(type, rowFeSpace, colFeSpace), - container(fct), - applyBC(apply) - {} -#endif - - template <class Tag> - DirichletBC<Tag>::DirichletBC(BoundaryType type, - DOFVectorBase<double> *vec, - bool apply) - : BoundaryCondition(type, vec->getFeSpace(), vec->getFeSpace()), - container(vec), - applyBC(apply) - {} - - - template <class Tag> - void DirichletBC<Tag>::fillBoundaryCondition(DOFMatrix* matrix, - ElInfo* elInfo, - const DegreeOfFreedom* dofIndices, - const BoundaryType* localBound, - int nBasFcts) - { - FUNCNAME_DBG("DirichletBC::fillBoundaryCondition()"); - TEST_EXIT_DBG(matrix->getRowFeSpace() == rowFeSpace)("invalid row fe space\n"); - } - - - template <class Tag> - void DirichletBC<Tag>::fillBoundaryCondition(DOFVectorBase<double>* vector, - ElInfo* elInfo, - const DegreeOfFreedom* dofIndices, - const BoundaryType* localBound, - int nBasFcts) - { - FUNCNAME_DBG("DirichletBC::fillBoundaryCondition()"); - - TEST_EXIT_DBG(vector->getFeSpace() == rowFeSpace)("invalid row fe space\n"); - fillBC(Tag(), vector, elInfo, dofIndices, localBound, nBasFcts); - } - - - template <class Tag> - void DirichletBC<Tag>::fillBC(_value_by_abstractfunction, - DOFVectorBase<double>* vector, - ElInfo* elInfo, - const DegreeOfFreedom* dofIndices, - const BoundaryType* localBound, - int nBasFcts) - { - WorldVector<double> worldCoords; - const BasisFunction *basFcts = rowFeSpace->getBasisFcts(); - - for (int i = 0; i < nBasFcts; i++) - if (localBound[i] == boundaryType) { - elInfo->coordToWorld(*(basFcts->getCoords(i)), worldCoords); - double value = container.value(worldCoords); - vector->setDirichletDofValue(dofIndices[i], value); - (*vector)[dofIndices[i]] = value; - } - } - - - // c++11 std::function of lambda-functions - template <class Tag> - void DirichletBC<Tag>::fillBC(_value_by_function, - DOFVectorBase<double>* vector, - ElInfo* elInfo, - const DegreeOfFreedom* dofIndices, - const BoundaryType* localBound, - int nBasFcts) - { - WorldVector<double> worldCoords; - const BasisFunction *basFcts = rowFeSpace->getBasisFcts(); - - for (int i = 0; i < nBasFcts; i++) - if (localBound[i] == boundaryType) { - elInfo->coordToWorld(*(basFcts->getCoords(i)), worldCoords); - double value = container.value(worldCoords); - vector->setDirichletDofValue(dofIndices[i], value); - (*vector)[dofIndices[i]] = value; - } - } - - - template <class Tag> - void DirichletBC<Tag>::fillBC(_value_by_dofvector, - DOFVectorBase<double>* vector, - ElInfo* elInfo, - const DegreeOfFreedom* dofIndices, - const BoundaryType* localBound, - int nBasFcts) - { - for (int i = 0; i < nBasFcts; i++) - if (localBound[i] == boundaryType) { - double value = (*container.value)[dofIndices[i]]; - vector->setDirichletDofValue(dofIndices[i], value); - (*vector)[dofIndices[i]] = value; - } - } - - - template <class Tag> - void DirichletBC<Tag>::initVector(DOFVectorBase<double>* vec) - { - if (dynamic_cast<DOFVector<double>*>(vec)) - dynamic_cast<DOFVector<double>*>(vec)->getDirichletValues().clear(); - } - -}