grid_dist_id_unit_test.cpp 45.8 KB
Newer Older
Pietro Incardona's avatar
Pietro Incardona committed
1
2
3
#ifndef GRID_DIST_UNIT_TEST_HPP
#define GRID_DIST_UNIT_TEST_HPP

Pietro Incardona's avatar
Pietro Incardona committed
4
5
6
7
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>

#include "Point_test.hpp"
Pietro Incardona's avatar
Pietro Incardona committed
8
9
#include "grid_dist_id.hpp"
#include "data_type/scalar.hpp"
10
#include "data_type/aggregate.hpp"
Pietro Incardona's avatar
Pietro Incardona committed
11

Pietro Incardona's avatar
Pietro Incardona committed
12

Pietro Incardona's avatar
Pietro Incardona committed
13
14
BOOST_AUTO_TEST_SUITE( grid_dist_id_test )

Pietro Incardona's avatar
Pietro Incardona committed
15
void print_test(std::string test, size_t sz)
Pietro Incardona's avatar
Pietro Incardona committed
16
{
17
	if (create_vcluster().getProcessUnitID() == 0)
Pietro Incardona's avatar
Pietro Incardona committed
18
		std::cout << test << " " << sz << "\n";
Pietro Incardona's avatar
Pietro Incardona committed
19
20
}

Pietro Incardona's avatar
Pietro Incardona committed
21
BOOST_AUTO_TEST_CASE( grid_dist_id_domain_grid_unit_converter3D_test)
Pietro Incardona's avatar
Pietro Incardona committed
22
{
23
24
	size_t bc[3] = {NON_PERIODIC, NON_PERIODIC, NON_PERIODIC};

25
	// Domain
Pietro Incardona's avatar
Pietro Incardona committed
26
	Box<3,float> domain({-0.3,-0.3,-0.3},{1.0,1.0,1.0});
27

28
	Vcluster & v_cl = create_vcluster();
Pietro Incardona's avatar
Pietro Incardona committed
29

Pietro Incardona's avatar
Pietro Incardona committed
30
31
32
33
	// Skip this test on big scale
	if (v_cl.getProcessingUnits() >= 32)
		return;

Pietro Incardona's avatar
Pietro Incardona committed
34
	// Test several grid dimensions
Pietro Incardona's avatar
Pietro Incardona committed
35

Pietro Incardona's avatar
Pietro Incardona committed
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
	long int k = 293;
	long int big_step = k / 30;
	big_step = (big_step == 0)?1:big_step;
	long int small_step = 21;

	print_test( "Testing 3D grid converter k<=",k);

	// 3D test
	for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
	{
		BOOST_TEST_CHECKPOINT( "Testing 3D grid converter k=" << k );

		// grid size
		size_t sz[3];
		sz[0] = k;
		sz[1] = k;
		sz[2] = k;

		// Ghost
		Ghost<3,float> g(0.01);

		// Distributed grid with id decomposition
		grid_dist_id<3, float, scalar<float>, CartDecomposition<3,float>> g_dist(sz,domain,g);

		// get the decomposition
		auto & dec = g_dist.getDecomposition();

		// check the consistency of the decomposition
		bool val = dec.check_consistency();
		BOOST_REQUIRE_EQUAL(val,true);

		// for each local volume
		// Get the number of local grid needed
		size_t n_grid = dec.getNSubDomain();

		size_t vol = 0;

		// vector of boxes
		openfpm::vector<Box<3,size_t>> vb;

		// Allocate the grids
		for (size_t i = 0 ; i < n_grid ; i++)
		{
			// Get the local hyper-cube
			SpaceBox<3,float> sub = dec.getSubDomain(i);
81
//			sub -= domain.getP1();
Pietro Incardona's avatar
Pietro Incardona committed
82

83
			Box<3,size_t> g_box = g_dist.getCellDecomposer().convertDomainSpaceIntoGridUnits(sub,bc);
Pietro Incardona's avatar
Pietro Incardona committed
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

			vb.add(g_box);

			vol += g_box.getVolumeKey();
		}

		// Create a writer and write
		VTKWriter<openfpm::vector<Box<3,size_t>>,VECTOR_BOX> vtk_box2;
		vtk_box2.add(vb);
		vtk_box2.write(std::to_string(v_cl.getProcessUnitID()) + "vtk_box_3D.vtk");

		v_cl.sum(vol);
		v_cl.execute();

		BOOST_REQUIRE_EQUAL(vol,sz[0]*sz[1]*sz[2]);
	}
}


BOOST_AUTO_TEST_CASE( grid_dist_id_domain_grid_unit_converter_test)
{
105
106
	size_t bc[2] = {NON_PERIODIC, NON_PERIODIC};

Pietro Incardona's avatar
Pietro Incardona committed
107
108
109
	// Domain
	Box<2,float> domain({0.0,0.0},{1.0,1.0});

110
	Vcluster & v_cl = create_vcluster();
Pietro Incardona's avatar
Pietro Incardona committed
111
112
113
114
115

	// Skip this test on big scale
	if (v_cl.getProcessingUnits() >= 32)
		return;

Pietro Incardona's avatar
Pietro Incardona committed
116
	for (size_t k = 1024 ; k >= 2 ; k--)
Pietro Incardona's avatar
Pietro Incardona committed
117
	{
Pietro Incardona's avatar
Pietro Incardona committed
118
		BOOST_TEST_CHECKPOINT( "Testing grid converter 3D k=" << k );
Pietro Incardona's avatar
Pietro Incardona committed
119

Pietro Incardona's avatar
Pietro Incardona committed
120
121
122
123
		// grid size
		size_t sz[2];
		sz[0] = k;
		sz[1] = k;
Pietro Incardona's avatar
Pietro Incardona committed
124

Pietro Incardona's avatar
Pietro Incardona committed
125
126
		// Ghost
		Ghost<2,float> g(0.01);
Pietro Incardona's avatar
Pietro Incardona committed
127

Pietro Incardona's avatar
Pietro Incardona committed
128
129
		// Distributed grid with id decomposition
		grid_dist_id<2, float, scalar<float>, CartDecomposition<2,float>> g_dist(sz,domain,g);
Pietro Incardona's avatar
Pietro Incardona committed
130

Pietro Incardona's avatar
Pietro Incardona committed
131
132
		// get the decomposition
		auto & dec = g_dist.getDecomposition();
Pietro Incardona's avatar
Pietro Incardona committed
133

Pietro Incardona's avatar
Pietro Incardona committed
134
135
136
137
		// check the consistency of the decomposition
		bool val = dec.check_consistency();
		BOOST_REQUIRE_EQUAL(val,true);

Pietro Incardona's avatar
Pietro Incardona committed
138
139
		// for each local volume
		// Get the number of local grid needed
Pietro Incardona's avatar
Pietro Incardona committed
140
		size_t n_grid = dec.getNSubDomain();
Pietro Incardona's avatar
Pietro Incardona committed
141

Pietro Incardona's avatar
Pietro Incardona committed
142
143
144
145
146
147
		size_t vol = 0;

		// Allocate the grids
		for (size_t i = 0 ; i < n_grid ; i++)
		{
			// Get the local hyper-cube
Pietro Incardona's avatar
Pietro Incardona committed
148
			SpaceBox<2,float> sub = dec.getSubDomain(i);
Pietro Incardona's avatar
Pietro Incardona committed
149

150
			Box<2,size_t> g_box = g_dist.getCellDecomposer().convertDomainSpaceIntoGridUnits(sub,bc);
Pietro Incardona's avatar
Pietro Incardona committed
151

Pietro Incardona's avatar
Pietro Incardona committed
152
153
			vol += g_box.getVolumeKey();
		}
Pietro Incardona's avatar
Pietro Incardona committed
154

155
		v_cl.sum(vol);
Pietro Incardona's avatar
Pietro Incardona committed
156
157
158
159
160
161
		v_cl.execute();

		BOOST_REQUIRE_EQUAL(vol,sz[0]*sz[1]);
	}
}

