RCNeighbourList.h 7.25 KB
Newer Older
1
2
3
4
5
6
// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
7
// ==  TU Dresden                                                            ==
8
// ==                                                                        ==
9
10
11
// ==  Institut für Wissenschaftliches Rechnen                               ==
// ==  Zellescher Weg 12-14                                                  ==
// ==  01069 Dresden                                                         ==
12
13
14
15
// ==  germany                                                               ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
16
// ==  https://gforge.zih.tu-dresden.de/projects/amdis/                      ==
17
18
19
20
21
22
23
24
25
26
// ==                                                                        ==
// ============================================================================

/** \file RCNeighbourList.h */

#ifndef AMDIS_RCNEIGHBOURLIST_H
#define AMDIS_RCNEIGHBOURLIST_H

#include <vector>
#include <deque>
Thomas Witkowski's avatar
Thomas Witkowski committed
27
#include "AMDiS_fwd.h"
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include "Global.h"

namespace AMDiS {

  /** \ingroup Adaption 
   * \brief
   * Stores information about coarsening and refinement patches. For refining 
   * and coarsening we need information of the elements at the refinement and 
   * coarsening edge. Thus, we have to collect all elements at this edge. In 2d 
   * we have at most the current element and its neighbour across this edge, if
   * the edge is not part of the boundary. In 3d we have to loop around this 
   * edge to collect all the elements. Every element at the edge has at most two
   * neighbours sharing the same edge. Defining an orientation for this edge, 
   * we can define the right and left neighbour.
   * For every element at the refinement/coarsening edge we have an entry in a 
   * vector. The elements of this vector build the refinement/coarsening patch.
   * In 2d the vector has length 2 and in 3d length mesh->getMaxEdgeNeigh() 
   * since this is the maximal number of elements sharing the same edge in the 
   * Mesh.
   */
  class RCNeighbourList
  {
  public:
51
    /// Constructs a RCNeighbourList of size maxEdgeNeigh
52
53
    RCNeighbourList(int maxEdgeNeigh);

54
    RCNeighbourList() {}
55

56
    /// Destructor
57
58
    virtual ~RCNeighbourList();

59
    /// Sets flag of \ref rclist[i] = true
Thomas Witkowski's avatar
Thomas Witkowski committed
60
61
    inline void setCoarsePatch(int i) 
    {
62
63
      rclist[i]->flag = true;
    }
64

65
    /// Sets flag of \ref rclist[i] = f
Thomas Witkowski's avatar
Thomas Witkowski committed
66
67
    inline void setCoarsePatch(int i, bool f) 
    {
68
69
      rclist[i]->flag = f;
    }
70

71
    /// Returns \ref rclist[i].flag
Thomas Witkowski's avatar
Thomas Witkowski committed
72
73
    inline const bool isPatchCoarse(int i) const 
    {
74
75
      return rclist[i]->flag;
    }
76
77
78

