Marker.cc 6.13 KB
Newer Older
1
2
3
4
#include "Marker.h"

namespace AMDiS {

Thomas Witkowski's avatar
Thomas Witkowski committed
5
6
  Marker *Marker::createMarker(std::string name, int row) 
  {
7
8
9
10
11
12
13
14
15
    int strategy = 0;
    GET_PARAMETER(0, name + "->strategy", "%d", &strategy);
  
    Marker *marker = NULL;

    switch(strategy) {
    case 0: 
      break;
    case 1:
Thomas Witkowski's avatar
Thomas Witkowski committed
16
      marker = new GRMarker(name, row);
17
18
      break;
    case 2:
Thomas Witkowski's avatar
Thomas Witkowski committed
19
      marker = new MSMarker(name, row);
20
21
      break;
    case 3:
Thomas Witkowski's avatar
Thomas Witkowski committed
22
      marker = new ESMarker(name, row);
23
24
      break;
    case 4:
Thomas Witkowski's avatar
Thomas Witkowski committed
25
      marker = new GERSMarker(name, row);
26
      break;
Thomas Witkowski's avatar
Thomas Witkowski committed
27
28
    default: 
      ERROR_EXIT("invalid strategy\n");
29
30
31
32
    }
    
    return marker;
  }
33

34
35
36
  
  void Marker::initMarking(AdaptInfo *adaptInfo, Mesh *mesh)
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
37
38
    FUNCNAME("Marker::initMarking()");

Thomas Witkowski's avatar
Thomas Witkowski committed
39
    TEST_EXIT_DBG(adaptInfo)("No AdaptInfo object!\n");
Thomas Witkowski's avatar
Thomas Witkowski committed
40

41
42
43
44
45
46
    elMarkRefine = 0;
    elMarkCoarsen = 0;
    estSum = pow(adaptInfo->getEstSum(row == -1 ? 0 : row), p);
    estMax = adaptInfo->getEstMax(row == -1 ? 0 : row);
  }

47

Thomas Witkowski's avatar
Thomas Witkowski committed
48
49
  void Marker::finishMarking(AdaptInfo *adaptInfo) 
  {
50
51
52
53
54
55
    FUNCNAME("Marker::finishMarking()");
    
    INFO(info, 4)("%d elements marked for refinement\n", elMarkRefine);
    INFO(info, 4)("%d elements marked for coarsening\n", elMarkCoarsen);
  }

56

Thomas Witkowski's avatar
Thomas Witkowski committed
57
58
  void Marker::markElement(AdaptInfo *adaptInfo, ElInfo *elInfo) 
  {
59
60
    Element *el = elInfo->getElement();
    double lError = el->getEstimation(row);
Thomas Witkowski's avatar
Thomas Witkowski committed
61

62
    if (adaptInfo->isRefinementAllowed(row == -1 ? 0 : row) && lError > markRLimit) {
Thomas Witkowski's avatar
Thomas Witkowski committed
63
64
      if (maxRefineLevel == -1 || elInfo->getLevel() < maxRefineLevel)
	setMark(el, adaptInfo->getRefineBisections(row == -1 ? 0 : row));      
65
66
67
    } else {
      if (adaptInfo->isCoarseningAllowed(row == -1 ? 0 : row) && lError <= markCLimit) {
	if (!el->getElementData()->getElementData(COARSENABLE) || 
Thomas Witkowski's avatar
Thomas Witkowski committed
68
69
	    lError + el->getCoarseningEstimation(row) <= markCLimit)
	  setMark(el, -adaptInfo->getCoarseBisections(row == -1 ? 0 : row));	
70
71
72
73
      }
    }
  }

74

Thomas Witkowski's avatar
Thomas Witkowski committed
75
76
  Flag Marker::markMesh(AdaptInfo *adaptInfo, Mesh *mesh) 
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
77
78
79
80
    FUNCNAME("Marker::markMesh()");

    TEST_EXIT_DBG(mesh)("No mesh!\n");

81
    initMarking(adaptInfo, mesh);
Thomas Witkowski's avatar
Thomas Witkowski committed
82
   
83
    if (!adaptInfo->isCoarseningAllowed(row == -1 ? 0 : row) && 
Thomas Witkowski's avatar
Thomas Witkowski committed
84
85
	!adaptInfo->isRefinementAllowed(row == -1 ? 0 : row))
      return 0;    
86
87
    
    TraverseStack stack;
Thomas Witkowski's avatar
Thomas Witkowski committed
88
    ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL);
89
    while (elInfo) {
Thomas Witkowski's avatar
Thomas Witkowski committed
90
      markElement(adaptInfo, elInfo);
91
92
93
94
95
96
97
98
99
100
101
      elInfo = stack.traverseNext(elInfo);
    }
    
    finishMarking(adaptInfo);
    
    Flag markFlag;
    if (elMarkRefine) 
      markFlag = 1;
    if (elMarkCoarsen) 
      markFlag |= 2;

Thomas Witkowski's avatar
Thomas Witkowski committed
102
    return markFlag; 
103
104
105
  } 