Pietro Incardona's avatar
Pietro Incardona committed
162
163
164
165
void Test2D_sub(const Box<2,float> & domain, long int k)
{
	long int big_step = k / 30;
	big_step = (big_step == 0)?1:big_step;
Pietro Incardona's avatar
Pietro Incardona committed
166
	long int small_step = 21;
Pietro Incardona's avatar
Pietro Incardona committed
167
168

	// this test is only performed when the number of processor is <= 32
169
	if (create_vcluster().getProcessingUnits() > 32)
Pietro Incardona's avatar
Pietro Incardona committed
170
171
172
173
174
175
176
177
178
179
180
181
182
183
		return;

	print_test( "Testing 2D grid sub iterator k<=",k);

	// 2D test
	for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
	{
		BOOST_TEST_CHECKPOINT( "Testing 2D grid k=" << k );

		// grid size
		size_t sz[2];
		sz[0] = k;
		sz[1] = k;

184
		float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/2.0f);
Pietro Incardona's avatar
Pietro Incardona committed
185
186
187
188
189

		// Ghost
		Ghost<2,float> g(0.01 / factor);

		// Distributed grid with id decomposition
190
		grid_dist_id<2, float, scalar<float>> g_dist(sz,domain,g);
Pietro Incardona's avatar
Pietro Incardona committed
191
192
193
194
195

		// check the consistency of the decomposition
		bool val = g_dist.getDecomposition().check_consistency();
		BOOST_REQUIRE_EQUAL(val,true);

Pietro Incardona's avatar
Pietro Incardona committed
196
197
		size_t count;

Pietro Incardona's avatar
Pietro Incardona committed
198
199
200
		// Grid sm
		grid_sm<2,void> info(sz);

Pietro Incardona's avatar
Pietro Incardona committed
201
		{
Pietro Incardona's avatar
Pietro Incardona committed
202
203
204
205
206
207
		//! [Usage of a sub_grid iterator]

		grid_key_dx<2> one(1,1);
		grid_key_dx<2> one_end(k-2,k-2);

		bool check = true;
Pietro Incardona's avatar
Pietro Incardona committed
208
209
210
		count = 0;

		// get the sub-domain iterator
Pietro Incardona's avatar
Pietro Incardona committed
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
		auto dom = g_dist.getSubDomainIterator(one,one_end);

		while (dom.isNext())
		{
			auto key = dom.get();
			auto key_g = g_dist.getGKey(key);

			// key_g should never be 1 or k-1
			check &= (key_g.get(0) == 0 || key_g.get(0) == k-1)?false:true;
			check &= (key_g.get(1) == 0 || key_g.get(1) == k-1)?false:true;

			g_dist.template get<0>(key) = info.LinId(key_g);

			// Count the point
			count++;

			++dom;
		}

		BOOST_REQUIRE_EQUAL(check,true);

		//! [Usage of a sub_grid iterator]

Pietro Incardona's avatar
Pietro Incardona committed
234
235
		}

Pietro Incardona's avatar
Pietro Incardona committed
236
237
238
239
240
241
242
243
		// Get the virtual cluster machine
		Vcluster & vcl = g_dist.getVC();

		// reduce
		vcl.sum(count);
		vcl.execute();

		// Check
Pietro Incardona's avatar
Pietro Incardona committed
244
		BOOST_REQUIRE_EQUAL(count,(size_t)(k-2)*(k-2));
Pietro Incardona's avatar
Pietro Incardona committed
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266

		// check with a 1x1 square

		{

		grid_key_dx<2> one(k/2,k/2);
		grid_key_dx<2> one_end(k/2,k/2);

		count = 0;

		// get the sub-domain iterator
		auto dom = g_dist.getSubDomainIterator(one,one_end);

		while (dom.isNext())
		{
			auto key = dom.get();
			auto key_g = g_dist.getGKey(key);

			// key_g
			BOOST_REQUIRE_EQUAL(key_g.get(0),k/2);
			BOOST_REQUIRE_EQUAL(key_g.get(1),k/2);

267
			auto key_s_it = dom.getGKey(key);
Pietro Incardona's avatar
Pietro Incardona committed
268
269
270
271
272
273
274
275
276
277
278
279
280
281

			BOOST_REQUIRE_EQUAL(key_g.get(0),key_s_it.get(0));
			BOOST_REQUIRE_EQUAL(key_g.get(1),key_s_it.get(1));

			// Count the point
			count++;

			++dom;
		}

		// reduce
		vcl.sum(count);
		vcl.execute();

Pietro Incardona's avatar
Pietro Incardona committed
282
		BOOST_REQUIRE_EQUAL(count,1ul);
Pietro Incardona's avatar
Pietro Incardona committed
283
		}
Pietro Incardona's avatar
Pietro Incardona committed
284
285
286
	}
}

