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 : #include "common/math/ugmath_types.h"
34 : #include "horizontal_anisotropy_adjuster.h"
35 : #include "common/util/vec_for_each.h"
36 :
37 : namespace ug{
38 :
39 : static inline bool IsVertical(const vector1&, const vector1&)
40 : {
41 : return false;
42 : }
43 :
44 : static inline bool IsVertical(const vector2& from, const vector2& to)
45 : {
46 0 : return fabs(from[0] - to[0]) < SMALL;
47 : }
48 :
49 : static inline bool IsVertical(const vector3& from, const vector3& to)
50 : {
51 0 : return (fabs(from[0] - to[0]) < SMALL) && (fabs(from[1] - to[1]) < SMALL);
52 : }
53 :
54 :
55 : static inline bool NotVertical(const vector1&, const vector1&)
56 : {
57 : return true;
58 : }
59 :
60 : static inline bool NotVertical(const vector2& from, const vector2& to)
61 : {
62 0 : return fabs(from[0] - to[0]) > SMALL;
63 : }
64 :
65 : static inline bool NotVertical(const vector3& from, const vector3& to)
66 : {
67 0 : return (fabs(from[0] - to[0]) > SMALL) || (fabs(from[1] - to[1]) > SMALL);
68 : }
69 :
70 :
71 : template <class TAPos>
72 0 : void HorizontalAnisotropyAdjuster<TAPos>::
73 : ref_marks_changed(IRefiner& ref,
74 : const std::vector<Vertex*>& vrts,
75 : const std::vector<Edge*>& edges,
76 : const std::vector<Face*>& faces,
77 : const std::vector<Volume*>& vols)
78 : {
79 0 : UG_COND_THROW(!ref.grid(), "A grid has to be associated with the given"
80 : " refiner in order to adjust refinement marks.");
81 :
82 0 : Grid& grid = *ref.grid();
83 0 : position_accessor_t aaPos = Grid::VertexAttachmentAccessor<position_attachment_t>(grid, m_aPos);
84 :
85 : Grid::edge_traits::secure_container assEdges;
86 : Grid::face_traits::secure_container assFaces;
87 : Grid::volume_traits::secure_container assVols;
88 :
89 0 : for_each_in_vec(Volume* vol, vols){
90 0 : if(!(ref.get_mark(vol) & RM_ANISOTROPIC))
91 0 : continue; // only process anisotropic volumes
92 :
93 : grid.associated_elements(assFaces, vol);
94 0 : for_each_in_vec(Face* f, assFaces){
95 0 : if(!(ref.get_mark(f) & RM_ANISOTROPIC))
96 0 : ref.mark(f, RM_ANISOTROPIC);
97 : }end_for;
98 : }end_for;
99 :
100 :
101 0 : for_each_in_vec(Face* f, faces){
102 0 : if(!(ref.get_mark(f) & RM_ANISOTROPIC))
103 0 : continue;
104 :
105 : grid.associated_elements(assEdges, f);
106 : bool horizontalMarked = false;
107 : bool verticalMarked = false;
108 : bool hasVerticalEdge = false;
109 0 : for_each_in_vec(Edge* e, assEdges){
110 0 : const bool isVertical = IsVertical(aaPos[e->vertex(0)], aaPos[e->vertex(1)]);
111 0 : hasVerticalEdge |= isVertical;
112 :
113 0 : if(ref.get_mark(e) & (RM_ANISOTROPIC | RM_REFINE | RM_CLOSURE)){
114 0 : if(isVertical)
115 : verticalMarked = true;
116 : else
117 : horizontalMarked = true;
118 : }
119 : }end_for;
120 :
121 : // if the face contains a vertical edge and has a marked
122 : // horizontal edge, we'll make sure that all horizontal
123 : // edges are marked.
124 : // If however a vertical edge is also marked, there's nothing we can do
125 0 : if(hasVerticalEdge && horizontalMarked && !verticalMarked){
126 0 : for_each_in_vec(Edge* e, assEdges){
127 0 : if(NotVertical(aaPos[e->vertex(0)], aaPos[e->vertex(1)]))
128 0 : ref.mark(e);
129 : }end_for;
130 : }
131 : }end_for;
132 :
133 :
134 : // mark all associated unmarked faces and volumes of marked edges as closure elements
135 0 : if(grid.num_volumes() > 0){
136 0 : for_each_in_vec(Edge*e, edges){
137 : grid.associated_elements(assVols, e);
138 0 : for_each_in_vec(Volume* vol, assVols){
139 0 : if(!(ref.get_mark(vol) & (RM_REFINE | RM_ANISOTROPIC | RM_CLOSURE)))
140 0 : ref.mark(vol, RM_CLOSURE);
141 : }end_for;
142 : }end_for;
143 : }
144 :
145 0 : if(grid.num_faces() > 0){
146 0 : for_each_in_vec(Edge*e, edges){
147 : grid.associated_elements(assFaces, e);
148 0 : for_each_in_vec(Face* f, assFaces){
149 0 : if(!(ref.get_mark(f) & (RM_REFINE | RM_ANISOTROPIC | RM_CLOSURE)))
150 0 : ref.mark(f, RM_CLOSURE);
151 : }end_for;
152 : }end_for;
153 : }
154 0 : }
155 :
156 : template class HorizontalAnisotropyAdjuster<AVector1>;
157 : template class HorizontalAnisotropyAdjuster<AVector2>;
158 : template class HorizontalAnisotropyAdjuster<AVector3>;
159 :
160 : }// end of namespace
|