    /** \brief
     * If \ref rclist[i].neigh[j] is not a NULL pointer 
Thomas Witkowski's avatar
Thomas Witkowski committed
79
     * \ref rclist[i].neigh[j]->no will be returned. Otherwise the return value is -1
80
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
81
82
    inline int getNeighbourNr(int i, int j) const 
    {
83
      return (rclist[i]->neigh[j])?rclist[i]->neigh[j]->no:-1;
84
    }
85
86
87
88
89
90

    /** \brief
     * If \ref rclist[i].neigh[j] is not a NULL pointer 
     * \ref rclist[i].neigh[j]->el will be returned. Otherwise the return value
     * is NULL
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
91
92
    inline Element* getNeighbourElement(int i, int j) const 
    {
93
      return rclist[i]->neigh[j]? rclist[i]->neigh[j]->el : NULL; 
94
    }
95

96
    /// Returns \ref rclist[i].el
Thomas Witkowski's avatar
Thomas Witkowski committed
97
98
    inline Element* getElement(int i) const 
    {
99
100
      if (static_cast<int>(rclist.size()) <= i) 
	return NULL;
101
      return rclist[i]->el;
102
    }
103

104
    /// Sets \ref rclist[i].el to el and \ref rclist[i].flag to cp.
Thomas Witkowski's avatar
Thomas Witkowski committed
105
106
    inline const Element* setElement(int i, const Element* el, bool cp = false) 
    {
107
108
      rclist[i]->el = const_cast<Element*>(el);
      rclist[i]->flag = cp;
109
      return el;
110
    }
111

112
    /// Returns \ref rclist[i].elType
Thomas Witkowski's avatar
Thomas Witkowski committed
113
114
    inline int getType(int i) const 
    {
115
116
      return rclist[i]->elType;
    }
117

Thomas Witkowski's avatar
Thomas Witkowski committed
118
119
    inline void setType(int i, int type) const 
    {
120
      rclist[i]->elType = type; 
121
    }
122

123
    /// If patch can be coarsend return true, else false and reset the element marks.
124
125
    virtual bool doCoarsePatch(int n_neigh);

126
    /// Sets \ref rclist[i].oppVertex[j] = k
Thomas Witkowski's avatar
Thomas Witkowski committed
127
128
    inline void setOppVertex(int i,int j,int k) 
    {
129
130
      rclist[i]->oppVertex[j] = k;
    }
131
  
132
    /// Returns \ref rclist[i].oppVertex[j]
Thomas Witkowski's avatar
Thomas Witkowski committed
133
134
    inline int getOppVertex(int i, int j) 
    { 
135
136
      return rclist[i]->oppVertex[j]; 
    }
137

138
    /// Sets \ref rclist[i].elType = t
Thomas Witkowski's avatar
Thomas Witkowski committed
139
140
    inline void setElType(int i,unsigned char t) 
    {
141
142
      rclist[i]->elType = t;
    }
143

144
    /// Sets \ref coarseningManager = cm
Thomas Witkowski's avatar
Thomas Witkowski committed
145
146
    inline void setCoarseningManager(CoarseningManager *cm) 
    { 
147
      coarseningManager = cm; 
148
    }
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167

    /** \brief
     * Fills \ref rclist[i].neigh and \ref rclist[i].oppVertex  infos ( 0 <= i 
     * < n_neigh)
     */
    void getNeighOnPatch(int n_neigh, int bound);

    /** \brief
     * Adds those dof's on the parent that are handed on by the
     * children and adds the dof in the midpoint of the coarsening edge (3d) 
     */
    void addDOFParent(int elIndex, DegreeOfFreedom* dof);

    /** \brief
     * If DOFs for higher order are been removed on parents during refinement
     * they are now added again (2d)
     */
    void addDOFParents(int n_neigh);

168
    /// Removes DOFs during refinement (3d)
169
170
    void removeDOFParent(int index);

171
    /// Removes DOFs during refinement (2d)
172
173
174
175
176
177
178
179
    void removeDOFParents(int n_neigh);  

    RCNeighbourList *periodicSplit(DegreeOfFreedom *edge[2],
				   DegreeOfFreedom *nextEdge[2],
				   int *n_neigh,
				   int *n_neigh_periodic);

  protected:
180
    /// Information about one Element of the patch
181
182
183
    class RCListElement
    {
    public:
184
      /// Pointer to the Element
185
186
      Element* el;

187
      /// This is the no-th entry in the RCNeighbourList 
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
      int no;

      /** \brief
       * Only used in the coarsening module: flag is true if the coarsening 
       * edge of the Element is the coarsening edge of the patch, otherwise 
       * flag is false;
       */
      bool flag;

      /** \brief
       * neigh[0/1] neighbour of element to the right/left in the orientation 
       * of the edge, or a NULL pointer in the case of a boundary face (only 3d)
       */
      RCListElement* neigh[2];

203
      /// opp vertex[0/1] the opposite vertex of neigh[0/1] (only 3d)
204
205
206
207
208
209
210
211
212
213
214
215
      int oppVertex[2];

      /** \brief
       * The element type; is set during looping around the 
       * refinement/coarsening edge; if neighbour information is produced by the
       * traversal routines, information about the type of an element can not be
       * accessed via el->getType() and thus has to be stored in the 
       * RCListElement vector (only 3d)
       */
      unsigned char elType;
    };

216
    /// Refinement/coarsening patch
217
    std::vector<RCListElement*> rclist;
218

219
    /// Pointer to the CoarseningManager
220
221
222
223
224
225
    CoarseningManager *coarseningManager; 
  };

}

#endif  // AMDIS_RCNEIGHBOURLIST_H