Pietro Incardona's avatar
Pietro Incardona committed
287
void Test2D(const Box<2,float> & domain, long int k)
Pietro Incardona's avatar
Pietro Incardona committed
288
{
289
290
	long int big_step = k / 30;
	big_step = (big_step == 0)?1:big_step;
Pietro Incardona's avatar
Pietro Incardona committed
291
	long int small_step = 21;
292

293
294
	print_test( "Testing 2D grid k<=",k);

Pietro Incardona's avatar
Pietro Incardona committed
295
	// 2D test
296
	for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
Pietro Incardona's avatar
Pietro Incardona committed
297
298
	{
		BOOST_TEST_CHECKPOINT( "Testing 2D grid k=" << k );
299
300
301

		//! [Create and access a distributed grid]

Pietro Incardona's avatar
Pietro Incardona committed
302
303
304
305
		// grid size
		size_t sz[2];
		sz[0] = k;
		sz[1] = k;
Pietro Incardona's avatar
Pietro Incardona committed
306

307
		float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/2.0f);
Pietro Incardona's avatar
Pietro Incardona committed
308

Pietro Incardona's avatar
Pietro Incardona committed
309
		// Ghost
310
		Ghost<2,float> g(0.01 / factor);
Pietro Incardona's avatar
Pietro Incardona committed
311

Pietro Incardona's avatar
Pietro Incardona committed
312
		// Distributed grid with id decomposition
313
		grid_dist_id<2, float, scalar<float>> g_dist(sz,domain,g);
Pietro Incardona's avatar
Pietro Incardona committed
314

Pietro Incardona's avatar
Pietro Incardona committed
315
316
317
318
		// check the consistency of the decomposition
		bool val = g_dist.getDecomposition().check_consistency();
		BOOST_REQUIRE_EQUAL(val,true);

Pietro Incardona's avatar
Pietro Incardona committed
319
320
321
322
323
324
325
326
327
328
329
330
		// Grid sm
		grid_sm<2,void> info(sz);

		// get the domain iterator
		size_t count = 0;

		auto dom = g_dist.getDomainIterator();

		while (dom.isNext())
		{
			auto key = dom.get();
			auto key_g = g_dist.getGKey(key);
Pietro Incardona's avatar
Pietro Incardona committed
331

Pietro Incardona's avatar
Pietro Incardona committed
332
333
334
335
336
337
338
339
			g_dist.template get<0>(key) = info.LinId(key_g);

			// Count the point
			count++;

			++dom;
		}

340
341
		//! [Create and access a distributed grid]

Pietro Incardona's avatar
Pietro Incardona committed
342
343
344
345
		// Get the virtual cluster machine
		Vcluster & vcl = g_dist.getVC();

		// reduce
346
		vcl.sum(count);
Pietro Incardona's avatar
Pietro Incardona committed
347
348
349
		vcl.execute();

		// Check
Pietro Incardona's avatar
Pietro Incardona committed
350
		BOOST_REQUIRE_EQUAL(count,(size_t)k*k);
Pietro Incardona's avatar
Pietro Incardona committed
351
352
353

		auto dom2 = g_dist.getDomainIterator();

Pietro Incardona's avatar
Pietro Incardona committed
354
355
356
		grid_key_dx<2> start = dom2.getStart();
		grid_key_dx<2> stop = dom2.getStop();

Pietro Incardona's avatar
Pietro Incardona committed
357
358
		BOOST_REQUIRE_EQUAL((long int)stop.get(0),(long int)g_dist.size(0)-1);
		BOOST_REQUIRE_EQUAL((long int)stop.get(1),(long int)g_dist.size(1)-1);
Pietro Incardona's avatar
Pietro Incardona committed
359
360
361
362

		BOOST_REQUIRE_EQUAL(start.get(0),0);
		BOOST_REQUIRE_EQUAL(start.get(1),0);

Pietro Incardona's avatar
Pietro Incardona committed
363
364
		bool match = true;

Pietro Incardona's avatar
Pietro Incardona committed
365
366
367
368
369
370
		// check that the grid store the correct information
		while (dom2.isNext())
		{
			auto key = dom2.get();
			auto key_g = g_dist.getGKey(key);

Pietro Incardona's avatar
Pietro Incardona committed
371
			match &= (g_dist.template get<0>(key) == info.LinId(key_g))?true:false;
Pietro Incardona's avatar
Pietro Incardona committed
372
373
374
375

			++dom2;
		}

Pietro Incardona's avatar
Pietro Incardona committed
376
377
		BOOST_REQUIRE_EQUAL(match,true);

Pietro Incardona's avatar
Pietro Incardona committed
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
		g_dist.template ghost_get<0>();

		// check that the communication is correctly completed

		auto domg = g_dist.getDomainGhostIterator();

		// check that the grid with the ghost past store the correct information
		while (domg.isNext())
		{
			auto key = domg.get();
			auto key_g = g_dist.getGKey(key);

			// In this case the boundary condition are non periodic
			if (g_dist.isInside(key_g))
			{
Pietro Incardona's avatar
Pietro Incardona committed
393
				match &= (g_dist.template get<0>(key) == info.LinId(key_g))?true:false;
Pietro Incardona's avatar
Pietro Incardona committed
394
395
396
397
			}

			++domg;
		}
Pietro Incardona's avatar
Pietro Incardona committed
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517

		BOOST_REQUIRE_EQUAL(match,true);
	}
}


void Test1D(const Box<1,float> & domain, long int k)
{
	Vcluster & v_cl = create_vcluster();
	long int big_step = k / 30;
	big_step = (big_step == 0)?1:big_step;
	long int small_step = 21;

	if (v_cl.getProcessingUnits() > 48)
		return;

	print_test( "Testing 1D grid k<=",k);

	// 1D test
	for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
	{
		BOOST_TEST_CHECKPOINT( "Testing 1D grid k=" << k );

		//! [Create and access a distributed grid]

		// grid size
		size_t sz[1];
		sz[0] = k;

		float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f);

		// Ghost
		Ghost<1,float> g(0.01 / factor);

		// Distributed grid with id decomposition
		grid_dist_id<1, float, scalar<float>> g_dist(sz,domain,g);

		// check the consistency of the decomposition
		bool val = g_dist.getDecomposition().check_consistency();
		BOOST_REQUIRE_EQUAL(val,true);

		// Grid sm
		grid_sm<1,void> info(sz);

		// get the domain iterator
		size_t count = 0;

		auto dom = g_dist.getDomainIterator();

		while (dom.isNext())
		{
			auto key = dom.get();
			auto key_g = g_dist.getGKey(key);

			g_dist.template get<0>(key) = info.LinId(key_g);

			// Count the point
			count++;

			++dom;
		}

		//! [Create and access a distributed grid]

		// Get the virtual cluster machine
		Vcluster & vcl = g_dist.getVC();

		// reduce
		vcl.sum(count);
		vcl.execute();

		// Check
		BOOST_REQUIRE_EQUAL(count,(size_t)k);

		auto dom2 = g_dist.getDomainIterator();

		grid_key_dx<1> start = dom2.getStart();
		grid_key_dx<1> stop = dom2.getStop();

		BOOST_REQUIRE_EQUAL((long int)stop.get(0),(long int)g_dist.size(0)-1);

		BOOST_REQUIRE_EQUAL(start.get(0),0);

		bool match = true;

		// check that the grid store the correct information
		while (dom2.isNext())
		{
			auto key = dom2.get();
			auto key_g = g_dist.getGKey(key);

			match &= (g_dist.template get<0>(key) == info.LinId(key_g))?true:false;

			++dom2;
		}

		BOOST_REQUIRE_EQUAL(match,true);

		g_dist.template ghost_get<0>();

		// check that the communication is correctly completed

		auto domg = g_dist.getDomainGhostIterator();

		// check that the grid with the ghost past store the correct information
		while (domg.isNext())
		{
			auto key = domg.get();
			auto key_g = g_dist.getGKey(key);

			// In this case the boundary condition are non periodic
			if (g_dist.isInside(key_g))
			{
				match &= (g_dist.template get<0>(key) == info.LinId(key_g))?true:false;
			}

			++domg;
		}

		BOOST_REQUIRE_EQUAL(match,true);
Pietro Incardona's avatar
Pietro Incardona committed
518
519
520
	}
}

