RCNeighbourList.h 8.07 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
// ==  crystal growth group                                                  ==
// ==                                                                        ==
// ==  Stiftung caesar                                                       ==
// ==  Ludwig-Erhard-Allee 2                                                 ==
// ==  53175 Bonn                                                            ==
// ==  germany                                                               ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
// ==  http://www.caesar.de/cg/AMDiS                                         ==
// ==                                                                        ==
// ============================================================================

/** \file RCNeighbourList.h */

#ifndef AMDIS_RCNEIGHBOURLIST_H
#define AMDIS_RCNEIGHBOURLIST_H

#include <vector>
#include <deque>
#include "Global.h"
#include "MemoryManager.h"

namespace AMDiS {

  class Element;
  class ElInfo;
  class CoarseningManager;

  // ===========================================================================
  // ===== class RCNeighbourList ===============================================
  // ===========================================================================

  /** \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:
    MEMORY_MANAGED(RCNeighbourList);

    /** \brief
     * Constructs a RCNeighbourList of size maxEdgeNeigh
     */
    RCNeighbourList(int maxEdgeNeigh);

66
    RCNeighbourList() {}
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

    /** \brief
     * Destructor
     */
    virtual ~RCNeighbourList();

    /** \brief
     * Sets flag of \ref rclist[i] = true
     */
    inline void setCoarsePatch(int i) {rclist[i]->flag=true;};

    /** \brief
     * Sets flag of \ref rclist[i] = f
     */
    inline void setCoarsePatch(int i,bool f) {rclist[i]->flag=f;};

    /** \brief
     * Returns \ref rclist[i].flag
     */
    inline const bool isPatchCoarse(int i) const {return rclist[i]->flag;};

    /** \brief
     * If \ref rclist[i].neigh[j] is not a NULL pointer 
     * \ref rclist[i].neigh[j]->no will be returned. Otherwise the return value
     * is -1
     */
    inline int getNeighbourNr(int i, int j) const {
      return (rclist[i]->neigh[j])?rclist[i]->neigh[j]->no:-1;
95
    }
96
97
98
99
100
101
102
103

    /** \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
     */
    inline Element* getNeighbourElement(int i, int j) const {
      return rclist[i]->neigh[j]? rclist[i]->neigh[j]->el : NULL; 
104
    }
105
106
107
108
109

    /** \brief
     * Returns \ref rclist[i].el
     */
    inline Element* getElement(int i) const {
110
111
      if (static_cast<int>(rclist.size()) <= i) 
	return NULL;
112
      return rclist[i]->el;
113
    }
114
115
116
117

    /** \brief
     * Sets \ref rclist[i].el to el and \ref rclist[i].flag to cp.
     */
118
119
120
    inline const Element* setElement(int i, const Element* el, bool cp = false) {
      rclist[i]->el = const_cast<Element*>(el);
      rclist[i]->flag = cp;
121
      return el;
122
    }
123
124
125
126

    /** \brief
     * Returns \ref rclist[i].elType
     */
127
128
129
    inline int getType(int i) const {
      return rclist[i]->elType;
    }
130
131
132

    inline void setType(int i, int type) const {
      rclist[i]->elType = type; 
133
    }
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248

    /** \brief
     * If patch can be coarsend return true, else false and reset the element 
     * marks
     */
    virtual bool doCoarsePatch(int n_neigh);

    /** \brief
     * Sets \ref rclist[i].oppVertex[j] = k
     */
    inline void setOppVertex(int i,int j,int k) {rclist[i]->oppVertex[j]=k;};
  
    /** \brief
     * Returns \ref rclist[i].oppVertex[j]
     */
    inline int getOppVertex(int i, int j) { return rclist[i]->oppVertex[j]; };

    /** \brief
     * Sets \ref rclist[i].elType = t
     */
    inline void setElType(int i,unsigned char t) {rclist[i]->elType=t;};

    /** \brief
     * Sets \ref coarseningManager = cm
     */
    inline void setCoarseningManager(CoarseningManager *cm) { 
      coarseningManager = cm; 
    };

    /** \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);

    /** \brief
     * Removes DOFs during refinement (3d)
     */
    void removeDOFParent(int index);

    /** \brief
     *  Removes DOFs during refinement (2d)
     */
    void removeDOFParents(int n_neigh);  

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

  protected:
    /** \brief
     * Information about one Element of the patch
     */
    class RCListElement
    {
    public:
      /** \brief
       * Pointer to the Element
       */
      Element* el;

      /** \brief
       * This is the no-th entry in the RCNeighbourList 
       */
      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];

      /** \brief
       * opp vertex[0/1] the opposite vertex of neigh[0/1] (only 3d)
       */
      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;

      //     /** \brief
      //      * Stores whether coordinate interpolation must be done.
      //      */
      //     bool newCoords;
    };

    /** \brief
     * Refinement/coarsening patch
     */
249
    std::vector<RCListElement*> rclist;
250
251
252
253
254
255
256
257
258
259

    /** \brief
     * Pointer to the CoarseningManager
     */
    CoarseningManager *coarseningManager; 
  };

}

#endif  // AMDIS_RCNEIGHBOURLIST_H