diff --git a/AMDiS/src/DirichletBC.hh b/AMDiS/src/DirichletBC.hh new file mode 100644 index 0000000000000000000000000000000000000000..103e8782090244367405383ba7e241a4e2b8c8f5 --- /dev/null +++ b/AMDiS/src/DirichletBC.hh @@ -0,0 +1,156 @@ +/****************************************************************************** + * + * 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(); + } + +}