Pietro Incardona's avatar
Pietro Incardona committed
521
522
523
524
void Test3D_sub(const Box<3,float> & domain, long int k)
{
	long int big_step = k / 30;
	big_step = (big_step == 0)?1:big_step;
Pietro Incardona's avatar
Pietro Incardona committed
525
	long int small_step = 21;
Pietro Incardona's avatar
Pietro Incardona committed
526
527

	// this test is only performed when the number of processor is <= 32
528
	if (create_vcluster().getProcessingUnits() > 32)
Pietro Incardona's avatar
Pietro Incardona committed
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
		return;

	print_test( "Testing 3D grid sub k<=",k);

	// 3D test
	for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
	{
		BOOST_TEST_CHECKPOINT( "Testing 3D grid sub k=" << k );

		// grid size
		size_t sz[3];
		sz[0] = k;
		sz[1] = k;
		sz[2] = k;

		// factor
545
		float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
Pietro Incardona's avatar
Pietro Incardona committed
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562

		// Ghost
		Ghost<3,float> g(0.01 / factor);

		// Distributed grid with id decomposition
		grid_dist_id<3, float, scalar<float>, CartDecomposition<3,float>> g_dist(sz,domain,g);

		// check the consistency of the decomposition
		bool val = g_dist.getDecomposition().check_consistency();
		BOOST_REQUIRE_EQUAL(val,true);

		// Grid sm
		grid_sm<3,void> info(sz);

		// get the domain iterator
		size_t count = 0;

Pietro Incardona's avatar
Pietro Incardona committed
563
564
565
566
567
		grid_key_dx<3> one(1,1,1);
		grid_key_dx<3> one_end(k-2,k-2,k-2);

		// Sub-domain iterator
		auto dom = g_dist.getSubDomainIterator(one,one_end);
Pietro Incardona's avatar
Pietro Incardona committed
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589

		while (dom.isNext())
		{
			auto key = dom.get();
			auto key_g = g_dist.getGKey(key);

			g_dist.template get<0>(key) = info.LinId(key_g);

			// Count the point
			count++;

			++dom;
		}

		// Get the virtual cluster machine
		Vcluster & vcl = g_dist.getVC();

		// reduce
		vcl.sum(count);
		vcl.execute();

		// Check
Pietro Incardona's avatar
Pietro Incardona committed
590
		BOOST_REQUIRE_EQUAL(count,(size_t)(k-2)*(k-2)*(k-2));
Pietro Incardona's avatar
Pietro Incardona committed
591

Pietro Incardona's avatar
Pietro Incardona committed
592
		// check with a 1x1x1 square
Pietro Incardona's avatar
Pietro Incardona committed
593
594
		{

Pietro Incardona's avatar
Pietro Incardona committed
595
596
		grid_key_dx<3> one(k/2,k/2,k/2);
		grid_key_dx<3> one_end(k/2,k/2,k/2);
Pietro Incardona's avatar
Pietro Incardona committed
597

Pietro Incardona's avatar
Pietro Incardona committed
598
		count = 0;
Pietro Incardona's avatar
Pietro Incardona committed
599

Pietro Incardona's avatar
Pietro Incardona committed
600
601
		// get the sub-domain iterator
		auto dom = g_dist.getSubDomainIterator(one,one_end);
Pietro Incardona's avatar
Pietro Incardona committed
602

Pietro Incardona's avatar
Pietro Incardona committed
603
604
605
606
		while (dom.isNext())
		{
			auto key = dom.get();
			auto key_g = g_dist.getGKey(key);
Pietro Incardona's avatar
Pietro Incardona committed
607

Pietro Incardona's avatar
Pietro Incardona committed
608
609
610
611
			// key_g
			BOOST_REQUIRE_EQUAL(key_g.get(0),k/2);
			BOOST_REQUIRE_EQUAL(key_g.get(1),k/2);
			BOOST_REQUIRE_EQUAL(key_g.get(2),k/2);
Pietro Incardona's avatar
Pietro Incardona committed
612

Pietro Incardona's avatar
Pietro Incardona committed
613
			auto key_s_it = dom.getGKey(key);
Pietro Incardona's avatar
Pietro Incardona committed
614

Pietro Incardona's avatar
Pietro Incardona committed
615
616
617
			BOOST_REQUIRE_EQUAL(key_g.get(0),key_s_it.get(0));
			BOOST_REQUIRE_EQUAL(key_g.get(1),key_s_it.get(1));
			BOOST_REQUIRE_EQUAL(key_g.get(2),key_s_it.get(2));
Pietro Incardona's avatar
Pietro Incardona committed
618

Pietro Incardona's avatar
Pietro Incardona committed
619
620
			// Count the point
			count++;
Pietro Incardona's avatar
Pietro Incardona committed
621

Pietro Incardona's avatar
Pietro Incardona committed
622
			++dom;
Pietro Incardona's avatar
Pietro Incardona committed
623
624
		}

Pietro Incardona's avatar
Pietro Incardona committed
625
626
627
		// reduce
		vcl.sum(count);
		vcl.execute();
Pietro Incardona's avatar
Pietro Incardona committed
628

Pietro Incardona's avatar
Pietro Incardona committed
629
		BOOST_REQUIRE_EQUAL(count,1ul);
Pietro Incardona's avatar
Pietro Incardona committed
630
		}
Pietro Incardona's avatar
Pietro Incardona committed
631
632
633
	}
}

Pietro Incardona's avatar
Pietro Incardona committed
634
635
void Test3D(const Box<3,float> & domain, long int k)
{
636
637
	long int big_step = k / 30;
	big_step = (big_step == 0)?1:big_step;
Pietro Incardona's avatar
Pietro Incardona committed
638
	long int small_step = 21;
639

640
641
	print_test( "Testing 3D grid k<=",k);

Pietro Incardona's avatar
Pietro Incardona committed
642
	// 3D test
643
	for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
Pietro Incardona's avatar
Pietro Incardona committed
644
645
646
647
648
649
650
651
652
	{
		BOOST_TEST_CHECKPOINT( "Testing 3D grid k=" << k );

		// grid size
		size_t sz[3];
		sz[0] = k;
		sz[1] = k;
		sz[2] = k;

Pietro Incardona's avatar
Pietro Incardona committed
653
		// factor
654
		float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
Pietro Incardona's avatar
Pietro Incardona committed
655

Pietro Incardona's avatar
Pietro Incardona committed
656
		// Ghost
Pietro Incardona's avatar
Pietro Incardona committed
657
		Ghost<3,float> g(0.01 / factor);
Pietro Incardona's avatar
Pietro Incardona committed
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690

		// Distributed grid with id decomposition
		grid_dist_id<3, float, scalar<float>, CartDecomposition<3,float>> g_dist(sz,domain,g);

		// check the consistency of the decomposition
		bool val = g_dist.getDecomposition().check_consistency();
		BOOST_REQUIRE_EQUAL(val,true);

		// Grid sm
		grid_sm<3,void> info(sz);

		// get the domain iterator
		size_t count = 0;

		auto dom = g_dist.getDomainIterator();

		while (dom.isNext())
		{
			auto key = dom.get();
			auto key_g = g_dist.getGKey(key);

			g_dist.template get<0>(key) = info.LinId(key_g);

			// Count the point
			count++;

			++dom;
		}

		// Get the virtual cluster machine
		Vcluster & vcl = g_dist.getVC();

		// reduce
691
		vcl.sum(count);
Pietro Incardona's avatar
Pietro Incardona committed
692
693
694
		vcl.execute();

		// Check
Pietro Incardona's avatar
Pietro Incardona committed
695
		BOOST_REQUIRE_EQUAL(count,(size_t)k*k*k);
Pietro Incardona's avatar
Pietro Incardona committed
696

Pietro Incardona's avatar
Pietro Incardona committed
697
698
		bool match = true;

Pietro Incardona's avatar
Pietro Incardona committed
699
700
701
702
703
704
705
706
		auto dom2 = g_dist.getDomainIterator();

		// check that the grid store the correct information
		while (dom2.isNext())
		{
			auto key = dom2.get();
			auto key_g = g_dist.getGKey(key);

Pietro Incardona's avatar
Pietro Incardona committed
707
			match &= (g_dist.template get<0>(key) == info.LinId(key_g))?true:false;
Pietro Incardona's avatar
Pietro Incardona committed
708
709
710
711

			++dom2;
		}

Pietro Incardona's avatar
Pietro Incardona committed
712
713
		BOOST_REQUIRE_EQUAL(match,true);

714
715
		//! [Synchronize the ghost and check the information]

Pietro Incardona's avatar
Pietro Incardona committed
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
		g_dist.template ghost_get<0>();

		// check that the communication is correctly completed

		auto domg = g_dist.getDomainGhostIterator();

		// check that the grid with the ghost past store the correct information
		while (domg.isNext())
		{
			auto key = domg.get();
			auto key_g = g_dist.getGKey(key);

			// In this case the boundary condition are non periodic
			if (g_dist.isInside(key_g))
			{
Pietro Incardona's avatar
Pietro Incardona committed
731
				match &= (g_dist.template get<0>(key) == info.LinId(key_g))?true:false;
Pietro Incardona's avatar
Pietro Incardona committed
732
733
734
735
			}

			++domg;
		}
Pietro Incardona's avatar
Pietro Incardona committed
736
737

		BOOST_REQUIRE_EQUAL(match,true);
738
739

		//! [Synchronize the ghost and check the information]
Pietro Incardona's avatar
Pietro Incardona committed
740
	}
Pietro Incardona's avatar
Pietro Incardona committed
741
742
}

