BoundaryManager.cc 5.9 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
//
// 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.


13
14
15
16
17
18
19
#include "FiniteElemSpace.h"
#include "BoundaryManager.h"
#include "DOFIndexed.h"
#include "DOFVector.h"
#include "Traverse.h"
#include "BasisFunction.h"
#include "ElInfo.h"
Thomas Witkowski's avatar
Thomas Witkowski committed
20
#include "OpenMP.h"
21
22
23

namespace AMDiS {

24
25
26
  std::map<BoundaryType, std::vector<BoundaryCondition*> > 
  BoundaryManager::globalBoundaryMap;

Thomas Witkowski's avatar
Thomas Witkowski committed
27

Thomas Witkowski's avatar
Thomas Witkowski committed
28
29
  BoundaryManager::BoundaryManager(const FiniteElemSpace *feSpace)
  {
30
    localBounds.resize(omp_get_overall_max_threads());
31
    dofIndices.resize(omp_get_overall_max_threads());
Thomas Witkowski's avatar
Thomas Witkowski committed
32
    allocatedMemoryLocalBounds = feSpace->getBasisFcts()->getNumber();
Thomas Witkowski's avatar
Thomas Witkowski committed
33
    for (unsigned int i = 0; i < localBounds.size(); i++)
34
      localBounds[i] = new BoundaryType[allocatedMemoryLocalBounds];
Thomas Witkowski's avatar
Thomas Witkowski committed
35
36
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
37

Thomas Witkowski's avatar
Thomas Witkowski committed
38
39
40
41
42
  BoundaryManager::BoundaryManager(BoundaryManager &bm)
  {
    localBCs = bm.localBCs;
    allocatedMemoryLocalBounds = bm.allocatedMemoryLocalBounds;
    localBounds.resize(bm.localBounds.size());
43
    dofIndices.resize(bm.localBounds.size());
Thomas Witkowski's avatar
Thomas Witkowski committed
44
    for (unsigned int i = 0; i < localBounds.size(); i++)
45
      localBounds[i] = new BoundaryType[allocatedMemoryLocalBounds];
Thomas Witkowski's avatar
Thomas Witkowski committed
46
47
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
48

Thomas Witkowski's avatar
Thomas Witkowski committed
49
50
  BoundaryManager::~BoundaryManager()
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
51
    for (unsigned int i = 0; i < localBounds.size(); i++)
52
      delete [] localBounds[i];
Thomas Witkowski's avatar
Thomas Witkowski committed
53
54
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
55

56
57
58
59
  double BoundaryManager::boundResidual(ElInfo *elInfo, 
					DOFMatrix *matrix,
					const DOFVectorBase<double> *dv)
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
60
    double result = 0.0;
61
    for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it)
62
      if ((*it).second)
63
	result += (*it).second->boundResidual(elInfo, matrix, dv);
64
    
65
66
67
    return result;
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
68

69
70
71
  void BoundaryManager::fillBoundaryConditions(ElInfo *elInfo, 
					       DOFVectorBase<double> *vec)
  {
72
    if (localBCs.size() > 0) {
73
      const FiniteElemSpace *feSpace = vec->getFeSpace();
74
75
76
77
      std::vector<DegreeOfFreedom> &dofVec = dofIndices[omp_get_thread_num()];
      const BasisFunction *basisFcts = feSpace->getBasisFcts();
      int nBasFcts = basisFcts->getNumber();
      dofVec.resize(nBasFcts);
78

79
80
81
      // get boundaries of all DOFs
      BoundaryType *localBound = localBounds[omp_get_thread_num()];
      basisFcts->getBound(elInfo, localBound);
82

83
84
      // get dof indices
      basisFcts->getLocalIndices(elInfo->getElement(), feSpace->getAdmin(), dofVec);
85

86
87
88
89
90
      // apply non dirichlet boundary conditions
      for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it)
	if ((*it).second && !(*it).second->isDirichlet())
	  (*it).second->fillBoundaryCondition(vec, elInfo, &dofVec[0], 
					      localBound, nBasFcts);
91

92
93
94
95
96
97
98
      // apply dirichlet boundary conditions
      for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it)
	if ((*it).second && (*it).second->isDirichlet())
	  (*it).second->fillBoundaryCondition(vec, elInfo, &dofVec[0], 
					      localBound, nBasFcts);
    }
  }
