Commit 2c1e3427 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

NULL replaced by nullptr and a lot of small changes

parent 02ff3473
...@@ -53,6 +53,20 @@ namespace experimental { ...@@ -53,6 +53,20 @@ namespace experimental {
typedef std::pair<DegreeOfFreedom, PointType> DataType; typedef std::pair<DegreeOfFreedom, PointType> DataType;
/** \brief Background-mesh structure
* Can be used to find k nearest neighbors to a given point. It uses a one
* level background-mesh to look for a box where the point lies inside and
* compares the distance to all other points in the box, respective with the
* points in the surrounding boxes.
* The point to look for are stores as DataType-objects, e.g. pairs of
* DOF-indices and coordinates. This makes it possible to evaluated DOFVectors
* at the found points.
*
* To use this class call Box::provideBackgroundMesh(feSpace) with feSpace
* a FiniteElemSpace holding all the degrees of freedom you want to look for.
* Or add an individual fillBox method that adds all the data points in the
* form of DataType to the box by calling addData for each point.
**/
struct Box { struct Box {
Box(int DOW_, std::vector<int> N_); Box(int DOW_, std::vector<int> N_);
......
...@@ -22,7 +22,9 @@ ...@@ -22,7 +22,9 @@
#include "AMDiS.h" #include "AMDiS.h"
#include "Tools.h" #include "Tools.h"
#ifndef USE_EXPERIMENTAL
#define USE_EXPERIMENTAL #define USE_EXPERIMENTAL
#endif
namespace experimental { namespace experimental {
...@@ -30,9 +32,34 @@ typedef WorldVector<double> PointType_; ...@@ -30,9 +32,34 @@ typedef WorldVector<double> PointType_;
typedef boost::tuple<const MacroElement*, int, unsigned long> ElInfoDataType; // data to recover elInfo typedef boost::tuple<const MacroElement*, int, unsigned long> ElInfoDataType; // data to recover elInfo
typedef std::pair<ElInfoDataType, PointType_> DataType_; typedef std::pair<ElInfoDataType, PointType_> DataType_;
template<typename PointType, typename DataType> // PointType ... type of coordinate vectors, e.g. WorldVector<double> in AMDiS
// DataType .... use DataType_ to look for ElInfos near coordinates
/** \brief Background-mesh structure for finding elements
* Can be used to find k nearest elements to a given point. It uses a one
* level background-mesh to look for a box where the point lies inside and
* compares the distance to all element centers in the box, respective with the
* elements in the surrounding boxes.
* The elements to look for are stores as DataType-objects, e.g. tuples of
* MacroElement*, refinementPath and refinementPathLength. This makes it
* possible to create a new ElInfo object from the mesh.
*
* To use this class call ElementBox<P,D>::provideBackgroundMesh(feSpace) with
* feSpace a FiniteElemSpace holding the mesh with all elements you want to look for.
* The template-arguments correspond to coordinate-vector type P and D a type
* in wich the elInfo is stored. Use PointType_ and DataType_ as defaults.
* Or add an individual fillBox method that adds all the elements in the
* form of DataType to the box by calling addData for each element.
**/
template<typename PointType=PointType_, typename DataType=DataType_>
struct ElementBox { struct ElementBox {
/** \brief Constructor for BackgroundMesh
* Mesh is enclosed in default box [-1,1]^2.
*
* \param DOW_ dimension of world
* \param N_ vector containing number of boxes per dimension [Nx,Ny,Nz]
**/
ElementBox(int DOW_, std::vector<int> N_) ElementBox(int DOW_, std::vector<int> N_)
: DOW(DOW_), N(N_), boxFilled(false) : DOW(DOW_), N(N_), boxFilled(false)
{ {
...@@ -41,6 +68,14 @@ struct ElementBox { ...@@ -41,6 +68,14 @@ struct ElementBox {
init(); init();
} }
/** \brief Constructor for BackgroundMesh
* Mesh is enclosed in a box given by the user.
*
* \param DOW_ dimension of world
* \param min_corner_ lower-left[-front] corner of enclosing box
* \param max_corner_ upper-right[-back] corner of enclosing box
* \param N_ vector containing number of boxes per dimension [Nx,Ny,Nz]
**/
ElementBox(int DOW_, PointType min_corner_, PointType max_corner_, std::vector<int> N_) ElementBox(int DOW_, PointType min_corner_, PointType max_corner_, std::vector<int> N_)
: DOW(DOW_), : DOW(DOW_),
min_corner(min_corner_), min_corner(min_corner_),
...@@ -50,15 +85,19 @@ struct ElementBox { ...@@ -50,15 +85,19 @@ struct ElementBox {
init(); init();
} }
/// add all elements of mesh corresponding to the feSpace to the background-mesh
void fillBox(const FiniteElemSpace* feSpace); void fillBox(const FiniteElemSpace* feSpace);
/// delete and clear all boxes
void clearBox() void clearBox()
{ {
boxData.clear(); boxData.clear();
} }
/// calculate boxSize
int getMaxBoxSize() int getMaxBoxSize()
{ {
size_t maxSize = 0; size_t maxSize = 0;
...@@ -69,6 +108,7 @@ struct ElementBox { ...@@ -69,6 +108,7 @@ struct ElementBox {
} }
/// test of point x lies in current box
bool inBox(PointType& x) bool inBox(PointType& x)
{ {
for (size_t i = 0; i < DOW; i++) for (size_t i = 0; i < DOW; i++)
...@@ -96,9 +136,14 @@ struct ElementBox { ...@@ -96,9 +136,14 @@ struct ElementBox {
} }
/// return ElInfo* created from DataType data nearest to x.
/// Template specialization for DataType=DataType_ and
/// PointType=PointType_ provided.
bool getNearestElInfo(PointType &x, ElInfo*& minElInfo); bool getNearestElInfo(PointType &x, ElInfo*& minElInfo);
/// get object of type DataType nearest to given coordinate x,
/// where data can be used to create an ElInfo from the mesh.
bool getNearestData(PointType& x, DataType& data) bool getNearestData(PointType& x, DataType& data)
{ {
if (!inBox(x)) if (!inBox(x))
...@@ -123,6 +168,9 @@ struct ElementBox { ...@@ -123,6 +168,9 @@ struct ElementBox {
return true; return true;
} }
/// get nData objects of type DataType nearest to given coordinate x,
/// where data can be used to create an ElInfo from the mesh.
bool getNearestData(PointType& x, std::vector<DataType>& data, int nData) bool getNearestData(PointType& x, std::vector<DataType>& data, int nData)
{ {
if (!inBox(x)) if (!inBox(x))
...@@ -190,6 +238,14 @@ struct ElementBox { ...@@ -190,6 +238,14 @@ struct ElementBox {
} }
/** \brief create background-mesh structure for given feSpace
* Using fillBox() implementation to store element-information in the DataType_
* format in the background-mesh structure. When a new background mesh is created
* parameters about size are read from init-file:
* - <c>backgroundMesh->N</c> reads to \ref N
* - <c>backgroundMesh->min_corner</c> reads to \ref min_corner
* - <c>backgroundMesh->max_corner</c> reads to \ref max_corner
**/
static ElementBox<PointType, DataType>* provideBackgroundMesh(const FiniteElemSpace* feSpace) static ElementBox<PointType, DataType>* provideBackgroundMesh(const FiniteElemSpace* feSpace)
{ {
if (boxMap.find(feSpace) != boxMap.end()) { if (boxMap.find(feSpace) != boxMap.end()) {
...@@ -218,6 +274,7 @@ struct ElementBox { ...@@ -218,6 +274,7 @@ struct ElementBox {
return boxMap[feSpace].second; return boxMap[feSpace].second;
} }
/// clear background mesh
static void delete_all() static void delete_all()
{ {
typename std::map<const FiniteElemSpace*, std::pair<int, ElementBox<PointType, DataType>*> >::iterator boxIter; typename std::map<const FiniteElemSpace*, std::pair<int, ElementBox<PointType, DataType>*> >::iterator boxIter;
...@@ -261,7 +318,7 @@ protected: ...@@ -261,7 +318,7 @@ protected:
return nr; return nr;
} }
inline void nr2idx(int nr, std::vector<int>& idx) // template specialization see below inline void nr2idx(int nr, std::vector<int>& idx)
{ {
switch (DOW) { switch (DOW) {
case 1: case 1:
...@@ -286,7 +343,7 @@ protected: ...@@ -286,7 +343,7 @@ protected:
} }
} }
/// get indices of boxes surrounding the box with given nr
void getSurroundingBoxes(int nr, std::set<int> &surrounding_nrs) void getSurroundingBoxes(int nr, std::set<int> &surrounding_nrs)
{ {
std::vector<int> idx; std::vector<int> idx;
...@@ -302,6 +359,8 @@ protected: ...@@ -302,6 +359,8 @@ protected:
surrounding_nrs.erase(nr); surrounding_nrs.erase(nr);
} }
/// get indices of boxes surrounding the boxes with given set of nrs
void getSurroundingBoxes(std::set<int> &nrs, std::set<int> &surrounding_nrs) void getSurroundingBoxes(std::set<int> &nrs, std::set<int> &surrounding_nrs)
{ {
std::set<int>::iterator nrsIter; std::set<int>::iterator nrsIter;
...@@ -312,7 +371,7 @@ protected: ...@@ -312,7 +371,7 @@ protected:
surrounding_nrs.erase(*nrsIter); surrounding_nrs.erase(*nrsIter);
} }
/// berechne die minimale Entfernung der Ränder der Box zu x /// get minimal distance of box-boundaries to x
double getBoxBoundaryDist(int nr, PointType& x) double getBoxBoundaryDist(int nr, PointType& x)
{ {
std::vector<int> idx; std::vector<int> idx;
...@@ -324,10 +383,11 @@ protected: ...@@ -324,10 +383,11 @@ protected:
} }
double dist = 1.e15; double dist = 1.e15;
for (int i = 0; i < DOW; i++) for (int i = 0; i < DOW; i++)
dist = std::min(dist, std::min(abs(max_c[i]-x[i]), abs(min_c[i]-x[i]))); dist = std::min(dist, std::min(std::abs(max_c[i]-x[i]), std::abs(min_c[i]-x[i])));
return dist; return dist;
} }
/// add data to the background-mesh at point x
void addData(PointType x, DataType data) void addData(PointType x, DataType data)
{ {
int nr = getBox(x); int nr = getBox(x);
...@@ -336,7 +396,7 @@ protected: ...@@ -336,7 +396,7 @@ protected:
boxData[nr].push_back(data); boxData[nr].push_back(data);
} }
/// used by \ref provideBackgroundMesh
static typename std::map<const FiniteElemSpace*, std::pair<int, ElementBox<PointType, DataType>*> > boxMap; static typename std::map<const FiniteElemSpace*, std::pair<int, ElementBox<PointType, DataType>*> > boxMap;
protected: protected:
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#define EXTENSIONS_EXTENDED_PROBLEM_STAT_H #define EXTENSIONS_EXTENDED_PROBLEM_STAT_H
#include "AMDiS.h" #include "AMDiS.h"
#include "SingularDirichletBC.h" #include "SingularDirichletBC2.h"
#if defined NONLIN_PROBLEM #if defined NONLIN_PROBLEM
#include "nonlin/ProblemNonLin.h" #include "nonlin/ProblemNonLin.h"
#endif #endif
...@@ -116,7 +116,6 @@ public: ...@@ -116,7 +116,6 @@ public:
{ {
ProblemStat_::buildAfterCoarsen(adaptInfo, flag, asmMatrix, asmVector); ProblemStat_::buildAfterCoarsen(adaptInfo, flag, asmMatrix, asmVector);
#ifndef HAVE_PARALLEL_DOMAIN_AMDIS
// update periodic data // update periodic data
if (oldMeshChangeIdx != getMesh()->getChangeIndex() if (oldMeshChangeIdx != getMesh()->getChangeIndex()
|| flag.isSet(UPDATE_PERIODIC_BC) || flag.isSet(UPDATE_PERIODIC_BC)
...@@ -130,16 +129,15 @@ public: ...@@ -130,16 +129,15 @@ public:
// apply periodic boundary conditions // apply periodic boundary conditions
for (size_t k = 0; k < manualPeriodicBC.size(); k++) for (size_t k = 0; k < manualPeriodicBC.size(); k++)
applyPeriodicBC(manualPeriodicBC[k], asmMatrix, asmVector); applyPeriodicBC(manualPeriodicBC[k], asmMatrix, asmVector);
#endif
// update dirichlet data // update dirichlet data
if (oldMeshChangeIdx != getMesh()->getChangeIndex() if (oldMeshChangeIdx != getMesh()->getChangeIndex()
|| flag.isSet(UPDATE_DIRICHLET_BC) || flag.isSet(UPDATE_DIRICHLET_BC)
|| (DirichletBcDataList.size() > 0 && singularDirichletBC.size() == 0)) { || (DirichletBcDataList.size() > 0 && singularDirichletBC.size() == 0)) {
singularDirichletBC.clear(); singularDirichletBC.clear();
std::vector<DirichletBcData>::iterator it; std::vector<DirichletBcDataBase*>::iterator it;
for (it = DirichletBcDataList.begin(); it != DirichletBcDataList.end(); it++) { for (it = DirichletBcDataList.begin(); it != DirichletBcDataList.end(); it++) {
it->addToList(getFeSpace(it->row), singularDirichletBC); (*it)->addToList(getFeSpace((*it)->row), singularDirichletBC);
} }
} }
...@@ -176,6 +174,29 @@ public: ...@@ -176,6 +174,29 @@ public:
} }
//============================================================================
template<typename ValueContainer>
void addDirichletBC(BoundaryType type, int row, int col,
ValueContainer *values)
{
BoundaryTypeContainer *bound = new BoundaryTypeContainer(type);
DirichletBcDataList.push_back(
new DirichletBcData<BoundaryTypeContainer, ValueContainer>(
row, col, *bound, *values));
}
// general templatized version of addDirichletBC
template<typename PosType, typename ValueContainer>
void addDirichletBC(PosType *pos, int row, int col,
ValueContainer *values)
{
DirichletBcDataList.push_back(
new DirichletBcData<PosType, ValueContainer>(row, col, *pos, *values));
}
/** /**
* Dirichlet boundary condition at DOF-Index of vertex near to coords 'pos'. * Dirichlet boundary condition at DOF-Index of vertex near to coords 'pos'.
* Value defined by AbstractFunction, that is evaluated at 'pos' * Value defined by AbstractFunction, that is evaluated at 'pos'
...@@ -184,7 +205,8 @@ public: ...@@ -184,7 +205,8 @@ public:
void addSingularDirichletBC(WorldVector<double> &pos, int row, int col, void addSingularDirichletBC(WorldVector<double> &pos, int row, int col,
ValueContainer &values) ValueContainer &values)
{ {
DirichletBcDataList.push_back(DirichletBcData(row, col, pos, values)); WARNING("Depreciated! Use addDirichletBC instead!!!\n");
addDirichletBC(&pos, row, col, &values);
} }
...@@ -192,13 +214,23 @@ public: ...@@ -192,13 +214,23 @@ public:
* Dirichlet boundary condition at DOF-Index 'idx'. Value defined by double. * Dirichlet boundary condition at DOF-Index 'idx'. Value defined by double.
**/ **/
template<typename ValueContainer> template<typename ValueContainer>
void addSingularDirichletBC(DegreeOfFreedom idx, int row, int col, void addDirichletBC(DofIndex* idx, int row, int col,
ValueContainer &values) ValueContainer *values)
{ {
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
if (MPI::COMM_WORLD.Get_rank() == 0) if (MPI::COMM_WORLD.Get_rank() == 0)
#endif #endif
DirichletBcDataList.push_back(DirichletBcData(row, col, idx, values)); DirichletBcDataList.push_back(
new DirichletBcData<DofIndex, ValueContainer>(row, col, *idx, *values));
}
template<typename ValueContainer>
void addSingularDirichletBC(DegreeOfFreedom idx, int row, int col,
ValueContainer &values)
{
WARNING("Depreciated! Use addDirichletBC instead!!!\n");
DofIndex* dofIndex = new DofIndex(idx);
addDirichletBC(*dofIndex, row, col, values);
} }
...@@ -213,37 +245,57 @@ public: ...@@ -213,37 +245,57 @@ public:
int row, int col, int row, int col,
ValueContainer &values) ValueContainer &values)
{ {
DirichletBcDataList.push_back(DirichletBcData(row, col, &signedDist, values)); WARNING("Depreciated! Use addDirichletBC instead!!!\n");
addDirichletBC(&signedDist, row, col, &values);
} }
///
template<typename ValueContainer> template<typename ValueContainer>
void addImplicitDirichletBC(AbstractFunction<double, WorldVector<double> > &signedDist, void addImplicitDirichletBC(AbstractFunction<double, WorldVector<double> > &signedDist,
int row, int col, int row, int col,
ValueContainer &values) ValueContainer &values)
{ {
DirichletBcDataList.push_back(DirichletBcData(row, col, &signedDist, values)); WARNING("Depreciated! Use addDirichletBC instead!!!\n");
addDirichletBC(&signedDist, row, col, &values);
} }
///
template<typename ValueContainer>
void addDirichletBC(BoundaryType nr, AbstractFunction<bool, WorldVector<double> >* meshIndicator,
int row, int col,
ValueContainer *values)
{
DirichletBcDataList.push_back(
new DirichletBcData<AbstractFunction<bool, WorldVector<double> >, ValueContainer>(
row, col, nr, *meshIndicator, *values));
}
template<typename ValueContainer> template<typename ValueContainer>
void addManualDirichletBC(BoundaryType nr, AbstractFunction<bool, WorldVector<double> >* meshIndicator, void addManualDirichletBC(BoundaryType nr, AbstractFunction<bool, WorldVector<double> >* meshIndicator,
int row, int col, int row, int col,
ValueContainer &values) ValueContainer &values)
{ {
DirichletBcDataList.push_back(DirichletBcData(row, col, nr, meshIndicator, values)); WARNING("Depreciated! Use addDirichletBC instead!!!\n");
addDirichletBC(nr, meshIndicator, row, col, &values);
} }
///
template<typename ValueContainer> template<typename ValueContainer>
void addManualDirichletBC(AbstractFunction<bool, WorldVector<double> >* meshIndicator, void addManualDirichletBC(AbstractFunction<bool, WorldVector<double> >* meshIndicator,
int row, int col, int row, int col,
ValueContainer &values) ValueContainer &values)
{ {
DirichletBcDataList.push_back(DirichletBcData(row, col, meshIndicator, values)); WARNING("Depreciated! Use addDirichletBC instead!!!\n");
addDirichletBC(meshIndicator, row, col, &values);
} }
// ===========================================================================
void addManualPeriodicBC(int row, void addManualPeriodicBC(int row,
BoundaryType nr, AbstractFunction<bool, WorldVector<double> >* meshIndicator, BoundaryType nr, AbstractFunction<bool, WorldVector<double> >* meshIndicator,
AbstractFunction<WorldVector<double>, WorldVector<double> >* periodicMap) AbstractFunction<WorldVector<double>, WorldVector<double> >* periodicMap)
...@@ -292,11 +344,19 @@ protected: ...@@ -292,11 +344,19 @@ protected:
if (asmMatrix) { if (asmMatrix) {
typedef mtl::traits::range_generator<tag::row, Matrix>::type c_type; typedef mtl::traits::range_generator<tag::row, Matrix>::type c_type;
typedef mtl::traits::range_generator<tag::nz, c_type>::type ic_type; typedef mtl::traits::range_generator<tag::nz, c_type>::type ic_type;
// if matrix-block for the identity row is NULL, create new DOFMatrix
if (getSystemMatrix(row_, col_) == NULL) {
TEST_EXIT(row_ != col_)("should have been created already\n");
(*systemMatrix)[row_][col_] = new DOFMatrix(getFeSpace(row_), getFeSpace(col_), "");
(*systemMatrix)[row_][col_]->setCoupleMatrix(true);
(*systemMatrix)[row_][col_]->getBoundaryManager()->
setBoundaryConditionMap((*systemMatrix)[row_][row_]->getBoundaryManager()->
getBoundaryConditionMap());
}
size_t numCols = static_cast<size_t>(getNumComponents()); size_t numCols = static_cast<size_t>(getNumComponents());
for (size_t col = 0; col < numCols; col++) { for (size_t col = 0; col < numCols; col++) {
TEST_EXIT(getSystemMatrix(row_, col) != NULL || col != col_)
("SystemMatrix block (%d,%d) must not be NULL! Insert a Simple_ZOT(0.0) as Workaround.\n",row_,col);
if (getSystemMatrix(row_, col) == NULL) if (getSystemMatrix(row_, col) == NULL)
continue; continue;
...@@ -463,7 +523,7 @@ private: ...@@ -463,7 +523,7 @@ private:
// data for dirichlet boundary conditions // data for dirichlet boundary conditions
std::vector<SingularDirichletBC> singularDirichletBC; std::vector<SingularDirichletBC> singularDirichletBC;
std::vector<DirichletBcData> DirichletBcDataList; std::vector<DirichletBcDataBase*> DirichletBcDataList;
std::map<const FiniteElemSpace*, bool> feSpaceVisited; std::map<const FiniteElemSpace*, bool> feSpaceVisited;
......
...@@ -149,11 +149,11 @@ public: ...@@ -149,11 +149,11 @@ public:
markElements(markFlag); markElements(markFlag);
meshChanged = refineMesh(markFlag, onlyRefine); meshChanged = refineMesh(markFlag, onlyRefine);
calcMeshSizes(minH, maxH, minLevel, maxLevel); calcMeshSizes(minH, maxH, minLevel, maxLevel, false);
int nr = mesh->getNumberOfVertices(); int nr = mesh->getNumberOfVertices();
meshChanged = meshChanged && oldOldNr!=nr && oldNr!=nr; meshChanged = meshChanged && oldOldNr!=nr && oldNr!=nr;
if (meshChanged) { if (meshChanged) {
MSG("Mesh sizes: [%f, %f], Vs: %d, ELs: %d\n", MSG("(local) mesh sizes: [%f, %f], Vs: %d, ELs: %d\n",
minH, maxH, nr, mesh->getNumberOfElements()); minH, maxH, nr, mesh->getNumberOfElements());
} }
i++; i++;
...@@ -161,8 +161,8 @@ public: ...@@ -161,8 +161,8 @@ public:
oldOldNr = oldNr; oldOldNr = oldNr;
oldNr = nr; oldNr = nr;
} }
calcMeshSizes(minH, maxH, minLevel, maxLevel); calcMeshSizes(minH, maxH, minLevel, maxLevel, true);
MSG("Final mesh: [%f, %f], Vs: %d, ELs: %d, Level: [%d, %d]\n", MSG("Final (global) mesh: [%f, %f], Vs: %d, ELs: %d, Level: [%d, %d]\n",
minH, maxH, mesh->getNumberOfVertices(), mesh->getNumberOfElements(), minLevel, maxLevel); minH, maxH, mesh->getNumberOfVertices(), mesh->getNumberOfElements(), minLevel, maxLevel);
} }
...@@ -176,7 +176,7 @@ public: ...@@ -176,7 +176,7 @@ public:
return numRefinements; return numRefinements;
} }
void calcMeshSizes(double& minH, double& maxH, int& minLevel, int& maxLevel)