743
744
745
746
747
748

void Test3D_gg(const Box<3,float> & domain, long int k, long int gk)
{
	long int big_step = k / 30;
	big_step = (big_step == 0)?1:big_step;

749
	// this test is only performed when the number of processor is <= 32
750
	if (create_vcluster().getProcessingUnits() > 32)
751
752
		return;

753
754
755
	print_test( "Testing 3D grid k<=",k);

	// 3D test
756
	for ( ; k > 64 ; k /= 2 )
757
758
759
760
761
762
763
764
765
766
	{
		BOOST_TEST_CHECKPOINT( "Testing 3D grid ghost integer k=" << k );

		// grid size
		size_t sz[3];
		sz[0] = k;
		sz[1] = k;
		sz[2] = k;

		// Ghost
767
		Ghost<3,long int> g(gk);
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783

		// Distributed grid with id decomposition
		grid_dist_id<3, float, scalar<float>, CartDecomposition<3,float>> g_dist(sz,domain,g);

		// check the consistency of the decomposition
		bool val = g_dist.getDecomposition().check_consistency();
		BOOST_REQUIRE_EQUAL(val,true);

		auto lg = g_dist.getLocalGridsInfo();

		// for each local grid check that the border is 1 point
		// (Warning this property can only be ensured with k is a multiple of 2)
		// in the other case it will be mostly like that but cannot be ensured

		for (size_t i = 0 ; i < lg.size() ; i++)
		{
Pietro Incardona's avatar
Pietro Incardona committed
784
785
786
787
788
			for (size_t j = 0 ; j < 3 ; j++)
			{
				BOOST_REQUIRE(lg.get(i).Dbox.getLow(j) >= gk);
				BOOST_REQUIRE((lg.get(i).GDbox.getHigh(j) - lg.get(i).Dbox.getHigh(j)) >= gk);
			}
789
790
791
792
		}
	}
}

793
794
795
796
797
/*! \brief Test when the domain is not from 0.0 to 1.0
 *
 *
 */

Pietro Incardona's avatar
Pietro Incardona committed
798
void Test3D_domain(const Box<3,float> & domain, long int k, const periodicity<3> & pr)
799
800
801
802
803
{
	long int big_step = k / 30;
	big_step = (big_step == 0)?1:big_step;
	long int small_step = 21;

Pietro Incardona's avatar
Pietro Incardona committed
804
	print_test( "Testing 3D grid shift domain k<=",k);
805
806
807
808

	// 3D test
	for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
	{
Pietro Incardona's avatar
Pietro Incardona committed
809
		BOOST_TEST_CHECKPOINT( "Testing 3D grid shift domain k=" << k );
810
811
812
813
814
815
816
817

		// grid size
		size_t sz[3];
		sz[0] = k;
		sz[1] = k;
		sz[2] = k;

		// factor
818
		float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
819
820
821
822
823

		// Ghost
		Ghost<3,float> g(0.01 / factor);

		// Distributed grid with id decomposition
Pietro Incardona's avatar
Pietro Incardona committed
824
825
826
		grid_dist_id<3, float, aggregate<long int,long int>, CartDecomposition<3,float>> g_dist(sz,domain,g,pr);

		auto & v_cl = create_vcluster();
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900

		// check the consistency of the decomposition
		bool val = g_dist.getDecomposition().check_consistency();
		BOOST_REQUIRE_EQUAL(val,true);

		// Grid sm
		grid_sm<3,void> info(sz);

		// get the domain iterator
		size_t count = 0;

		auto dom = g_dist.getDomainIterator();

		while (dom.isNext())
		{
			auto key = dom.get();
			auto key_g = g_dist.getGKey(key);

			g_dist.template get<0>(key) = count;
			g_dist.template get<1>(key) = info.LinId(key_g);

			// Count the point
			count++;

			++dom;
		}

		size_t count2 = count;
		openfpm::vector<size_t> pnt;

		// Get the total size of the local grids on each processors
		// and the total size
		v_cl.sum(count2);
		v_cl.allGather(count,pnt);
		v_cl.execute();
		size_t s_pnt = 0;

		// calculate the starting point for this processor
		for (size_t i = 0 ; i < v_cl.getProcessUnitID() ; i++)
			s_pnt += pnt.get(i);

		// Check
		BOOST_REQUIRE_EQUAL(count2,(size_t)k*k*k);

		// sync the ghost
		g_dist.template ghost_get<0,1>();

		bool match = true;

		// check that the communication is correctly completed

		auto domg = g_dist.getDomainGhostIterator();

		// check that the grid with the ghost past store the correct information
		while (domg.isNext())
		{
			auto key = domg.get();
			auto key_g = g_dist.getGKey(key);

			// In this case the boundary condition are non periodic
			if (g_dist.isInside(key_g))
			{
				match &= (g_dist.template get<1>(key) == info.LinId(key_g))?true:false;
			}

			++domg;
		}

		BOOST_REQUIRE_EQUAL(match,true);
	}
}



