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
  
  void Marker::initMarking(AdaptInfo *adaptInfo, Mesh *mesh)
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
36
37
    FUNCNAME("Marker::initMarking()");

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

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

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

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

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

Thomas Witkowski's avatar
Thomas Witkowski committed
71
72
  Flag Marker::markMesh(AdaptInfo *adaptInfo, Mesh *mesh) 
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
73
74
75
76
    FUNCNAME("Marker::markMesh()");

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

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

Thomas Witkowski's avatar
Thomas Witkowski committed
98
    return markFlag; 
99
100
101
  } 


Thomas Witkowski's avatar
Thomas Witkowski committed
102
103
  void ESMarker::initMarking(AdaptInfo *adaptInfo, Mesh *mesh) 
  {
104
105
106
    FUNCNAME("ESMarker::initMarking()");
    
    Marker::initMarking(adaptInfo, mesh);
Thomas Witkowski's avatar
Thomas Witkowski committed
107
   
108
109
110
111
112
113
114
115
    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
116
117
    INFO(info, 2)("start mark_limits: %.3le %.3le nt=%d\n",
		  markRLimit, markCLimit, mesh->getNumberOfLeaves());
118
119
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
120
121
  Flag GERSMarker::markMesh(AdaptInfo *adaptInfo, Mesh *mesh) 
  {
122
123
124
125
126
    FUNCNAME("GERSMarker::markMesh()");

    initMarking(adaptInfo, mesh);

    if (!adaptInfo->isCoarseningAllowed(row == -1 ? 0 : row) && 
Thomas Witkowski's avatar
Thomas Witkowski committed
127
128
	!adaptInfo->isRefinementAllowed(row == -1 ? 0 : row))
      return 0;    
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144

    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
145
146
	INFO(info, 1)("GERS: use extrapolated theta_star = %lf\n",
		      pow(LTheta, 1.0 / p));
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
      }
    }

    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
171
      INFO(info, 2)("GERS refinement with gamma = %.3lf\n", GERSGamma);
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
    }

    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
191
192
	INFO(info, 6)("coarse loop: gamma=%.3e, sum=%.3e, limit=%.3e\n",
		      GERSGamma, GERSSum, LTheta);
193
194
      } while(GERSSum > LTheta);
      
Thomas Witkowski's avatar
Thomas Witkowski committed
195
      INFO(info, 2)("GERS coarsening with gamma = %.3lf\n", GERSGamma);      
196
197
198
199
200
201
202
203
204
205
206
207
208
    }
    
    finishMarking(adaptInfo);
    
    Flag markFlag;
    if (elMarkRefine) 
      markFlag = 1;
    if (elMarkCoarsen) 
      markFlag |= 2;
      
    return(markFlag); 
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
209
210
  void GERSMarker::markElementForRefinement(AdaptInfo *adaptInfo, ElInfo *elInfo) 
  {
211
212
213
214
215
216
217
218
219
    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
220
221
  void GERSMarker::markElementForCoarsening(AdaptInfo *adaptInfo, ElInfo *elInfo) 
  {
222
223
224
225
    Element *el = elInfo->getElement();
    double lError = el->getEstimation(row);
    
    if (el->getMark() <= 0) {
Thomas Witkowski's avatar
Thomas Witkowski committed
226
227
      if (el->getElementData()->getElementData(COARSENABLE))
	lError += el->getCoarseningEstimation(row);      
228
229
230
231
232
233
234
235
236
237
238
      
      if (lError <= markCLimit) {
	GERSSum += lError;
	setMark(el, -adaptInfo->getCoarseBisections(row == -1 ? 0 : row));
      } else {
	setMark(el, 0);
      }
    }
  }


239
240

}