Line data Source code
1 : /*
2 : * Copyright (c) 2015: G-CSC, Goethe University Frankfurt
3 : * Author: Sebastian Reiter
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : #ifndef __H__UG_refinement_mark_util_impl
34 : #define __H__UG_refinement_mark_util_impl
35 :
36 : #include <algorithm>
37 : #include <limits>
38 : #include "refinement_mark_util.h"
39 : #include "lib_grid/lg_base.h"
40 : #include "lib_grid/refinement/refiner_interface.h"
41 :
42 : namespace ug{
43 :
44 : template <class TRef, class TIter, class TAAPos>
45 0 : void MarkForAnisotropicRefinement (
46 : Grid& grid,
47 : TRef& ref,
48 : number minEdgeRatio,
49 : TIter elemsBegin,
50 : TIter elemsEnd,
51 : TAAPos aaPos)
52 : {
53 : using namespace std;
54 : typedef typename TIter::value_type elem_ptr_t;
55 :
56 : number minEdgeRatioSq = sq(minEdgeRatio);
57 : Grid::edge_traits::secure_container assEdges;
58 :
59 0 : for(TIter iter = elemsBegin; iter != elemsEnd; ++iter){
60 : elem_ptr_t elem = *iter;
61 0 : ref.mark(elem, RM_CLOSURE);
62 :
63 : grid.associated_elements(assEdges, elem);
64 :
65 0 : if(assEdges.size() < 2)
66 0 : continue;
67 :
68 : // find the length of the shortest and the longest edge
69 0 : number shortestLenSq = numeric_limits<number>::max();
70 0 : number longestLenSq = 0;
71 :
72 0 : for_each_in_vec(Edge* e, assEdges){
73 0 : number lenSq = EdgeLengthSq(e, aaPos);
74 0 : shortestLenSq = min(shortestLenSq, lenSq);
75 0 : longestLenSq = max(longestLenSq, lenSq);
76 : }end_for;
77 :
78 0 : if(longestLenSq < SMALL_SQ)
79 0 : continue;
80 :
81 0 : if(shortestLenSq / longestLenSq >= minEdgeRatioSq)
82 0 : continue;
83 :
84 : // the element is anisotropic mark it and all long edges
85 0 : ref.mark(elem, RM_ANISOTROPIC);
86 : // refine all edges that are at least half as long as the longest one
87 0 : number thresholdLenSq = shortestLenSq / minEdgeRatioSq;
88 0 : for_each_in_vec(Edge* e, assEdges){
89 0 : if(EdgeLengthSq(e, aaPos) > thresholdLenSq){
90 0 : ref.mark(e, RM_REFINE);
91 : }
92 : }end_for;
93 : }
94 0 : }
95 :
96 : template <class TRef, class TEdgeIter, class TAAPos>
97 0 : void MarkForRefinementByDirection (
98 : TRef& ref,
99 : TAAPos aaPos,
100 : TEdgeIter edgesBegin,
101 : TEdgeIter edgesEnd,
102 : const typename TAAPos::ValueType& dir,
103 : number minDeviationAngle,
104 : number maxDeviationAngle,
105 : bool selectFlipped)
106 : {
107 0 : UG_COND_THROW(!ref.grid(), "The given refiner has to operate on a grid");
108 :
109 : typedef typename TAAPos::ValueType vector_t;
110 :
111 0 : Grid& g = *ref.grid();
112 :
113 : vector_t n;
114 0 : VecNormalize(n, dir);
115 :
116 0 : number maxDot = cos(deg_to_rad(minDeviationAngle));
117 0 : number minDot = cos(deg_to_rad(maxDeviationAngle));
118 :
119 : Grid::face_traits::secure_container faces;
120 : Grid::volume_traits::secure_container vols;
121 :
122 0 : for(TEdgeIter eIter = edgesBegin; eIter != edgesEnd; ++eIter){
123 : Edge* e = *eIter;
124 : vector_t dir;
125 0 : VecSubtract(dir, aaPos[e->vertex(1)], aaPos[e->vertex(0)]);
126 0 : VecNormalize(dir, dir);
127 : number d = VecDot(dir, n);
128 0 : if((d >= minDot - SMALL && d <= maxDot + SMALL) ||
129 0 : (selectFlipped && (-d >= minDot - SMALL && -d <= maxDot + SMALL)))
130 : {
131 0 : ref.mark(e);
132 :
133 : g.associated_elements(faces, e);
134 0 : for(size_t i = 0; i < faces.size(); ++i)
135 0 : ref.mark(faces[i], RM_CLOSURE);
136 :
137 : g.associated_elements(vols, e);
138 0 : for(size_t i = 0; i < vols.size(); ++i)
139 0 : ref.mark(vols[i], RM_CLOSURE);
140 :
141 : }
142 : }
143 0 : }
144 :
145 : }// end of namespace
146 :
147 : #endif //__H__UG_refinement_mark_util_impl
|