Pietro Incardona's avatar
Pietro Incardona committed
901
void Test2D_complex(const Box<2,float> & domain, long int k)
Pietro Incardona's avatar
Pietro Incardona committed
902
{
Pietro Incardona's avatar
Pietro Incardona committed
903
	typedef Point_test<float> p;
Pietro Incardona's avatar
Pietro Incardona committed
904

Pietro Incardona's avatar
Pietro Incardona committed
905
906
	long int big_step = k / 30;
	big_step = (big_step == 0)?1:big_step;
Pietro Incardona's avatar
Pietro Incardona committed
907
	long int small_step = 21;
Pietro Incardona's avatar
Pietro Incardona committed
908

909
910
	print_test( "Testing 2D complex grid k<=",k);

Pietro Incardona's avatar
Pietro Incardona committed
911
912
913
914
	// 2D test
	for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
	{
		BOOST_TEST_CHECKPOINT( "Testing 2D complex grid k=" << k );
Pietro Incardona's avatar
Pietro Incardona committed
915

916
917
		//! [Create and access a distributed grid complex]

Pietro Incardona's avatar
Pietro Incardona committed
918
919
920
921
		// grid size
		size_t sz[2];
		sz[0] = k;
		sz[1] = k;
Pietro Incardona's avatar
Pietro Incardona committed
922

923
		float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/2.0f);
Pietro Incardona's avatar
Pietro Incardona committed
924

Pietro Incardona's avatar
Pietro Incardona committed
925
926
		// Ghost
		Ghost<2,float> g(0.01 / factor);
927

Pietro Incardona's avatar
Pietro Incardona committed
928
		// Distributed grid with id decomposition
929
		grid_dist_id<2, float, Point_test<float>> g_dist(sz,domain,g);
930

Pietro Incardona's avatar
Pietro Incardona committed
931
932
933
		// check the consistency of the decomposition
		bool val = g_dist.getDecomposition().check_consistency();
		BOOST_REQUIRE_EQUAL(val,true);
Pietro Incardona's avatar
Pietro Incardona committed
934

Pietro Incardona's avatar
Pietro Incardona committed
935
936
		// Grid sm
		grid_sm<2,void> info(sz);
Pietro Incardona's avatar
Pietro Incardona committed
937

Pietro Incardona's avatar
Pietro Incardona committed
938
939
		// get the domain iterator
		size_t count = 0;
Pietro Incardona's avatar
Pietro Incardona committed
940

Pietro Incardona's avatar
Pietro Incardona committed
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
		auto dom = g_dist.getDomainIterator();

		while (dom.isNext())
		{
			auto key = dom.get();
			auto key_g = g_dist.getGKey(key);

			size_t k = info.LinId(key_g);

			g_dist.template get<p::x>(key) = 1 + k;
			g_dist.template get<p::y>(key) = 567 + k;
			g_dist.template get<p::z>(key) = 341 + k;
			g_dist.template get<p::s>(key) = 5670 + k;
			g_dist.template get<p::v>(key)[0] = 921 + k;
			g_dist.template get<p::v>(key)[1] = 5675 + k;
			g_dist.template get<p::v>(key)[2] = 117 + k;
			g_dist.template get<p::t>(key)[0][0] = 1921 + k;
			g_dist.template get<p::t>(key)[0][1] = 25675 + k;
			g_dist.template get<p::t>(key)[0][2] = 3117 + k;
			g_dist.template get<p::t>(key)[1][0] = 4921 + k;
			g_dist.template get<p::t>(key)[1][1] = 55675 + k;
			g_dist.template get<p::t>(key)[1][2] = 6117 + k;
			g_dist.template get<p::t>(key)[2][0] = 7921 + k;
			g_dist.template get<p::t>(key)[2][1] = 85675 + k;
			g_dist.template get<p::t>(key)[2][2] = 9117 + k;

			// Count the point
			count++;

			++dom;
		}
Pietro Incardona's avatar
Pietro Incardona committed
972

973
974
		//! [Create and access a distributed grid complex]

Pietro Incardona's avatar
Pietro Incardona committed
975
976
		// Get the virtual cluster machine
		Vcluster & vcl = g_dist.getVC();
Pietro Incardona's avatar
Pietro Incardona committed
977

Pietro Incardona's avatar
Pietro Incardona committed
978
		// reduce
979
		vcl.sum(count);
Pietro Incardona's avatar
Pietro Incardona committed
980
		vcl.execute();
Pietro Incardona's avatar
Pietro Incardona committed
981

Pietro Incardona's avatar
Pietro Incardona committed
982
		// Check
Pietro Incardona's avatar
Pietro Incardona committed
983
		BOOST_REQUIRE_EQUAL(count,(size_t)k*k);
Pietro Incardona's avatar
Pietro Incardona committed
984
985

		auto dom2 = g_dist.getDomainIterator();
Pietro Incardona's avatar
Pietro Incardona committed
986

Pietro Incardona's avatar
Pietro Incardona committed
987
		bool match = true;
Pietro Incardona's avatar
Pietro Incardona committed
988

Pietro Incardona's avatar
Pietro Incardona committed
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
		// check that the grid store the correct information
		while (dom2.isNext())
		{
			auto key = dom2.get();
			auto key_g = g_dist.getGKey(key);

			size_t k = info.LinId(key_g);

			match &= (g_dist.template get<p::x>(key) == 1 + k)?true:false;
			match &= (g_dist.template get<p::y>(key) == 567 + k)?true:false;
			match &= (g_dist.template get<p::z>(key) == 341 + k)?true:false;
			match &= (g_dist.template get<p::s>(key) == 5670 + k)?true:false;
			match &= (g_dist.template get<p::v>(key)[0] == 921 + k)?true:false;
			match &= (g_dist.template get<p::v>(key)[1] == 5675 + k)?true:false;
			match &= (g_dist.template get<p::v>(key)[2] == 117 + k)?true:false;
			match &= (g_dist.template get<p::t>(key)[0][0] == 1921 + k)?true:false;
			match &= (g_dist.template get<p::t>(key)[0][1] == 25675 + k)?true:false;
			match &= (g_dist.template get<p::t>(key)[0][2] == 3117 + k)?true:false;
			match &= (g_dist.template get<p::t>(key)[1][0] == 4921 + k)?true:false;
			match &= (g_dist.template get<p::t>(key)[1][1] == 55675 + k)?true:false;
			match &= (g_dist.template get<p::t>(key)[1][2] == 6117 + k)?true:false;
			match &= (g_dist.template get<p::t>(key)[2][0] == 7921 + k)?true:false;
			match &= (g_dist.template get<p::t>(key)[2][1] == 85675 + k)?true:false;
			match &= (g_dist.template get<p::t>(key)[2][2] == 9117 + k)?true:false;

			++dom2;
		}

		BOOST_REQUIRE_EQUAL(match,true);

1019
1020
		//! [Synchronized distributed grid complex]

Pietro Incardona's avatar
Pietro Incardona committed
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
		g_dist.template ghost_get<p::x,p::y,p::z,p::s,p::v,p::t>();

		// check that the communication is correctly completed

		auto domg = g_dist.getDomainGhostIterator();

		// check that the grid with the ghost past store the correct information
		while (domg.isNext())
		{
			auto key = domg.get();
			auto key_g = g_dist.getGKey(key);

			// In this case the boundary condition are non periodic
			if (g_dist.isInside(key_g))
			{
				size_t k = info.LinId(key_g);

				match &= (g_dist.template get<p::x>(key) == 1 + k)?true:false;
				match &= (g_dist.template get<p::y>(key) == 567 + k)?true:false;
				match &= (g_dist.template get<p::z>(key) == 341 + k)?true:false;
				match &= (g_dist.template get<p::s>(key) == 5670 + k)?true:false;

				match &= (g_dist.template get<p::v>(key)[0] == 921 + k)?true:false;
				match &= (g_dist.template get<p::v>(key)[1] == 5675 + k)?true:false;
				match &= (g_dist.template get<p::v>(key)[2] == 117 + k)?true:false;

				match &= (g_dist.template get<p::t>(key)[0][0] == 1921 + k)?true:false;
				match &= (g_dist.template get<p::t>(key)[0][1] == 25675 + k)?true:false;
				match &= (g_dist.template get<p::t>(key)[0][2] == 3117 + k)?true:false;
				match &= (g_dist.template get<p::t>(key)[1][0] == 4921 + k)?true:false;
				match &= (g_dist.template get<p::t>(key)[1][1] == 55675 + k)?true:false;
				match &= (g_dist.template get<p::t>(key)[1][2] == 6117 + k)?true:false;
				match &= (g_dist.template get<p::t>(key)[2][0] == 7921 + k)?true:false;
				match &= (g_dist.template get<p::t>(key)[2][1] == 85675 + k)?true:false;
				match &= (g_dist.template get<p::t>(key)[2][2] == 9117 + k)?true:false;
			}

			++domg;
		}
1060
1061

		//! [Synchronized distributed grid complex]
Pietro Incardona's avatar
Pietro Incardona committed
1062
	}
