18
20
#include "checkgeometryinfather.cc"
19
21
#include "checkintersectionit.cc"
21
#include <dune/common/mpihelper.hh>
23
#include <dune/common/parallel/mpihelper.hh>
23
25
using namespace Dune;
25
27
class ArcOfCircle : public Dune::BoundarySegment<2>
29
ArcOfCircle(const Dune::FieldVector<double,2>& center, double radius,
30
double fromAngle, double toAngle)
31
ArcOfCircle(const Dune::FieldVector<double,2>& center, double radius,
32
double fromAngle, double toAngle)
31
33
: center_(center), radius_(radius), fromAngle_(fromAngle), toAngle_(toAngle)
34
Dune::FieldVector<double,2> operator()(const Dune::FieldVector<double,1>& local) const {
36
double angle = fromAngle_ + local[0]*(toAngle_ - fromAngle_);
38
Dune::FieldVector<double,2> result = center_;
39
result[0] += radius_ * std::cos(angle);
40
result[1] += radius_ * std::sin(angle);
45
Dune::FieldVector<double,2> center_;
36
Dune::FieldVector<double,2> operator()(const Dune::FieldVector<double,1>& local) const {
38
double angle = fromAngle_ + local[0]*(toAngle_ - fromAngle_);
40
Dune::FieldVector<double,2> result = center_;
41
result[0] += radius_ * std::cos(angle);
42
result[1] += radius_ * std::sin(angle);
47
Dune::FieldVector<double,2> center_;
55
57
void makeHalfCircleQuad(Dune::UGGrid<2>& grid, bool boundarySegments, bool parametrization)
57
Dune::GridFactory<Dune::UGGrid<2> > factory(&grid);
59
// /////////////////////////////
60
// Create boundary segments
61
// /////////////////////////////
62
if (boundarySegments) {
64
FieldVector<double,2> center(0);
67
std::vector<unsigned int> vertices(2);
69
if (parametrization) {
71
vertices[0] = 1; vertices[1] = 2;
72
factory.insertBoundarySegment(vertices, shared_ptr<BoundarySegment<2,2> >(new ArcOfCircle(center, 15, M_PI, M_PI*4/3)));
74
vertices[0] = 2; vertices[1] = 3;
75
factory.insertBoundarySegment(vertices, shared_ptr<BoundarySegment<2,2> >(new ArcOfCircle(center, 15, M_PI*4/3, M_PI*5/3)));
77
vertices[0] = 3; vertices[1] = 0;
78
factory.insertBoundarySegment(vertices, shared_ptr<BoundarySegment<2,2> >(new ArcOfCircle(center, 15, M_PI*5/3, M_PI*2)));
82
vertices[0] = 1; vertices[1] = 2;
83
factory.insertBoundarySegment(vertices);
85
vertices[0] = 2; vertices[1] = 3;
86
factory.insertBoundarySegment(vertices);
88
vertices[0] = 3; vertices[1] = 0;
89
factory.insertBoundarySegment(vertices);
59
Dune::GridFactory<Dune::UGGrid<2> > factory(&grid);
61
// /////////////////////////////
62
// Create boundary segments
63
// /////////////////////////////
64
if (boundarySegments) {
66
FieldVector<double,2> center(0);
69
std::vector<unsigned int> vertices(2);
71
if (parametrization) {
73
vertices[0] = 1; vertices[1] = 2;
74
factory.insertBoundarySegment(vertices, shared_ptr<BoundarySegment<2,2> >(new ArcOfCircle(center, 15, M_PI, M_PI*4/3)));
76
vertices[0] = 2; vertices[1] = 3;
77
factory.insertBoundarySegment(vertices, shared_ptr<BoundarySegment<2,2> >(new ArcOfCircle(center, 15, M_PI*4/3, M_PI*5/3)));
79
vertices[0] = 3; vertices[1] = 0;
80
factory.insertBoundarySegment(vertices, shared_ptr<BoundarySegment<2,2> >(new ArcOfCircle(center, 15, M_PI*5/3, M_PI*2)));
84
vertices[0] = 1; vertices[1] = 2;
85
factory.insertBoundarySegment(vertices);
87
vertices[0] = 2; vertices[1] = 3;
88
factory.insertBoundarySegment(vertices);
90
vertices[0] = 3; vertices[1] = 0;
91
factory.insertBoundarySegment(vertices);
95
// ///////////////////////
97
// ///////////////////////
98
FieldVector<double,2> pos;
100
pos[0] = 15; pos[1] = 15;
101
factory.insertVertex(pos);
103
pos[0] = -15; pos[1] = 15;
104
factory.insertVertex(pos);
106
pos[0] = -7.5; pos[1] = 2.00962;
107
factory.insertVertex(pos);
109
pos[0] = 7.5; pos[1] = 2.00962;
110
factory.insertVertex(pos);
116
std::vector<unsigned int> cornerIDs(4);
122
factory.insertElement(GeometryType(GeometryType::cube,2), cornerIDs);
124
// //////////////////////////////////////
125
// Finish initialization
126
// //////////////////////////////////////
127
factory.createGrid();
97
// ///////////////////////
99
// ///////////////////////
100
FieldVector<double,2> pos;
102
pos[0] = 15; pos[1] = 15;
103
factory.insertVertex(pos);
105
pos[0] = -15; pos[1] = 15;
106
factory.insertVertex(pos);
108
pos[0] = -7.5; pos[1] = 2.00962;
109
factory.insertVertex(pos);
111
pos[0] = 7.5; pos[1] = 2.00962;
112
factory.insertVertex(pos);
118
std::vector<unsigned int> cornerIDs(4);
124
factory.insertElement(GeometryType(GeometryType::cube,2), cornerIDs);
126
// //////////////////////////////////////
127
// Finish initialization
128
// //////////////////////////////////////
129
factory.createGrid();
151
153
void generalTests(bool greenClosure)
153
// /////////////////////////////////////////////////////////////////
154
// Prelude: the UGGrid implementation relies on the face that std::array,
155
// Dune::FieldVector, and C-arrays have the same memory layout. Here
156
// we make sure this is really so.
157
// /////////////////////////////////////////////////////////////////
159
double cArray[3] = {1,2,3};
161
for (int i=0; i<3; i++) {
162
assert(cArray[i] == (*((FieldVector<double,3>*)&cArray))[i]);
163
assert(cArray[i] == (*((array<double,3>*)&cArray))[i]);
166
// //////////////////////////////////////////////////////////
167
// Make some grids for testing
168
// //////////////////////////////////////////////////////////
170
std::auto_ptr<Dune::UGGrid<2> > grid2d(make2DHybridTestGrid<Dune::UGGrid<2> >());
171
std::auto_ptr<Dune::UGGrid<3> > grid3d(make3DHybridTestGrid<Dune::UGGrid<3> >());
173
// Switch of the green closure, if requested
175
grid2d->setClosureType(UGGrid<2>::NONE);
176
grid3d->setClosureType(UGGrid<3>::NONE);
183
// check communication interface
184
checkCommunication(*grid2d,-1,Dune::dvverb);
185
checkCommunication(*grid3d,-1,Dune::dvverb);
186
for(int l=0; l<=grid2d->maxLevel(); ++l)
187
checkCommunication(*grid2d,l,Dune::dvverb);
188
for(int l=0; l<=grid3d->maxLevel(); ++l)
189
checkCommunication(*grid3d,l,Dune::dvverb);
191
// create hybrid grid
192
markOne(*grid2d,0,1) ;
193
markOne(*grid3d,0,1) ;
198
// check communication interface
199
checkCommunication(*grid2d,-1,Dune::dvverb);
200
checkCommunication(*grid3d,-1,Dune::dvverb);
201
for(int l=0; l<=grid2d->maxLevel(); ++l)
202
checkCommunication(*grid2d,l,Dune::dvverb);
203
for(int l=0; l<=grid3d->maxLevel(); ++l)
204
checkCommunication(*grid3d,l,Dune::dvverb);
206
grid2d->globalRefine(1);
207
grid3d->globalRefine(1);
211
// check communication interface
212
checkCommunication(*grid2d,-1,Dune::dvverb);
213
checkCommunication(*grid3d,-1,Dune::dvverb);
214
for(int l=0; l<=grid2d->maxLevel(); ++l)
215
checkCommunication(*grid2d,l,Dune::dvverb);
216
for(int l=0; l<=grid3d->maxLevel(); ++l)
217
checkCommunication(*grid3d,l,Dune::dvverb);
219
// check geometry lifetime
220
checkGeometryLifetime( grid2d->leafView() );
221
checkGeometryLifetime( grid3d->leafView() );
223
// check the method geometryInFather()
224
checkGeometryInFather(*grid2d);
225
checkGeometryInFather(*grid3d);
227
// check the intersection iterator
228
checkIntersectionIterator(*grid2d);
229
checkIntersectionIterator(*grid3d);
155
// /////////////////////////////////////////////////////////////////
156
// Prelude: the UGGrid implementation relies on the face that std::array,
157
// Dune::FieldVector, and C-arrays have the same memory layout. Here
158
// we make sure this is really so.
159
// /////////////////////////////////////////////////////////////////
161
double cArray[3] = {1,2,3};
163
for (int i=0; i<3; i++) {
164
assert(cArray[i] == (*((FieldVector<double,3>*)&cArray))[i]);
165
assert(cArray[i] == (*((array<double,3>*)&cArray))[i]);
168
// //////////////////////////////////////////////////////////
169
// Make some grids for testing
170
// //////////////////////////////////////////////////////////
172
std::auto_ptr<Dune::UGGrid<2> > grid2d(make2DHybridTestGrid<Dune::UGGrid<2> >());
173
std::auto_ptr<Dune::UGGrid<3> > grid3d(make3DHybridTestGrid<Dune::UGGrid<3> >());
175
// Switch of the green closure, if requested
177
grid2d->setClosureType(UGGrid<2>::NONE);
178
grid3d->setClosureType(UGGrid<3>::NONE);
185
// check communication interface
186
checkCommunication(*grid2d,-1,Dune::dvverb);
187
checkCommunication(*grid3d,-1,Dune::dvverb);
188
for(int l=0; l<=grid2d->maxLevel(); ++l)
189
checkCommunication(*grid2d,l,Dune::dvverb);
190
for(int l=0; l<=grid3d->maxLevel(); ++l)
191
checkCommunication(*grid3d,l,Dune::dvverb);
193
// create hybrid grid
194
markOne(*grid2d,0,1) ;
195
markOne(*grid3d,0,1) ;
200
// check communication interface
201
checkCommunication(*grid2d,-1,Dune::dvverb);
202
checkCommunication(*grid3d,-1,Dune::dvverb);
203
for(int l=0; l<=grid2d->maxLevel(); ++l)
204
checkCommunication(*grid2d,l,Dune::dvverb);
205
for(int l=0; l<=grid3d->maxLevel(); ++l)
206
checkCommunication(*grid3d,l,Dune::dvverb);
208
grid2d->globalRefine(1);
209
grid3d->globalRefine(1);
213
// check communication interface
214
checkCommunication(*grid2d,-1,Dune::dvverb);
215
checkCommunication(*grid3d,-1,Dune::dvverb);
216
for(int l=0; l<=grid2d->maxLevel(); ++l)
217
checkCommunication(*grid2d,l,Dune::dvverb);
218
for(int l=0; l<=grid3d->maxLevel(); ++l)
219
checkCommunication(*grid3d,l,Dune::dvverb);
221
// check geometry lifetime
222
checkGeometryLifetime( grid2d->leafView() );
223
checkGeometryLifetime( grid3d->leafView() );
225
// check the method geometryInFather()
226
checkGeometryInFather(*grid2d);
227
checkGeometryInFather(*grid3d);
229
// check the intersection iterator
230
checkIntersectionIterator(*grid2d);
231
checkIntersectionIterator(*grid3d);
233
235
int main (int argc , char **argv) try
235
// use MPI helper to initialize MPI
236
MPIHelper :: instance( argc, argv );
238
// ////////////////////////////////////////////////////////////////////////
239
// Do the standard grid test for a 2d and a 3d UGGrid
240
// ////////////////////////////////////////////////////////////////////////
242
// Do the general tests for red/green refinement
243
std::cout << "Testing UGGrid<2> and UGGrid<3> with red/green refinement" << std::endl;
246
// Do the general tests for nonconforming refinement
247
std::cout << "Testing UGGrid<2> and UGGrid<3> with nonconforming refinement" << std::endl;
250
// ////////////////////////////////////////////////////////////////////////////
251
// Test whether I can create a grid with explict boundary segment ordering,
252
// but not parametrization functions (only 2d, so far)
253
// ////////////////////////////////////////////////////////////////////////////
255
Dune::UGGrid<2> gridWithOrderedBoundarySegments;
256
makeHalfCircleQuad(gridWithOrderedBoundarySegments, true, false);
258
gridWithOrderedBoundarySegments.globalRefine(1);
259
gridcheck(gridWithOrderedBoundarySegments);
261
// ////////////////////////////////////////////////////////////////////////
262
// Check whether geometryInFather returns equal results with and
263
// without parametrized boundaries
264
// ////////////////////////////////////////////////////////////////////////
266
Dune::UGGrid<2> gridWithParametrization, gridWithoutParametrization;
237
// use MPI helper to initialize MPI
238
MPIHelper :: instance( argc, argv );
240
// ////////////////////////////////////////////////////////////////////////
241
// Do the standard grid test for a 2d and a 3d UGGrid
242
// ////////////////////////////////////////////////////////////////////////
244
// Do the general tests for red/green refinement
245
std::cout << "Testing UGGrid<2> and UGGrid<3> with red/green refinement" << std::endl;
248
// Do the general tests for nonconforming refinement
249
std::cout << "Testing UGGrid<2> and UGGrid<3> with nonconforming refinement" << std::endl;
252
// ////////////////////////////////////////////////////////////////////////////
253
// Test whether I can create a grid with explict boundary segment ordering,
254
// but not parametrization functions (only 2d, so far)
255
// ////////////////////////////////////////////////////////////////////////////
257
{ // Force destruction of test grid right after the next test,
258
// because for parallel UG there can be only one (2d-)grid at once.
260
Dune::UGGrid<2> gridWithOrderedBoundarySegments;
261
makeHalfCircleQuad(gridWithOrderedBoundarySegments, true, false);
263
gridWithOrderedBoundarySegments.globalRefine(1);
264
gridcheck(gridWithOrderedBoundarySegments);
268
// ////////////////////////////////////////////////////////////////////////
269
// Check whether geometryInFather returns equal results with and
270
// without parametrized boundaries
271
// ////////////////////////////////////////////////////////////////////////
273
// Only the sequential UG can provide more than one 2d- or 3d-grid at once.
274
// Therefore we do not perform the following test for parallel UGGrid.
276
Dune::UGGrid<2> gridWithParametrization, gridWithoutParametrization;
279
makeHalfCircleQuad(gridWithoutParametrization, false, false);
280
makeHalfCircleQuad(gridWithParametrization, true, true);
282
// make grids again just to check this is possible
283
makeHalfCircleQuad(gridWithoutParametrization, false, false);
284
makeHalfCircleQuad(gridWithParametrization, true, true);
286
gridWithParametrization.globalRefine(1);
287
gridWithoutParametrization.globalRefine(1);
289
typedef Dune::UGGrid<2>::Codim<0>::LevelIterator ElementIterator;
290
ElementIterator eIt = gridWithParametrization.lbegin<0>(1);
291
ElementIterator eWoIt = gridWithoutParametrization.lbegin<0>(1);
292
ElementIterator eEndIt = gridWithParametrization.lend<0>(1);
294
for (; eIt!=eEndIt; ++eIt, ++eWoIt) {
296
// The grids where constructed identically and they are traversed identically
297
// Thus their respective output from geometryInFather should be the same
298
for (int i=0; i<eIt->geometry().corners(); i++) {
300
Dune::FieldVector<double,2> diff = eIt->geometryInFather().corner(i) - eWoIt->geometryInFather().corner(i);
302
if ( diff.two_norm() > 1e-5 )
303
DUNE_THROW(Dune::GridError, "output of geometryInFather() depends on boundary parametrization!");
309
// ////////////////////////////////////////////////////////////////////////
310
// Check whether copies of elements have the same global ID
311
// ////////////////////////////////////////////////////////////////////////
314
std::cout << "Testing if copies of elements have the same id." << std::endl;
315
Dune::UGGrid<2> locallyRefinedGrid;
317
locallyRefinedGrid.setRefinementType(Dune::UGGrid<2>::COPY);
319
typedef Dune::UGGrid<2>::Codim<0>::LevelIterator ElementIterator;
320
typedef Dune::UGGrid<2>::HierarchicIterator HierarchicIterator;
321
typedef Dune::UGGrid<2>::Traits::GlobalIdSet GlobalIdSet;
322
typedef Dune::UGGrid<2>::Traits::LocalIdSet LocalIdSet;
269
makeHalfCircleQuad(gridWithoutParametrization, false, false);
270
makeHalfCircleQuad(gridWithParametrization, true, true);
272
// make grids again just to check this is possible
273
makeHalfCircleQuad(gridWithoutParametrization, false, false);
274
makeHalfCircleQuad(gridWithParametrization, true, true);
276
gridWithParametrization.globalRefine(1);
277
gridWithoutParametrization.globalRefine(1);
279
typedef Dune::UGGrid<2>::Codim<0>::LevelIterator ElementIterator;
280
ElementIterator eIt = gridWithParametrization.lbegin<0>(1);
281
ElementIterator eWoIt = gridWithoutParametrization.lbegin<0>(1);
282
ElementIterator eEndIt = gridWithParametrization.lend<0>(1);
284
for (; eIt!=eEndIt; ++eIt, ++eWoIt) {
286
// The grids where constructed identically and they are traversed identically
287
// Thus their respective output from geometryInFather should be the same
288
for (int i=0; i<eIt->geometry().corners(); i++) {
290
Dune::FieldVector<double,2> diff = eIt->geometryInFather().corner(i) - eWoIt->geometryInFather().corner(i);
292
if ( diff.two_norm() > 1e-5 )
293
DUNE_THROW(Dune::GridError, "output of geometryInFather() depends on boundary parametrization!");
299
// ////////////////////////////////////////////////////////////////////////
300
// Check whether copies of elements have the same global ID
301
// ////////////////////////////////////////////////////////////////////////
325
makeHalfCircleQuad(locallyRefinedGrid, false, false);
327
markOne(locallyRefinedGrid,0,1);
328
markOne(locallyRefinedGrid,0,1);
330
const GlobalIdSet& globalIdSet = locallyRefinedGrid.globalIdSet();
331
const LocalIdSet& localIdSet = locallyRefinedGrid.localIdSet();
333
for (int level=0; level<locallyRefinedGrid.maxLevel(); ++level)
304
std::cout << "Testing if copies of elements have the same id." << std::endl;
305
Dune::UGGrid<2> locallyRefinedGrid;
307
locallyRefinedGrid.setRefinementType(Dune::UGGrid<2>::COPY);
309
typedef Dune::UGGrid<2>::Codim<0>::LevelIterator ElementIterator;
310
typedef Dune::UGGrid<2>::HierarchicIterator HierarchicIterator;
311
typedef Dune::UGGrid<2>::Traits::GlobalIdSet GlobalIdSet;
312
typedef Dune::UGGrid<2>::Traits::LocalIdSet LocalIdSet;
315
makeHalfCircleQuad(locallyRefinedGrid, false, false);
317
markOne(locallyRefinedGrid,0,1);
318
markOne(locallyRefinedGrid,0,1);
320
const GlobalIdSet& globalIdSet = locallyRefinedGrid.globalIdSet();
321
const LocalIdSet& localIdSet = locallyRefinedGrid.localIdSet();
323
for (int level=0; level<locallyRefinedGrid.maxLevel(); ++level)
335
ElementIterator eIt = locallyRefinedGrid.lbegin<0>(level);
336
ElementIterator eEnd = locallyRefinedGrid.lend<0>(level);
337
for(; eIt!=eEnd; ++eIt)
340
GlobalIdSet::IdType globalChildId;
341
LocalIdSet::IdType localChildId;
343
HierarchicIterator hIt = eIt->hbegin(level+1);
344
HierarchicIterator hEnd = eIt->hend(level+1);
347
for( ; hIt!=hEnd; ++hIt)
325
ElementIterator eIt = locallyRefinedGrid.lbegin<0>(level);
326
ElementIterator eEnd = locallyRefinedGrid.lend<0>(level);
327
for(; eIt!=eEnd; ++eIt)
330
GlobalIdSet::IdType globalChildId;
331
LocalIdSet::IdType localChildId;
333
HierarchicIterator hIt = eIt->hbegin(level+1);
334
HierarchicIterator hEnd = eIt->hend(level+1);
337
for( ;hIt!=hEnd; ++hIt)
339
globalChildId = globalIdSet.id<0>(*hIt);
340
localChildId = localIdSet.id<0>(*hIt);
346
if (globalIdSet.id<0>(*eIt) != globalChildId)
347
DUNE_THROW(Dune::GridError, "Copy of element has different globalId!");
349
if (localIdSet.id<0>(*eIt) != localChildId)
350
DUNE_THROW(Dune::GridError, "Copy of element has different localId!");
349
globalChildId = globalIdSet.id<0>(*hIt);
350
localChildId = localIdSet.id<0>(*hIt);
356
if (globalIdSet.id<0>(*eIt) != globalChildId)
357
DUNE_THROW(Dune::GridError, "Copy of element has different globalId!");
359
if (localIdSet.id<0>(*eIt) != localChildId)
360
DUNE_THROW(Dune::GridError, "Copy of element has different localId!");
356
} catch (Dune::Exception& e) {
357
std::cerr << e << std::endl;
360
std::cerr << "Generic exception!" << std::endl;
367
catch (Dune::Exception& e) {
368
std::cerr << e << std::endl;
371
std::cerr << "Generic exception!" << std::endl;