Loading [MathJax]/extensions/tex2jax.js

DUNE-FEM (unstable)

default.hh
1#ifndef DUNE_FEMPY_PY_DEFAULT_MARKING_HH
2#define DUNE_FEMPY_PY_DEFAULT_MARKING_HH
3
4#include <array>
5#include <memory>
6#include <dune/geometry/referenceelements.hh>
7#include <dune/fem/gridpart/common/gridpart.hh>
8#include <dune/fem/function/localfunction/const.hh>
9
10namespace Dune
11{
12 namespace Fem
13 {
14 namespace GridAdaptation
15 {
16 struct Marker
17 {
18 static const int refine = 1;
19 static const int keep = 0;
20 static const int coarsen = -1;
21 };
22
23 // Indicator is of type DiscreteFunction or GridFunction
24 template <class Grid, class Indicator>
25 static inline
26 std::pair< int, int >
27 mark( Grid& grid, Indicator& indicator,
28 const double refineTolerance, const double coarsenTolerance,
29 const int minLevel = 0,
30 int maxLevel = -1,
31 const double minVolume = -1.,
32 double maxVolume = -1.0,
33 const bool markNeighbors = false,
34 const bool statistics = false ) // if true return number of marked cells
35 {
36 Dune::Fem::ConstLocalFunction<Indicator> localIndicator(indicator);
37 typename Indicator::RangeType value;
38
39 std::array< int, 2 > sumMarks = {{ 0,0 }};
40
41 int& refMarked = sumMarks[ 0 ];
42 int& crsMarked = sumMarks[ 1 ];
43
44 if ( maxLevel < 0 )
46
47 const bool useVolumeRefinement = minVolume > 0.0;
48 const bool useVolumeCoarsening = maxVolume > 0.0;
49 if ( ! useVolumeCoarsening )
50 {
51 // this will avoid volume check
53 }
54
55 const auto& gridPart = indicator.space().gridPart();
56
57 for (const auto &e : indicator.space())
58 {
59 if (!e.isLeaf()) continue;
60
61 const auto &gridEntity = Dune::Fem::gridEntity(e);
62 int marked = grid.getMark(gridEntity);
63 if (marked==1) continue;
64
65 localIndicator.bind(e);
66 const auto &center = Dune::referenceElement< typename Grid::ctype, Grid::dimension>( e.type() ).position(0,0);
67 localIndicator.evaluate(center,value);
68 double eta = std::abs(value[0]);
69 const int level = e.level();
70
71 // compute volume only if necessary
72 const double volume = (useVolumeRefinement || useVolumeCoarsening) ? localIndicator.geometry().volume() : 0.0;
73
74 // check that estimator is larger than tolerance
75 // check that level is smaller than minimal level
76 // check that volume of element is larger than minimal acceptable volume
77 if (eta>refineTolerance && level<maxLevel && volume>minVolume)
78 {
79 refMarked += grid.mark( Marker::refine, gridEntity);
80 if( markNeighbors )
81 {
82 const auto iEnd = gridPart.iend( e );
83 for( auto it = gridPart.ibegin( e ); it != iEnd; ++it )
84 {
85 const auto& intersection = *it;
86 if( intersection.neighbor() )
87 {
88 const auto& outside = intersection.outside();
89 const double outsideVol = (useVolumeRefinement) ? outside.geometry().volume() : 0.0;
90 if (outside.level()<maxLevel && outsideVol>minVolume )
91 refMarked += grid.mark( Marker::refine, Dune::Fem::gridEntity(outside) );
92 }
93 }
94
95 }
96 }
97 else if (eta<coarsenTolerance && level>minLevel && volume<maxVolume )
98 crsMarked += grid.mark( Marker::coarsen, gridEntity);
99 else
100 grid.mark(Marker::keep, gridEntity);
101 }
102
103 // only do communication if statistics is enabled
104 if( statistics )
105 {
106 gridPart.comm().sum( sumMarks.data(), 2 );
107 return std::make_pair( refMarked, crsMarked );
108 }
109 else
110 return std::make_pair( int(-1), int(-1));
111 } // end mark
112
113 } // end namespace GridAdaptation
114
115
116 namespace SpaceAdaptation
117 {
118 // Indicator is of type DiscreteFunction or GridFunction
119 template <class Space, class Indicator>
120 static inline
121 std::pair< int, int >
122 mark( Space& space, Indicator& indicator,
123 const double refineTolerance, const double coarsenTolerance, // tolerances for increasing or decreasing polynomial order
124 const int minOrder, const int maxOrder, // min and max polOrders [0, space.order()]
125 const bool markNeighbors = false, // also mark neighbors
126 const bool statistics = false ) // if true return number of marked cells
127 {
128 Dune::Fem::ConstLocalFunction<Indicator> localIndicator(indicator);
129 typename Indicator::RangeType value;
130 if( minOrder < 0 && minOrder > space.order() )
131 DUNE_THROW(Dune::InvalidStateException,"SpaceAdaptation::mark: minOrder out of range: select something between 0 and the space's order! Selected was " << minOrder);
132
133 if( maxOrder < minOrder && maxOrder > space.order() )
134 DUNE_THROW(Dune::InvalidStateException,"SpaceAdaptation::mark: maxOrder out of range: select something between minOrder and the space's order! Selected was " << maxOrder);
135
136 const auto& gridPart = space.gridPart();
137
138 std::array< int, 2 > sumMarks = {{ 0,0 }};
139 int& refMarked = sumMarks[ 0 ]; // increased polynomial order
140 int& crsMarked = sumMarks[ 1 ]; // decreased polynomial order
141
142 std::vector< bool > marked;
143 if( markNeighbors )
144 marked.resize( gridPart.indexSet().size( 0 ), false );
145
146 for (const auto &e : space)
147 {
148 localIndicator.bind(e);
149 const auto &center = Dune::referenceElement( e ).position(0,0);
150 localIndicator.evaluate(center,value);
151 double eta = std::abs(value[0]);
152
153 const bool markedAlready = ( markNeighbors ) ? marked[ gridPart.indexSet().index( e ) ] : false;
154
155 // get current polynomial degree
156 const int currentOrder = space.order( e );
157 int polOrder = currentOrder;
158
159 // if the element itself has been marked check that
160 // the current mark is lower than the proposed mark
161 if( markedAlready )
162 {
163 // if the current mark is higher than the current order just continue
164 if( space.getMark( e ) > polOrder )
165 continue ;
166 }
167
168 // check that estimator is larger than tolerance
169 // check that polOrder is larger than minimal polOrder
170 if (eta > refineTolerance && polOrder < maxOrder)
171 {
172 // increase order by one
173 ++ polOrder;
174
175 if( markNeighbors )
176 {
177 const auto iEnd = gridPart.iend( e );
178 for( auto it = gridPart.ibegin( e ); it != iEnd; ++it )
179 {
180 const auto& intersection = *it;
181 if( intersection.neighbor() )
182 {
183 const auto& outside = intersection.outside();
184 // mark neighbor for refinement only (i.e. if polynomial order is higher)
185 const int nbOrder = space.getMark( outside );
186 if ( polOrder > nbOrder )
187 {
188 space.mark( polOrder, outside );
189 ++refMarked;
190
191 // mark as marked (marked should be resized correctly)
192 marked[ gridPart.indexSet().index( outside ) ] = true;
193 }
194 }
195 }
196 }
197 }
198 else if (! markedAlready && eta < coarsenTolerance && polOrder > minOrder)
199 {
200 -- polOrder;
201 }
202 // else keep the same polynomial order
203
204 // increase counters
205 if( polOrder > currentOrder )
206 ++refMarked;
207 else if ( polOrder < currentOrder )
208 ++crsMarked;
209
210 // mark polynomial order for current element
211 space.mark( polOrder, e );
212
213 // mark as marked
214 if( markNeighbors )
215 marked[ gridPart.indexSet().index( e ) ] = true;
216 }
217
218 // only do communication if statistics is enabled
219 if( statistics )
220 {
221 gridPart.comm().sum( sumMarks.data(), 2 );
222 return std::make_pair( refMarked, crsMarked );
223 }
224 else
225 return std::make_pair( int(-1), int(-1));
226 } // end mark
227
228 } // end namespace SpaceAdaptation
229
230 } // end namespace Fem
231} // end namespace Dune
232#endif
Default exception if a function was called while the object is not in a valid state for that function...
Definition: exceptions.hh:375
#define DUNE_THROW(E,...)
Definition: exceptions.hh:314
unspecified value type referenceElement(T &&... t)
Returns a reference element for the objects t....
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:485
Dune namespace.
Definition: alignedallocator.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Apr 23, 22:35, 2025)