Pietro Incardona's avatar
Pietro Incardona committed
1063
1064
}

Pietro Incardona's avatar
Pietro Incardona committed
1065
void Test3D_complex(const Box<3,float> & domain, long int k)
Pietro Incardona's avatar
Pietro Incardona committed
1066
{
Pietro Incardona's avatar
Pietro Incardona committed
1067
	typedef Point_test<float> p;
Pietro Incardona's avatar
Pietro Incardona committed
1068

Pietro Incardona's avatar
Pietro Incardona committed
1069
1070
	long int big_step = k / 30;
	big_step = (big_step == 0)?1:big_step;
Pietro Incardona's avatar
Pietro Incardona committed
1071
	long int small_step = 21;
Pietro Incardona's avatar
Pietro Incardona committed
1072

1073
1074
	print_test( "Testing 3D grid complex k<=",k);

Pietro Incardona's avatar
Pietro Incardona committed
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
	// 2D test
	for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
	{
		BOOST_TEST_CHECKPOINT( "Testing 3D complex grid k=" << k );

		// grid size
		size_t sz[3];
		sz[0] = k;
		sz[1] = k;
		sz[2] = k;
Pietro Incardona's avatar
Pietro Incardona committed
1085

Pietro Incardona's avatar
Pietro Incardona committed
1086
		// factor
1087
		float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
Pietro Incardona's avatar
Pietro Incardona committed
1088

Pietro Incardona's avatar
Pietro Incardona committed
1089
1090
		// Ghost
		Ghost<3,float> g(0.01 / factor);
Pietro Incardona's avatar
Pietro Incardona committed
1091

Pietro Incardona's avatar
Pietro Incardona committed
1092
1093
		// Distributed grid with id decomposition
		grid_dist_id<3, float, Point_test<float>, CartDecomposition<3,float>> g_dist(sz,domain,g);
Pietro Incardona's avatar
Pietro Incardona committed
1094

Pietro Incardona's avatar
Pietro Incardona committed
1095
1096
1097
		// check the consistency of the decomposition
		bool val = g_dist.getDecomposition().check_consistency();
		BOOST_REQUIRE_EQUAL(val,true);
Pietro Incardona's avatar
Pietro Incardona committed
1098

Pietro Incardona's avatar
Pietro Incardona committed
1099
1100
		// Grid sm
		grid_sm<3,void> info(sz);
Pietro Incardona's avatar
Pietro Incardona committed
1101

Pietro Incardona's avatar
Pietro Incardona committed
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
		// get the domain iterator
		size_t count = 0;

		auto dom = g_dist.getDomainIterator();

		while (dom.isNext())
		{
			auto key = dom.get();
			auto key_g = g_dist.getGKey(key);

			size_t k = info.LinId(key_g);

			g_dist.template get<p::x>(key) = 1 + k;
			g_dist.template get<p::y>(key) = 567 + k;
			g_dist.template get<p::z>(key) = 341 + k;
			g_dist.template get<p::s>(key) = 5670 + k;
			g_dist.template get<p::v>(key)[0] = 921 + k;
			g_dist.template get<p::v>(key)[1] = 5675 + k;
			g_dist.template get<p::v>(key)[2] = 117 + k;
			g_dist.template get<p::t>(key)[0][0] = 1921 + k;
			g_dist.template get<p::t>(key)[0][1] = 25675 + k;
			g_dist.template get<p::t>(key)[0][2] = 3117 + k;
			g_dist.template get<p::t>(key)[1][0] = 4921 + k;
			g_dist.template get<p::t>(key)[1][1] = 55675 + k;
			g_dist.template get<p::t>(key)[1][2] = 6117 + k;
			g_dist.template get<p::t>(key)[2][0] = 7921 + k;
			g_dist.template get<p::t>(key)[2][1] = 85675 + k;
			g_dist.template get<p::t>(key)[2][2] = 9117 + k;

			// Count the point
			count++;

			++dom;
		}

		// Get the virtual cluster machine
		Vcluster & vcl = g_dist.getVC();

		// reduce
1141
		vcl.sum(count);
Pietro Incardona's avatar
Pietro Incardona committed
1142
1143
1144
		vcl.execute();

		// Check
Pietro Incardona's avatar
Pietro Incardona committed
1145
		BOOST_REQUIRE_EQUAL(count,(size_t)k*k*k);
Pietro Incardona's avatar
Pietro Incardona committed
1146

Pietro Incardona's avatar
Pietro Incardona committed
1147
		bool match = true;
Pietro Incardona's avatar
Pietro Incardona committed
1148

Pietro Incardona's avatar
Pietro Incardona committed
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
		auto dom2 = g_dist.getDomainIterator();

		// check that the grid store the correct information
		while (dom2.isNext())
		{
			auto key = dom2.get();
			auto key_g = g_dist.getGKey(key);

			size_t k = info.LinId(key_g);

			match &= (g_dist.template get<p::x>(key) == 1 + k)?true:false;
			match &= (g_dist.template get<p::y>(key) == 567 + k)?true:false;
			match &= (g_dist.template get<p::z>(key) == 341 + k)?true:false;
			match &= (g_dist.template get<p::s>(key) == 5670 + k)?true:false;
			match &= (g_dist.template get<p::v>(key)[0] == 921 + k)?true:false;
			match &= (g_dist.template get<p::v>(key)[1] == 5675 + k)?true:false;
			match &= (g_dist.template get<p::v>(key)[2] == 117 + k)?true:false;
			match &= (g_dist.template get<p::t>(key)[0][0] == 1921 + k)?true:false;
			match &= (g_dist.template get<p::t>(key)[0][1] == 25675 + k)?true:false;
			match &= (g_dist.template get<p::t>(key)[0][2] == 3117 + k)?true:false;
			match &= (g_dist.template get<p::t>(key)[1][0] == 4921 + k)?true:false;
			match &= (g_dist.template get<p::t>(key)[1][1] == 55675 + k)?true:false;
			match &= (g_dist.template get<p::t>(key)[1][2] == 6117 + k)?true:false;
			match &= (g_dist.template get<p::t>(key)[2][0] == 7921 + k)?true:false;
			match &= (g_dist.template get<p::t>(key)[2][1] == 85675 + k)?true:false;
			match &= (g_dist.template get<p::t>(key)[2][2] == 9117 + k)?true:false;

			++dom2;
		}

		BOOST_REQUIRE_EQUAL(match,true);

		g_dist.template ghost_get<p::x,p::y,p::z,p::s,p::v,p::t>();
Pietro Incardona's avatar
Pietro Incardona committed
1182

Pietro Incardona's avatar
Pietro Incardona committed
1183
		// check that the communication is correctly completed
Pietro Incardona's avatar
Pietro Incardona committed
1184

Pietro Incardona's avatar
Pietro Incardona committed
1185
		auto domg = g_dist.getDomainGhostIterator();
Pietro Incardona's avatar
Pietro Incardona committed
1186

Pietro Incardona's avatar
Pietro Incardona committed
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
		// check that the grid with the ghost past store the correct information
		while (domg.isNext())
		{
			auto key = domg.get();
			auto key_g = g_dist.getGKey(key);

			size_t k = info.LinId(key_g);

			// In this case the boundary condition are non periodic
			if (g_dist.isInside(key_g))
			{
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
				match &= (g_dist.template get<p::x>(key) == 1 + k)?true:false;
				match &= (g_dist.template get<p::y>(key) == 567 + k)?true:false;
				match &= (g_dist.template get<p::z>(key) == 341 + k)?true:false;
				match &= (g_dist.template get<p::s>(key) == 5670 + k)?true:false;

				match &= (g_dist.template get<p::v>(key)[0] == 921 + k)?true:false;
				match &= (g_dist.template get<p::v>(key)[1] == 5675 + k)?true:false;
				match &= (g_dist.template get<p::v>(key)[2] == 117 + k)?true:false;

				match &= (g_dist.template get<p::t>(key)[0][0] == 1921 + k)?true:false;
				match &= (g_dist.template get<p::t>(key)[0][1] == 25675 + k)?true:false;
				match &= (g_dist.template get<p::t>(key)[0][2] == 3117 + k)?true:false;
				match &= (g_dist.template get<p::t>(key)[1][0] == 4921 + k)?true:false;
				match &= (g_dist.template get<p::t>(key)[1][1] == 55675 + k)?true:false;
				match &= (g_dist.template get<p::t>(key)[1][2] == 6117 + k)?true:false;
				match &= (g_dist.template get<p::t>(key)[2][0] == 7921 + k)?true:false;
				match &= (g_dist.template get<p::t>(key)[2][1] == 85675 + k)?true:false;
				match &= (g_dist.template get<p::t>(key)[2][2] == 9117 + k)?true:false;
Pietro Incardona's avatar
Pietro Incardona committed
1216
1217
1218
1219
1220
1221
1222
1223
1224
			}

			++domg;
		}

		BOOST_REQUIRE_EQUAL(match,true);
	}
}