99

Thomas Witkowski's avatar
Thomas Witkowski committed
100

101
  void BoundaryManager::fillBoundaryConditions(ElInfo *elInfo, DOFMatrix *mat)
102
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
103
104
105
    if (localBCs.size() <= 0)
      return;
      
106
    const FiniteElemSpace *feSpace = mat->getRowFeSpace();
107
    std::vector<DegreeOfFreedom> &dofVec = dofIndices[omp_get_thread_num()];
Thomas Witkowski's avatar
Thomas Witkowski committed
108
109
    const BasisFunction *basisFcts = feSpace->getBasisFcts();
    int nBasFcts = basisFcts->getNumber();
110
          dofVec.resize(nBasFcts);
111

Thomas Witkowski's avatar
Thomas Witkowski committed
112
113
114
115
116
    // get boundaries of all DOFs
    BoundaryType *localBound = localBounds[omp_get_thread_num()];
    basisFcts->getBound(elInfo, localBound);
    
    // get dof indices
117
    basisFcts->getLocalIndices(elInfo->getElement(), feSpace->getAdmin(), dofVec);
Thomas Witkowski's avatar
Thomas Witkowski committed
118
119
    
    // apply non dirichlet boundary conditions
120
121
122
123
    for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it)
      if ((*it).second && !(*it).second->isDirichlet())
	(*it).second->fillBoundaryCondition(mat, elInfo, &dofVec[0], 
					    localBound, nBasFcts);
Thomas Witkowski's avatar
Thomas Witkowski committed
124
125
    
    // apply dirichlet boundary conditions
126
127
128
129
    for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it)
      if ((*it).second && (*it).second->isDirichlet())
	(*it).second->fillBoundaryCondition(mat, elInfo, &dofVec[0], 
					    localBound, nBasFcts);
130
131
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
132

133
134
  void BoundaryManager::initMatrix(DOFMatrix *matrix)
  {
135
136
137
    for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it)
      if ((*it).second && !(*it).second->isDirichlet())
	(*it).second->initMatrix(matrix);
Thomas Witkowski's avatar
Thomas Witkowski committed
138

139
140
141
    for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it)
      if ((*it).second && (*it).second->isDirichlet())
	(*it).second->initMatrix(matrix);
142
143
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
144

145
146
  void BoundaryManager::exitMatrix(DOFMatrix *matrix)
  {
147
148
149
    for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it)
      if ((*it).second && !(*it).second->isDirichlet())
	(*it).second->exitMatrix(matrix);
Thomas Witkowski's avatar
Thomas Witkowski committed
150

151
152
153
    for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it)
      if ((*it).second && (*it).second->isDirichlet())
	(*it).second->exitMatrix(matrix);
154
155
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
156

157
158
  void BoundaryManager::initVector(DOFVectorBase<double> *vector)
  {
159
160
161
    for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it)
      if ((*it).second && !(*it).second->isDirichlet())
	(*it).second->initVector(vector);
Thomas Witkowski's avatar
Thomas Witkowski committed
162

163
164
165
    for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it)
      if ((*it).second && (*it).second->isDirichlet())
	(*it).second->initVector(vector);
166
167
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
168

169
170
  void BoundaryManager::exitVector(DOFVectorBase<double> *vector)
  {
171
172
173
    for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it)
      if ((*it).second && !(*it).second->isDirichlet())
	(*it).second->exitVector(vector);
Thomas Witkowski's avatar
Thomas Witkowski committed
174

175
176
177
    for (BoundaryIndexMap::iterator it = localBCs.begin(); it != localBCs.end(); ++it)
      if ((*it).second && (*it).second->isDirichlet())
	(*it).second->exitVector(vector);
178
179
180
  }

}