Thomas Witkowski's avatar
Thomas Witkowski committed
106
107
  void ESMarker::initMarking(AdaptInfo *adaptInfo, Mesh *mesh) 
  {
108
109
110
    FUNCNAME("ESMarker::initMarking()");
    
    Marker::initMarking(adaptInfo, mesh);
Thomas Witkowski's avatar
Thomas Witkowski committed
111
   
112
113
114
115
116
117
118
119
    double ESThetaP = pow(ESTheta, p);
    double ESThetaCP = pow(ESThetaC, p);
    
    double epsP = pow(adaptInfo->getSpaceTolerance(row == -1 ? 0 : row), p);
    
    markRLimit = ESThetaP * epsP / mesh->getNumberOfLeaves();
    markCLimit = ESThetaCP * epsP / mesh->getNumberOfLeaves();
    
Thomas Witkowski's avatar
Thomas Witkowski committed
120
121
    INFO(info, 2)("start mark_limits: %.3le %.3le nt=%d\n",
		  markRLimit, markCLimit, mesh->getNumberOfLeaves());
122
123
  }

124

Thomas Witkowski's avatar
Thomas Witkowski committed
125
126
  Flag GERSMarker::markMesh(AdaptInfo *adaptInfo, Mesh *mesh) 
  {
127
128
129
130
131
    FUNCNAME("GERSMarker::markMesh()");

    initMarking(adaptInfo, mesh);

    if (!adaptInfo->isCoarseningAllowed(row == -1 ? 0 : row) && 
Thomas Witkowski's avatar
Thomas Witkowski committed
132
133
	!adaptInfo->isRefinementAllowed(row == -1 ? 0 : row))
      return 0;    
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

    GERSSum = 0.0;

    double LTheta = pow(1.0 - GERSThetaStar, p);
    double improv, redfac, wanted, epsP, GERSGamma;
    
    epsP = pow(adaptInfo->getSpaceTolerance(row == -1 ? 0 : row), p);

    if (estSum < oldErrSum) {
      improv = estSum / oldErrSum;
      wanted = 0.8 * epsP / estSum;
      redfac = std::min((1.0 - wanted) / (1.0 - improv), 1.0);
      redfac = std::max(redfac, 0.0);
      
      if (redfac < 1.0) {
	LTheta *= redfac;
Thomas Witkowski's avatar
Thomas Witkowski committed
150
151
	INFO(info, 1)("GERS: use extrapolated theta_star = %lf\n",
		      pow(LTheta, 1.0 / p));
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
      }
    }

    oldErrSum = estSum;
    GERSGamma = 1.0;

    if (adaptInfo->isRefinementAllowed(row == -1 ? 0 : row)) {
      if (LTheta > 0) {
	do {
	  GERSSum = 0.0;	  
	  GERSGamma -= GERSNu;
	  markRLimit = GERSGamma * estMax;

	  TraverseStack stack;
	  ElInfo *elInfo = NULL;
	  elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL);
	  while (elInfo) {
	    markElementForRefinement(adaptInfo, elInfo);
	    elInfo = stack.traverseNext(elInfo);
	  }
	  
	} while((GERSGamma > 0) && (GERSSum < LTheta * estSum));
      }

Thomas Witkowski's avatar
Thomas Witkowski committed
176
      INFO(info, 2)("GERS refinement with gamma = %.3lf\n", GERSGamma);
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
    }

    if (adaptInfo->isCoarseningAllowed(row == -1 ? 0 : row)) {
      GERSGamma = 0.3;
      LTheta = GERSThetaC * epsP;
      
      do {
	GERSSum = 0.0;
	GERSGamma -= GERSNu;
	markCLimit = GERSGamma * estMax;
	
	TraverseStack stack;
	ElInfo *elInfo = NULL;
	elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL);
	while (elInfo) {
	  markElementForCoarsening(adaptInfo, elInfo);
	  elInfo = stack.traverseNext(elInfo);
	}

Thomas Witkowski's avatar
Thomas Witkowski committed
196
197
	INFO(info, 6)("coarse loop: gamma=%.3e, sum=%.3e, limit=%.3e\n",
		      GERSGamma, GERSSum, LTheta);
198
199
      } while(GERSSum > LTheta);
      
Thomas Witkowski's avatar
Thomas Witkowski committed
200
      INFO(info, 2)("GERS coarsening with gamma = %.3lf\n", GERSGamma);      
201
202
203
204
205
206
207
208
209
210
211
212
213
    }
    
    finishMarking(adaptInfo);
    
    Flag markFlag;
    if (elMarkRefine) 
      markFlag = 1;
    if (elMarkCoarsen) 
      markFlag |= 2;
      
    return(markFlag); 
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
214
215
  void GERSMarker::markElementForRefinement(AdaptInfo *adaptInfo, ElInfo *elInfo) 
  {
216
217
218
219
220
221
222
223
224
    Element *el = elInfo->getElement();
    double lError = el->getEstimation(row);

    if (lError > markRLimit) {
      GERSSum += lError;
      setMark(el, adaptInfo->getRefineBisections(row == -1 ? 0 : row));
    }
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
225
226
  void GERSMarker::markElementForCoarsening(AdaptInfo *adaptInfo, ElInfo *elInfo) 
  {
227
228
229
230
    Element *el = elInfo->getElement();
    double lError = el->getEstimation(row);
    
    if (el->getMark() <= 0) {
Thomas Witkowski's avatar
Thomas Witkowski committed
231
232
      if (el->getElementData()->getElementData(COARSENABLE))
	lError += el->getCoarseningEstimation(row);      
233
234
235
236
237
238
239
240
241
242
243
      
      if (lError <= markCLimit) {
	GERSSum += lError;
	setMark(el, -adaptInfo->getCoarseBisections(row == -1 ? 0 : row));
      } else {
	setMark(el, 0);
      }
    }
  }


244
245

}