Pietro Incardona's avatar
Pietro Incardona committed
1225
1226
1227
1228
1229
1230
// Test duplicated topology

void Test3D_dup(const Box<3,float> & domain, long int k)
{
	long int big_step = k / 30;
	big_step = (big_step == 0)?1:big_step;
Pietro Incardona's avatar
Pietro Incardona committed
1231
	long int small_step = 21;
Pietro Incardona's avatar
Pietro Incardona committed
1232
	long int k_old = k;
Pietro Incardona's avatar
Pietro Incardona committed
1233

1234
	Vcluster & v_cl = create_vcluster();
Pietro Incardona's avatar
Pietro Incardona committed
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252

	if ( v_cl.getProcessingUnits() > 32 )
		return;

	print_test( "Testing 3D duplicate topology complex k<=",k);

	// 3D test
	for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
	{
		BOOST_TEST_CHECKPOINT( "Testing 3D copy decomposition grid k=" << k );

		// grid size
		size_t sz[3];
		sz[0] = k;
		sz[1] = k;
		sz[2] = k;

		// factor
1253
		float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
Pietro Incardona's avatar
Pietro Incardona committed
1254
1255
1256
1257

		// Ghost
		Ghost<3,float> g(0.01 / factor);

Pietro Incardona's avatar
Pietro Incardona committed
1258
		//! [Construct two grid with the same decomposition]
Pietro Incardona's avatar
Pietro Incardona committed
1259

1260
1261
		// Distributed grid with id decomposition (It work also without the third template parameter)
		// Here is given to show that the 2 grid MUST have the same decomposition strategy
Pietro Incardona's avatar
Pietro Incardona committed
1262
1263
1264
1265
1266
		grid_dist_id<3, float, Point_test<float>, CartDecomposition<3,float>> g_dist1(sz,domain,g);

		// another grid with the same decomposition
		grid_dist_id<3, float, Point_test<float>, CartDecomposition<3,float>> g_dist2(g_dist1.getDecomposition(),sz,domain,g);

Pietro Incardona's avatar
Pietro Incardona committed
1267
1268
		//! [Construct two grid with the same decomposition]

1269
1270
1271
1272
1273
		bool ret = g_dist2.getDecomposition().check_consistency();
		BOOST_REQUIRE_EQUAL(ret,true);
		ret = g_dist2.getDecomposition().is_equal(g_dist2.getDecomposition());
		BOOST_REQUIRE_EQUAL(ret,true);

Pietro Incardona's avatar
Pietro Incardona committed
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292

		auto dom_g1 = g_dist1.getDomainIterator();
		auto dom_g2 = g_dist2.getDomainIterator();

		bool check = true;

		while (dom_g1.isNext())
		{
			auto key1 = dom_g1.get();
			auto key2 = dom_g2.get();

			check &= (key1 == key2)?true:false;

			++dom_g1;
			++dom_g2;
		}

		BOOST_REQUIRE_EQUAL(check,true);
	}
Pietro Incardona's avatar
Pietro Incardona committed
1293

Pietro Incardona's avatar
Pietro Incardona committed
1294
1295
	k = k_old;

Pietro Incardona's avatar
Pietro Incardona committed
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
	// 3D test
	for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
	{
		BOOST_TEST_CHECKPOINT( "Testing 3D copy decomposition grid k=" << k );

		// grid size
		size_t sz[3];
		sz[0] = k;
		sz[1] = k;
		sz[2] = k;

		// factor
1308
		float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
Pietro Incardona's avatar
Pietro Incardona committed
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320

		// Ghost
		Ghost<3,float> g(0.01 / factor);

		// Distributed grid with id decomposition
		grid_dist_id<3, float, Point_test<float>, CartDecomposition<3,float>> * g_dist1 = new grid_dist_id<3, float, Point_test<float>, CartDecomposition<3,float>>(sz,domain,g);

		// another grid with the same decomposition
		grid_dist_id<3, float, Point_test<float>, CartDecomposition<3,float>> * g_dist2 = new grid_dist_id<3, float, Point_test<float>, CartDecomposition<3,float>>(g_dist1->getDecomposition(),sz,domain,g);

		delete g_dist1;

Pietro Incardona's avatar
Pietro Incardona committed
1321
1322
		bool ret = g_dist2->getDecomposition().check_consistency();
		BOOST_REQUIRE_EQUAL(ret,true);
1323
1324

		delete g_dist2;
Pietro Incardona's avatar
Pietro Incardona committed
1325
	}
Pietro Incardona's avatar
Pietro Incardona committed
1326
1327
}

1328
1329
1330
1331
// Test decomposition grid iterator

void Test3D_decit(const Box<3,float> & domain, long int k)
{
1332
1333
	size_t k_bck = k;
	{
1334
		Vcluster & v_cl = create_vcluster();
1335

1336
1337
		if ( v_cl.getProcessingUnits() > 32 )
			return;
1338

1339
1340
1341
		long int big_step = k / 30;
		big_step = (big_step == 0)?1:big_step;
		long int small_step = 21;
1342

1343
		print_test( "Testing grid iterator from decomposition k<=",k);
1344

1345
1346
1347
1348
		// 3D test
		for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
		{
			BOOST_TEST_CHECKPOINT( "Testing grid iterator from decomposition k<=" << k );
1349

1350
1351
1352
1353
1354
			// grid size
			size_t sz[3];
			sz[0] = k;
			sz[1] = k;
			sz[2] = k;
1355

1356
			// factor