Peano
Loading...
Searching...
No Matches
refinement.h
Go to the documentation of this file.
1#ifndef EXASEIS_REFINEMENT_HEADER
2#define EXASEIS_REFINEMENT_HEADER
3
4// #include "kernels/GaussLegendreBasis.h"
6#include "../Numerics/idx.h"
7
8namespace Refinement {
9 template <class Shortcuts>
11 public:
12 virtual bool eval(
13 const double* luh,
16 double t,
17 const int level,
19 ) = 0;
20 };
21 template <class Shortcuts>
22 class trackVelocity: public RefinementCriterion<Shortcuts> {
23 public:
24 trackVelocity(int a_basisSize, double a_refine_threshold, double a_coarsen_threshold):
25 basisSize(a_basisSize),
26 refine_threshold_2(a_refine_threshold * a_refine_threshold),
27 coarsen_threshold_2(a_coarsen_threshold * a_coarsen_threshold){};
28
29 bool eval(
30 const double* luh,
33 double t,
34 const int level,
36 ) override {
37 Shortcuts s;
38 kernels::idx4 idx(basisSize, basisSize, basisSize, s.NumberOfUnknowns + s.NumberOfAuxiliaryVariables);
39 double maxVelocity_2 = 0;
40 double minVelocity_2 = std::numeric_limits<double>::max();
41 for (int i = 0; i < basisSize; i++) {
42 for (int j = 0; j < basisSize; j++) {
43 for (int k = 0; k < basisSize; k++) {
44 double velocity_2 = luh[idx(i, j, k, s.v + 0)] * luh[idx(i, j, k, s.v + 0)]
45 + luh[idx(i, j, k, s.v + 1)] * luh[idx(i, j, k, s.v + 1)]
46 + luh[idx(i, j, k, s.v + 2)] * luh[idx(i, j, k, s.v + 2)];
47
48 maxVelocity_2 = std::max(maxVelocity_2, velocity_2);
49 minVelocity_2 = std::min(minVelocity_2, velocity_2);
50 }
51 }
52 }
53
55
56 if (refine_threshold_2 < maxVelocity_2) {
58 return false;
59 }
60
61 if (coarsen_threshold_2 > minVelocity_2) {
63 return false;
64 }
65
66 return false;
67 };
68
69 private:
73 };
74
75 template <class Shortcuts>
76 class StaticAMR: public RefinementCriterion<Shortcuts> {
77 public:
78 bool eval(
79 const double* luh,
82 double t,
83 const int level,
85 ) override {
86 // static AMR
87 if (!tarch::la::equals(t, 0.0)) {
89 return true;
90 }
91 return false;
92 }
93 };
94
95 template <class Shortcuts>
97 public:
98 RefineBetweenPositions(double a_left[3], double a_right[3]){
99 rectangle_left[0] = a_left[0];
100 rectangle_left[1] = a_left[1];
101 rectangle_left[2] = a_left[2];
102
103 rectangle_right[0] = a_right[0];
104 rectangle_right[1] = a_right[1];
105 rectangle_right[2] = a_right[2];
106 }
107
108 bool eval(
109 const double* luh,
112 double t,
113 const int level,
115 ) override {
116 double left_vertex[3];
117 double right_vertex[3];
118 bool elementBetweenPoints = true;
119
120 for (int i = 0; i < Dimensions; i++) {
121 left_vertex[i] = center[i] - dx[i] * 0.5;
122 right_vertex[i] = center[i] + dx[i] * 0.5;
123 elementBetweenPoints &= ((left_vertex[i] < rectangle_right[i]) && (right_vertex[i] > rectangle_left[i]));
124 }
125
126 if (elementBetweenPoints) { // solver->getMaximumAdaptiveMeshLevel()-1
128 return true;
129 }
130 return false;
131 }
132
133 private:
134 double rectangle_left[3];
136 };
137
138 template <class Shortcuts>
140 public:
141 RefineDownToPositionCustomCoordinates(int a_basisSize, int level, double a_position[3], int a_top, double* a_FL):
142 basisSize(a_basisSize),
143 max_level(level),
144 top(a_top) {
145 position[0] = a_position[0];
146 position[1] = a_position[1];
147 position[2] = a_position[2];
148 FL = new double[a_basisSize];
149 std::copy_n(a_FL, a_basisSize, FL);
150 }
151
152 bool eval(
153 const double* luh,
156 double t,
157 const int level,
159 ) {
160 double left_vertex = std::numeric_limits<double>::min();
161
162 Shortcuts s;
163 kernels::idx4 idx(basisSize, basisSize, basisSize, s.NumberOfUnknowns + s.NumberOfAuxiliaryVariables);
164 for (int j = 0; j < basisSize; j++) {
165 for (int k = 0; k < basisSize; k++) {
166 double vertex = 0;
167 for (int i = 0; i < basisSize; i++) {
168 if (top == 2) {
169 vertex += luh[idx(i, j, k, s.curve_grid + top)] * FL[i];
170 } else if (top == 1) {
171 vertex += luh[idx(j, i, k, s.curve_grid + top)] * FL[i];
172 } else if (top == 0) {
173 vertex += luh[idx(j, k, i, s.curve_grid + top)] * FL[i];
174 }
175 }
176 left_vertex = std::max(left_vertex, vertex);
177 }
178 }
179
180 bool elementAbovePointSource = (left_vertex < position[top]);
181 if (elementAbovePointSource) { // solver->getMaximumAdaptiveMeshLevel()-1
183 return true;
184 }
185 return false;
186 }
187
188 private:
189 double position[3];
190 double* FL;
193 int top;
194 };
195
196 template <class Shortcuts>
197 class RefineDownToPosition: public RefinementCriterion<Shortcuts> {
198 public:
199 RefineDownToPosition(int a_basisSize, int level, double a_position[3], int a_top):
200 basisSize(a_basisSize),
201 max_level(level),
202 top(a_top) {
203 position[0] = a_position[0];
204 position[1] = a_position[1];
205 position[2] = a_position[2];
206 }
207
208 bool eval(
209 const double* luh,
212 double t,
213 const int level,
215 ) {
216 double left_vertex[Dimensions];
217 for (int d = 0; d < Dimensions; d++) {
218 left_vertex[d] = center[d] - dx[d] * 0.5;
219 }
220
221 bool elementAbovePointSource = (left_vertex[top] < position[top]);
222 if (elementAbovePointSource) { // solver->getMaximumAdaptiveMeshLevel()-1
224 return true;
225 }
226 return false;
227 }
228
229 private:
230 double position[3];
233 int top;
234 };
235
236 template <class Shortcuts>
238 public:
239 RefinePositionCustomCoordinates(double a_position[3], int a_basisSize, double* a_FL, double* a_FR) {
240 position[0] = a_position[0];
241 position[1] = a_position[1];
242 position[2] = a_position[2];
243
244 basisSize = a_basisSize;
245 FR = new double[a_basisSize];
246 std::copy_n(a_FR, a_basisSize, FR);
247
248 FL = new double[a_basisSize];
249 std::copy_n(a_FL, a_basisSize, FL);
250 };
251
252 inline bool eval(
253 const double* luh,
256 double t,
257 const int level,
259 ) {
260 double left_vertex[3];
261 double right_vertex[3];
262 Shortcuts s;
263 bool positionInElement = true;
264 kernels::idx4 idx(basisSize, basisSize, basisSize, s.NumberOfUnknowns + s.NumberOfAuxiliaryVariables);
265 for (int i = 0; i < basisSize; i++) {
266 left_vertex[0] += luh[idx(0, 0, i, s.curve_grid + 0)] * FL[i];
267 right_vertex[0] += luh[idx(basisSize - 1, basisSize - 1, i, s.curve_grid + 0)] * FR[i];
268
269 left_vertex[1] += luh[idx(0, i, 0, s.curve_grid + 1)] * FL[i];
270 right_vertex[1] += luh[idx(basisSize - 1, i, basisSize - 1, s.curve_grid + 1)] * FR[i];
271
272 left_vertex[2] += luh[idx(i, 0, 0, s.curve_grid + 2)] * FL[i];
273 right_vertex[2] += luh[idx(i, basisSize - 1, basisSize - 1, s.curve_grid + 2)] * FR[i];
274 }
275
276 for (int i = 0; i < Dimensions; i++) {
277 positionInElement &= ((left_vertex[i] <= position[i]) && (right_vertex[i] >= position[i]));
278 }
279
280 if (positionInElement) {
282 return true;
283 }
284 return false;
285 }
286
287 private:
288 double position[3];
289 double* FL;
290 double* FR;
292 };
293
294 template <class Shortcuts>
295 class RefinePosition: public RefinementCriterion<Shortcuts> {
296 public:
297 RefinePosition(double a_position[3]) {
298 position[0] = a_position[0];
299 position[1] = a_position[1];
300 position[2] = a_position[2];
301 };
302
303 inline bool eval(
304 const double* luh,
307 double t,
308 const int level,
310 ) {
311 double left_vertex[3];
312 double right_vertex[3];
313
314 bool positionInElement = true;
315
316 for (int i = 0; i < Dimensions; i++) {
317 left_vertex[i] = center[i] - dx[i] * 0.5;
318 right_vertex[i] = center[i] + dx[i] * 0.5;
319 }
320
321 for (int i = 0; i < Dimensions; i++) {
322 positionInElement &= ((left_vertex[i] <= position[i]) && (right_vertex[i] >= position[i]));
323 }
324
325 if (positionInElement) {
327 return true;
328 std::cout << "refine ps" << std::endl;
329 }
330 return false;
331 }
332
333 private:
334 double position[3];
335 };
336
337 template <class Shortcuts>
338 class CoarseBoundaryLayer: public RefinementCriterion<Shortcuts> {
339 private:
340 std::vector<double> threshold_p[3];
341 std::vector<double> threshold_m[2];
342
344 int max_depth; // Maximal tracked depth
346 int top;
347 int left;
348 int front;
349
350 public:
352 int a_max_depth,
353 int a_coarsest_level,
354 double a_coarsest_size,
355 int a_top,
356 const double domainSize[3],
357 const double domainOffset[3]
358 ):
359 max_depth(a_max_depth),
360 coarsest_level(a_coarsest_level),
361 coarsest_size(a_coarsest_size),
362 top(a_top) {
363
364 left = (top + 1) % 3;
365 front = (top + 2) % 3;
366
367 // We first compute properties of the mesh for the coarsest mesh size
368
369 // The coorindates for the coars layers around the fine domain
370 double coarse_layer[3];
371
372 // We aim for 1/3 of the domain in each direction
373 /* coarse_layer[left ] = 1.0/3.0;
374 coarse_layer[top ] = 1.0/3.0;
375 coarse_layer[front] = 1.0/3.0;*/
376
377 coarse_layer[left] = 12.5 / 25.0;
378 coarse_layer[top] = 12.5 / 25.0;
379 coarse_layer[front] = 12.5 / 25.0;
380
381 double coarse_elts[3];
382 // Number of elements for the estimated layer
383 coarse_elts[left] = domainSize[left] / coarsest_size;
384 coarse_elts[top] = domainSize[top] / coarsest_size;
385 coarse_elts[front] = domainSize[front] / coarsest_size;
386
387 // Adjust positions to fit with coarsest mesh size,
388 // we round down elements inside the fine domain
389 coarse_layer[left] = std::floor(coarse_elts[left] * coarse_layer[left]) / coarse_elts[left];
390 coarse_layer[top] = std::floor(coarse_elts[top] * coarse_layer[top]) / coarse_elts[top];
391 coarse_layer[front] = std::floor(coarse_elts[front] * coarse_layer[front]) / coarse_elts[front];
392
393 // for each possible depth (0 beeing the coarsest layer) we store the refinement threshold
394 // left
395 threshold_p[0].resize(max_depth);
396 threshold_m[0].resize(max_depth);
397
398 // front
399 threshold_p[1].resize(max_depth);
400 threshold_m[1].resize(max_depth);
401
402 // top
403 threshold_p[2].resize(max_depth);
404
405 for (int depth = 0; depth < max_depth; depth++) {
406 // the total number of elements in each dimenion for the current depth
407 double num_elts[3];
408 num_elts[left] = coarse_elts[left] * pow(3.0, depth);
409 num_elts[top] = coarse_elts[top] * pow(3.0, depth);
410 num_elts[front] = coarse_elts[front] * pow(3.0, depth);
411
412 // the number of elements on one side of each layer for the current depth
413 int num_layer_elements[3];
414 num_layer_elements[left] = coarse_layer[left] * num_elts[left];
415 num_layer_elements[top] = coarse_layer[top] * num_elts[top];
416 num_layer_elements[front] = coarse_layer[front] * num_elts[front];
417
418 // For each depth level we add a single element to the step wise layer
419 for (int d = 0; d < depth; d++) {
420 num_layer_elements[left] += std::pow(3.0, d);
421 num_layer_elements[top] += std::pow(3.0, d);
422 num_layer_elements[front] += std::pow(3.0, d);
423 }
424
425 // width of the coarse layer for the current depth
426 double threshold_width[3];
427 threshold_width[0] = domainSize[left] / num_elts[left] * num_layer_elements[left];
428 threshold_width[1] = domainSize[front] / num_elts[front] * num_layer_elements[front];
429 threshold_width[2] = domainSize[top] / num_elts[top] * num_layer_elements[top];
430
431 // boundaries of the coarse domain
432 // index for level = 2 is 0
433 threshold_m[0][depth] = domainOffset[left] + threshold_width[0];
434 threshold_m[1][depth] = domainOffset[front] + threshold_width[1];
435
436 threshold_p[0][depth] = domainOffset[left] + domainSize[left] - threshold_width[0];
437 threshold_p[1][depth] = domainOffset[front] + domainSize[front] - threshold_width[1];
438 threshold_p[2][depth] = domainOffset[top] + domainSize[top] - threshold_width[2];
439 }
440 }
441
442 bool eval(
443 const double* luh,
446 double t,
447 const int level,
449 ) {
450 // depth of the current element
451 int depth = level - coarsest_level;
452
453 if (depth >= max_depth) {
454 return false;
455 }
456
457 // check if cell is in the boundary layer
458 bool cellInBoundaryLayer = (center[left] < threshold_m[0][depth] || center[left] > threshold_p[0][depth])
459 || (/*center[1] < boundary_y_left ||*/ center[top] > threshold_p[2][depth])
460 || (center[front] < threshold_m[1][depth] || center[front] > threshold_p[1][depth]);
461
462 if (cellInBoundaryLayer) {
464 return true;
465 }
466
467 return false;
468 }
469 };
470
471 template <class Shortcuts>
473 public:
474 RefineCubeAroundPosition(double a_position[3], double radius) {
475 for (int i = 0; i < Dimensions; i++) {
476 left_vertice[i] = a_position[i] - radius;
477 right_vertice[i] = a_position[i] + radius;
478 }
479 }
480
481 bool eval(
482 const double* luh,
485 double t,
486 const int level,
488 ) {
489 bool inRadius = true;
490 for (int i = 0; i < Dimensions; i++) {
491 inRadius &= center[i] < right_vertice[i];
492 inRadius &= center[i] > left_vertice[i];
493 }
494
495 if (inRadius) {
497 return true;
498 }
499
500 return false;
501 }
502
503 private:
504 double left_vertice[3];
505 double right_vertice[3];
506 };
507
508 template <class Shortcuts>
509 class RefineFilterCube: public RefinementCriterion<Shortcuts> {
510 public:
511 RefineFilterCube(double a_left_vertice[3], double a_right_vertice[3], int a_level_inside, int a_level_outside):
512 level_inside(a_level_inside),
513 level_outside(a_level_outside) {
514 for (int i = 0; i < Dimensions; i++) {
515 left_vertice[i] = a_left_vertice[i];
516 right_vertice[i] = a_right_vertice[i];
517 }
518 }
519
520 bool eval(
521 const double* luh,
524 double t,
525 const int level,
527 ) {
528 bool left_vertice_in = true;
529 bool right_vertice_in = true;
530 for (int i = 0; i < Dimensions; i++) {
531 left_vertice_in &= center[i] - dx[i] < right_vertice[i];
532 left_vertice_in &= center[i] - dx[i] > left_vertice[i];
533
534 right_vertice_in &= center[i] + dx[i] < right_vertice[i];
535 right_vertice_in &= center[i] + dx[i] > left_vertice[i];
536 }
537
538 if (left_vertice_in || right_vertice_in) {
539 if (level == level_inside) {
542 }
543 }
544 } else {
545 if (level == level_outside) {
548 }
549 }
550 }
551 return true;
552 }
553
554 private:
555 double left_vertice[3];
556 double right_vertice[3];
559 };
560
561} // namespace Refinement
562
563#endif
std::vector< double > threshold_m[2]
Definition refinement.h:341
std::vector< double > threshold_p[3]
Definition refinement.h:340
bool eval(const double *luh, const tarch::la::Vector< Dimensions, double > &center, const tarch::la::Vector< Dimensions, double > &dx, double t, const int level, ::exahype2::RefinementCommand &refine)
Definition refinement.h:442
CoarseBoundaryLayer(int a_max_depth, int a_coarsest_level, double a_coarsest_size, int a_top, const double domainSize[3], const double domainOffset[3])
Definition refinement.h:351
bool eval(const double *luh, const tarch::la::Vector< Dimensions, double > &center, const tarch::la::Vector< Dimensions, double > &dx, double t, const int level, ::exahype2::RefinementCommand &refine) override
Definition refinement.h:108
RefineBetweenPositions(double a_left[3], double a_right[3])
Definition refinement.h:98
bool eval(const double *luh, const tarch::la::Vector< Dimensions, double > &center, const tarch::la::Vector< Dimensions, double > &dx, double t, const int level, ::exahype2::RefinementCommand &refine)
Definition refinement.h:481
RefineCubeAroundPosition(double a_position[3], double radius)
Definition refinement.h:474
RefineDownToPositionCustomCoordinates(int a_basisSize, int level, double a_position[3], int a_top, double *a_FL)
Definition refinement.h:141
bool eval(const double *luh, const tarch::la::Vector< Dimensions, double > &center, const tarch::la::Vector< Dimensions, double > &dx, double t, const int level, ::exahype2::RefinementCommand &refine)
Definition refinement.h:152
bool eval(const double *luh, const tarch::la::Vector< Dimensions, double > &center, const tarch::la::Vector< Dimensions, double > &dx, double t, const int level, ::exahype2::RefinementCommand &refine)
Definition refinement.h:208
RefineDownToPosition(int a_basisSize, int level, double a_position[3], int a_top)
Definition refinement.h:199
bool eval(const double *luh, const tarch::la::Vector< Dimensions, double > &center, const tarch::la::Vector< Dimensions, double > &dx, double t, const int level, ::exahype2::RefinementCommand &refine)
Definition refinement.h:520
RefineFilterCube(double a_left_vertice[3], double a_right_vertice[3], int a_level_inside, int a_level_outside)
Definition refinement.h:511
RefinePositionCustomCoordinates(double a_position[3], int a_basisSize, double *a_FL, double *a_FR)
Definition refinement.h:239
bool eval(const double *luh, const tarch::la::Vector< Dimensions, double > &center, const tarch::la::Vector< Dimensions, double > &dx, double t, const int level, ::exahype2::RefinementCommand &refine)
Definition refinement.h:252
bool eval(const double *luh, const tarch::la::Vector< Dimensions, double > &center, const tarch::la::Vector< Dimensions, double > &dx, double t, const int level, ::exahype2::RefinementCommand &refine)
Definition refinement.h:303
RefinePosition(double a_position[3])
Definition refinement.h:297
virtual bool eval(const double *luh, const tarch::la::Vector< Dimensions, double > &center, const tarch::la::Vector< Dimensions, double > &dx, double t, const int level, ::exahype2::RefinementCommand &refine)=0
bool eval(const double *luh, const tarch::la::Vector< Dimensions, double > &center, const tarch::la::Vector< Dimensions, double > &dx, double t, const int level, ::exahype2::RefinementCommand &refine) override
Definition refinement.h:78
bool eval(const double *luh, const tarch::la::Vector< Dimensions, double > &center, const tarch::la::Vector< Dimensions, double > &dx, double t, const int level, ::exahype2::RefinementCommand &refine) override
Definition refinement.h:29
trackVelocity(int a_basisSize, double a_refine_threshold, double a_coarsen_threshold)
Definition refinement.h:24
bool equals(const Matrix< Rows, Cols, Scalar > &lhs, const Matrix< Rows, Cols, Scalar > &rhs, const Scalar &tolerance=NUMERICAL_ZERO_DIFFERENCE)
Compares to matrices on equality by means of a numerical accuracy.
Simple vector class.
Definition Vector.h:159