1 | #define BOOST_TEST_DYN_LINK |
2 | #include <boost/test/unit_test.hpp> |
3 | |
4 | #include "Decomposition/CartDecomposition.hpp" |
5 | #include "util/mathutil.hpp" |
6 | #include "nn_processor_unit_test.hpp" |
7 | |
8 | BOOST_AUTO_TEST_SUITE (CartDecomposition_test) |
9 | |
10 | #define SUB_UNIT_FACTOR 1024 |
11 | |
12 | void setComputationCosts(CartDecomposition<2, float> &dec, size_t n_v, Point<2, float> center, float radius, size_t weight_h, size_t weight_l) |
13 | { |
14 | float radius2 = pow(radius, 2); |
15 | float eq; |
16 | |
17 | // Position structure for the single vertex |
18 | float pos[2]; |
19 | |
20 | for (size_t i = 0; i < n_v; i++) |
21 | { |
22 | dec.getSubSubDomainPosition(i, pos); |
23 | |
24 | eq = pow((pos[0] - center.get(0)), 2) + pow((pos[1] - center.get(1)), 2); |
25 | |
26 | if (eq <= radius2) |
27 | dec.setSubSubDomainComputationCost(i, weight_h); |
28 | else |
29 | dec.setSubSubDomainComputationCost(i, weight_l); |
30 | } |
31 | } |
32 | |
33 | void setComputationCosts3D(CartDecomposition<3, float> &dec, size_t n_v, Point<3, float> center, float radius, size_t weight_h, size_t weight_l) |
34 | { |
35 | float radius2 = radius * radius; |
36 | float eq; |
37 | |
38 | // Position structure for the single vertex |
39 | float pos[3]; |
40 | |
41 | for (size_t i = 0; i < n_v; i++) |
42 | { |
43 | dec.getSubSubDomainPosition(i, pos); |
44 | |
45 | eq = pow((pos[0] - center.get(0)), 2) + pow((pos[1] - center.get(1)), 2) + pow((pos[2] - center.get(2)), 2); |
46 | |
47 | if (eq <= radius2) |
48 | dec.setSubSubDomainComputationCost(i, weight_h); |
49 | else |
50 | dec.setSubSubDomainComputationCost(i, weight_l); |
51 | } |
52 | } |
53 | |
54 | |
55 | |
56 | BOOST_AUTO_TEST_CASE( CartDecomposition_non_periodic_test) |
57 | { |
58 | // Vcluster |
59 | Vcluster<> & vcl = create_vcluster(); |
60 | |
61 | CartDecomposition<3, float> dec(vcl); |
62 | |
63 | // Physical domain |
64 | Box<3, float> box( { 0.0, 0.0, 0.0 }, { 1.0, 1.0, 1.0 }); |
65 | size_t div[3]; |
66 | |
67 | // Get the number of processor and calculate the number of sub-domain |
68 | // for each processor (SUB_UNIT_FACTOR=64) |
69 | size_t n_proc = vcl.getProcessingUnits(); |
70 | size_t n_sub = n_proc * SUB_UNIT_FACTOR; |
71 | |
72 | // Set the number of sub-domains on each dimension (in a scalable way) |
73 | for (int i = 0; i < 3; i++) |
74 | { div[i] = openfpm::math::round_big_2(pow(n_sub,1.0/3));} |
75 | |
76 | // Define ghost |
77 | Ghost<3, float> g(0.01); |
78 | |
79 | // Boundary conditions |
80 | size_t bc[] = { NON_PERIODIC, NON_PERIODIC, NON_PERIODIC }; |
81 | |
82 | // Decompose |
83 | dec.setParameters(div,box,bc,g); |
84 | dec.decompose(); |
85 | |
86 | // For each calculated ghost box |
87 | for (size_t i = 0; i < dec.getNIGhostBox(); i++) |
88 | { |
89 | SpaceBox<3,float> b = dec.getIGhostBox(i); |
90 | size_t proc = dec.getIGhostBoxProcessor(i); |
91 | |
92 | // sample one point inside the box |
93 | Point<3,float> p = b.rnd(); |
94 | |
95 | // Check that ghost_processorsID return that processor number |
96 | const openfpm::vector<size_t> & pr = dec.ghost_processorID<CartDecomposition<3,float>::processor_id>(p); |
97 | |
98 | bool found = false; |
99 | |
100 | for (size_t j = 0; j < pr.size(); j++) |
101 | { |
102 | if (pr.get(j) == proc) |
103 | { found = true; break;} |
104 | } |
105 | |
106 | if (found == false) |
107 | { |
108 | const openfpm::vector<size_t> pr2 = dec.ghost_processorID<CartDecomposition<3,float>::processor_id>(p); |
109 | } |
110 | |
111 | BOOST_REQUIRE_EQUAL(found,true); |
112 | } |
113 | |
114 | // Check the consistency |
115 | |
116 | bool val = dec.check_consistency(); |
117 | BOOST_REQUIRE_EQUAL(val,true); |
118 | |
119 | // We duplicate the decomposition |
120 | CartDecomposition<3, float> dec2 = dec.duplicate(); |
121 | dec2.check_consistency(); |
122 | |
123 | // check that dec and dec2 contain the same information |
124 | bool ret = dec.is_equal(dec2); |
125 | |
126 | // We check if the two decomposition are equal |
127 | BOOST_REQUIRE_EQUAL(ret,true); |
128 | |
129 | // We duplicate the decomposition redefining the ghost |
130 | |
131 | // Define ghost |
132 | Ghost<3, float> g3(0.005); |
133 | |
134 | // We duplicate the decomposition redefining the ghost |
135 | CartDecomposition<3, float> dec3 = dec.duplicate(g3); |
136 | |
137 | ret = dec3.check_consistency(); |
138 | BOOST_REQUIRE_EQUAL(ret,true); |
139 | |
140 | // Check that dec3 is equal to dec2 with the exception of the ghost part |
141 | ret = dec3.is_equal_ng(dec2); |
142 | BOOST_REQUIRE_EQUAL(ret,true); |
143 | } |
144 | |
145 | BOOST_AUTO_TEST_CASE( CartDecomposition_periodic_test) |
146 | { |
147 | // Vcluster |
148 | Vcluster<> & vcl = create_vcluster(); |
149 | |
150 | //! [Create CartDecomposition] |
151 | CartDecomposition<3, float> dec(vcl); |
152 | |
153 | // Physical domain |
154 | Box<3, float> box( { 0.0, 0.0, 0.0 }, { 1.0, 1.0, 1.0 }); |
155 | size_t div[3]; |
156 | |
157 | // Get the number of processor and calculate the number of sub-domain |
158 | // for each processor (SUB_UNIT_FACTOR=64) |
159 | size_t n_proc = vcl.getProcessingUnits(); |
160 | size_t n_sub = n_proc * SUB_UNIT_FACTOR; |
161 | |
162 | // Set the number of sub-domains on each dimension (in a scalable way) |
163 | for (int i = 0; i < 3; i++) |
164 | { div[i] = openfpm::math::round_big_2(pow(n_sub,1.0/3));} |
165 | |
166 | // Define ghost |
167 | Ghost<3, float> g(0.01); |
168 | |
169 | // Boundary conditions |
170 | size_t bc[] = { PERIODIC, PERIODIC, PERIODIC }; |
171 | |
172 | // Decompose |
173 | dec.setParameters(div,box,bc,g); |
174 | dec.decompose(); |
175 | |
176 | //! [Create CartDecomposition] |
177 | |
178 | // For each calculated ghost box |
179 | for (size_t i = 0; i < dec.getNIGhostBox(); i++) |
180 | { |
181 | SpaceBox<3,float> b = dec.getIGhostBox(i); |
182 | size_t proc = dec.getIGhostBoxProcessor(i); |
183 | |
184 | // sample one point inside the box |
185 | Point<3,float> p = b.rnd(); |
186 | |
187 | // Check that ghost_processorsID return that processor number |
188 | const openfpm::vector<size_t> & pr = dec.ghost_processorID<CartDecomposition<3,float>::processor_id>(p); |
189 | |
190 | bool found = false; |
191 | |
192 | for (size_t j = 0; j < pr.size(); j++) |
193 | { |
194 | if (pr.get(j) == proc) |
195 | { found = true; break;} |
196 | } |
197 | |
198 | if (found == false) |
199 | { |
200 | const openfpm::vector<size_t> pr2 = dec.ghost_processorID<CartDecomposition<3,float>::processor_id>(p); |
201 | } |
202 | |
203 | BOOST_REQUIRE_EQUAL(found,true); |
204 | } |
205 | |
206 | // Check the consistency |
207 | bool val = dec.check_consistency(); |
208 | BOOST_REQUIRE_EQUAL(val,true); |
209 | |
210 | // We duplicate the decomposition |
211 | CartDecomposition<3, float> dec2 = dec.duplicate(); |
212 | dec2.check_consistency(); |
213 | |
214 | bool ret = dec.is_equal(dec2); |
215 | |
216 | // We check if the two decomposition are equal |
217 | BOOST_REQUIRE_EQUAL(ret,true); |
218 | |
219 | // check that dec and dec2 contain the same information |
220 | |
221 | // We duplicate the decomposition redefining the ghost |
222 | |
223 | // Define ghost |
224 | Ghost<3, float> g3(0.005); |
225 | |
226 | // We duplicate the decomposition refefining the ghost |
227 | CartDecomposition<3, float> dec3 = dec.duplicate(g3); |
228 | |
229 | ret = dec3.check_consistency(); |
230 | BOOST_REQUIRE_EQUAL(ret,true); |
231 | |
232 | // Check that g3 is equal to dec2 with the exception of the ghost part |
233 | ret = dec3.is_equal_ng(dec2); |
234 | BOOST_REQUIRE_EQUAL(ret,true); |
235 | } |
236 | |
237 | |
238 | ////////////////////////// CartDecomposition extended |
239 | |
240 | BOOST_AUTO_TEST_CASE( CartDecomposition_ext_non_periodic_test) |
241 | { |
242 | // Vcluster |
243 | Vcluster<> & vcl = create_vcluster(); |
244 | |
245 | CartDecomposition<3,float> dec(vcl); |
246 | |
247 | // Physical domain |
248 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
249 | size_t div[3]; |
250 | |
251 | // Get the number of processor and calculate the number of sub-domain |
252 | // for each processor (SUB_UNIT_FACTOR=64) |
253 | size_t n_proc = vcl.getProcessingUnits(); |
254 | size_t n_sub = n_proc * SUB_UNIT_FACTOR; |
255 | |
256 | // Set the number of sub-domains on each dimension (in a scalable way) |
257 | for (int i = 0 ; i < 3 ; i++) |
258 | {div[i] = openfpm::math::round_big_2(pow(n_sub,1.0/3));} |
259 | |
260 | // Define ghost |
261 | Ghost<3,float> g(0.01); |
262 | |
263 | // Boundary conditions |
264 | size_t bc[] = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC}; |
265 | |
266 | // Decompose |
267 | dec.setParameters(div,box,bc,g); |
268 | dec.decompose(); |
269 | |
270 | //! [Extend CartDecomposition] |
271 | |
272 | Box<3,float> box_ext({-0.1,-0.1,-0.1},{1.1,1.1,1.1}); |
273 | |
274 | // Use the old decomposition to extend on a bigger domain |
275 | CartDecomposition_ext<3,float> dec_ext(vcl); |
276 | |
277 | dec_ext.setParameters(dec,g,box_ext); |
278 | |
279 | //! [Extend CartDecomposition] |
280 | |
281 | // Check the new decomposition is fully contained in the new one, and there are |
282 | // box not fully contained i the old box |
283 | |
284 | BOOST_REQUIRE_EQUAL(dec_ext.getNSubDomain(),dec.getNSubDomain()); |
285 | |
286 | double volume = 0.0; |
287 | for (size_t i = 0; i < dec_ext.getNSubDomain() ; i++) |
288 | { |
289 | volume += dec_ext.getSubDomain(i).getVolume(); |
290 | BOOST_REQUIRE_EQUAL(dec_ext.getSubDomain(i).isContained(dec.getSubDomain(i)),true); |
291 | } |
292 | |
293 | vcl.sum(volume); |
294 | vcl.execute(); |
295 | |
296 | BOOST_REQUIRE_CLOSE(volume,1.728,0.0001); |
297 | |
298 | BOOST_REQUIRE_EQUAL(dec.getNNProcessors(),dec_ext.getNNProcessors()); |
299 | |
300 | double volume_g = 0.0; |
301 | double volume_ge = 0.0; |
302 | for (size_t p = 0; p < dec.getNNProcessors(); p++) |
303 | { |
304 | BOOST_REQUIRE_EQUAL(dec.getProcessorNEGhost(p),dec_ext.getProcessorNEGhost(p)); |
305 | for (size_t i = 0; i < dec.getProcessorNEGhost(p); i++) |
306 | { |
307 | volume_g += dec.getProcessorEGhostBox(p,i).getVolume(); |
308 | volume_ge += dec_ext.getProcessorEGhostBox(p,i).getVolume(); |
309 | |
310 | BOOST_REQUIRE_EQUAL(dec_ext.getProcessorEGhostBox(p,i).isContained(dec_ext.getProcessorEGhostBox(p,i)),true); |
311 | } |
312 | } |
313 | |
314 | vcl.sum(volume_g); |
315 | vcl.sum(volume_ge); |
316 | vcl.execute(); |
317 | |
318 | if (vcl.getProcessingUnits() > 1) |
319 | { |
320 | BOOST_REQUIRE(volume_ge > volume_g*1.05); |
321 | } |
322 | |
323 | volume_g = 0.0; |
324 | volume_ge = 0.0; |
325 | for (size_t p = 0; p < dec.getNNProcessors(); p++) |
326 | { |
327 | for (size_t i = 0; i< dec.getProcessorNIGhost(p); i++) |
328 | { |
329 | volume_g += dec.getProcessorIGhostBox(p,i).getVolume(); |
330 | volume_ge += dec_ext.getProcessorIGhostBox(p,i).getVolume(); |
331 | BOOST_REQUIRE_EQUAL(dec_ext.getProcessorIGhostBox(p,i).isContained(dec.getProcessorIGhostBox(p,i)),true); |
332 | } |
333 | } |
334 | |
335 | vcl.sum(volume_g); |
336 | vcl.sum(volume_ge); |
337 | vcl.execute(); |
338 | |
339 | if (vcl.getProcessingUnits() > 1) |
340 | { |
341 | BOOST_REQUIRE(volume_ge > volume_g*1.05); |
342 | } |
343 | } |
344 | |
345 | BOOST_AUTO_TEST_CASE( CartDecomposition_check_cross_consistency_between_proc_idbc_and_ghost ) |
346 | { |
347 | // Vcluster |
348 | Vcluster<> & vcl = create_vcluster(); |
349 | |
350 | if (vcl.size() != 3) |
351 | {return;} |
352 | |
353 | CartDecomposition<3, double> dec(vcl); |
354 | |
355 | size_t bc[3] = {PERIODIC,PERIODIC,PERIODIC}; |
356 | |
357 | // Physical domain |
358 | Box<3, double> box( { -0.01, -0.01, 0.0 }, { 0.01, 0.01, 0.003 }); |
359 | |
360 | Ghost<3,double> g(0.0015); |
361 | |
362 | dec.setGoodParameters(box, bc, g, 512); |
363 | |
364 | dec.decompose(); |
365 | |
366 | // Now we check the point |
367 | |
368 | Point<3,double> p1({-0.0067499999999999999237,-0.0012499999999999995923,0.001250000000000000026}); |
369 | Point<3,double> p2({-0.0067499999999999999237,-0.0012499999999999993755,0.001250000000000000026}); |
370 | |
371 | size_t proc1 = dec.processorIDBC(p1); |
372 | size_t proc2 = dec.processorIDBC(p2); |
373 | |
374 | const openfpm::vector<std::pair<size_t, size_t>> & vp_id1 = dec.template ghost_processorID_pair<typename CartDecomposition<3, double>::lc_processor_id, typename CartDecomposition<3, double>::shift_id>(p1, UNIQUE); |
375 | const openfpm::vector<std::pair<size_t, size_t>> & vp_id2 = dec.template ghost_processorID_pair<typename CartDecomposition<3, double>::lc_processor_id, typename CartDecomposition<3, double>::shift_id>(p2, UNIQUE); |
376 | |
377 | if (proc1 != proc2) |
378 | { |
379 | if (vcl.rank() == proc2) |
380 | { |
381 | BOOST_REQUIRE(vp_id2.size() != 0); |
382 | BOOST_REQUIRE(vp_id1.size() == 0); |
383 | } |
384 | |
385 | if (vcl.rank() == proc1) |
386 | { |
387 | BOOST_REQUIRE(vp_id2.size() == 0 ); |
388 | BOOST_REQUIRE(vp_id1.size() != 0 ); |
389 | } |
390 | } |
391 | } |
392 | |
393 | BOOST_AUTO_TEST_CASE( CartDecomposition_check_cross_consistency_between_proc_idbc_and_ghost2 ) |
394 | { |
395 | // Vcluster |
396 | Vcluster<> & vcl = create_vcluster(); |
397 | |
398 | CartDecomposition<3, double> dec(vcl); |
399 | |
400 | size_t bc[3] = {PERIODIC,PERIODIC,PERIODIC}; |
401 | |
402 | // Physical domain |
403 | Box<3, double> box( { -0.01, -0.01, 0.0 }, { 0.01, 0.01, 0.003 }); |
404 | |
405 | Ghost<3,double> g(0.0015); |
406 | |
407 | dec.setGoodParameters(box, bc, g, 512); |
408 | |
409 | dec.decompose(); |
410 | |
411 | // Now we check the point |
412 | |
413 | for (size_t j = 0 ; j < 3 ; j++ ) |
414 | { |
415 | for (size_t i = 0 ; i < dec.getNSubDomain() ; i++) |
416 | { |
417 | Point<3,double> p1; |
418 | Point<3,double> p2; |
419 | |
420 | p1.get(0) = SpaceBox<3,double>(dec.getSubDomains().get(i)).getLow(0); |
421 | p1.get(1) = SpaceBox<3,double>(dec.getSubDomains().get(i)).getLow(1); |
422 | p1.get(2) = SpaceBox<3,double>(dec.getSubDomains().get(i)).getLow(2); |
423 | |
424 | p2 = p1; |
425 | |
426 | p2.get(j) = std::nextafter(SpaceBox<3,double>(dec.getSubDomains().get(i)).getLow(j),-1.0); |
427 | |
428 | size_t proc1 = dec.processorIDBC(p1); |
429 | size_t proc2 = dec.processorIDBC(p2); |
430 | |
431 | BOOST_REQUIRE(proc1 < vcl.size()); |
432 | BOOST_REQUIRE(proc2 < vcl.size()); |
433 | |
434 | const openfpm::vector<std::pair<size_t, size_t>> & vp_id1 = dec.template ghost_processorID_pair<typename CartDecomposition<3, double>::lc_processor_id, typename CartDecomposition<3, double>::shift_id>(p1, UNIQUE); |
435 | const openfpm::vector<std::pair<size_t, size_t>> & vp_id2 = dec.template ghost_processorID_pair<typename CartDecomposition<3, double>::lc_processor_id, typename CartDecomposition<3, double>::shift_id>(p2, UNIQUE); |
436 | |
437 | if (proc1 != proc2) |
438 | { |
439 | if (vcl.rank() == proc2) |
440 | { |
441 | BOOST_REQUIRE(vp_id2.size() != 0); |
442 | BOOST_REQUIRE(vp_id1.size() == 0); |
443 | } |
444 | |
445 | if (vcl.rank() == proc1) |
446 | { |
447 | BOOST_REQUIRE(vp_id2.size() == 0 ); |
448 | BOOST_REQUIRE(vp_id1.size() != 0 ); |
449 | } |
450 | } |
451 | |
452 | |
453 | p1.get(0) = std::nextafter(SpaceBox<3,double>(dec.getSubDomains().get(i)).getHigh(0),SpaceBox<3,double>(dec.getSubDomains().get(i)).getLow(0)); |
454 | p1.get(1) = std::nextafter(SpaceBox<3,double>(dec.getSubDomains().get(i)).getHigh(1),SpaceBox<3,double>(dec.getSubDomains().get(i)).getLow(1)); |
455 | p1.get(2) = std::nextafter(SpaceBox<3,double>(dec.getSubDomains().get(i)).getHigh(2),SpaceBox<3,double>(dec.getSubDomains().get(i)).getLow(2)); |
456 | |
457 | p2 = p1; |
458 | |
459 | p2.get(j) = std::nextafter(SpaceBox<3,double>(dec.getSubDomains().get(i)).getHigh(j),1.0); |
460 | |
461 | proc1 = dec.processorIDBC(p1); |
462 | proc2 = dec.processorIDBC(p2); |
463 | |
464 | BOOST_REQUIRE(proc1 < vcl.size()); |
465 | BOOST_REQUIRE(proc2 < vcl.size()); |
466 | |
467 | const openfpm::vector<std::pair<size_t, size_t>> & vp_id3 = dec.template ghost_processorID_pair<typename CartDecomposition<3, double>::lc_processor_id, typename CartDecomposition<3, double>::shift_id>(p1, UNIQUE); |
468 | const openfpm::vector<std::pair<size_t, size_t>> & vp_id4 = dec.template ghost_processorID_pair<typename CartDecomposition<3, double>::lc_processor_id, typename CartDecomposition<3, double>::shift_id>(p2, UNIQUE); |
469 | |
470 | if (proc1 != proc2) |
471 | { |
472 | if (vcl.rank() == proc2) |
473 | { |
474 | BOOST_REQUIRE(vp_id4.size() != 0); |
475 | BOOST_REQUIRE(vp_id3.size() == 0); |
476 | } |
477 | |
478 | if (vcl.rank() == proc1) |
479 | { |
480 | BOOST_REQUIRE(vp_id4.size() == 0 ); |
481 | BOOST_REQUIRE(vp_id3.size() != 0 ); |
482 | } |
483 | } |
484 | |
485 | } |
486 | } |
487 | } |
488 | |
489 | |
490 | |
491 | BOOST_AUTO_TEST_CASE( CartDecomposition_non_periodic_test_dist_grid) |
492 | { |
493 | // Vcluster |
494 | Vcluster<> & vcl = create_vcluster(); |
495 | |
496 | CartDecomposition<3, float> dec(vcl); |
497 | |
498 | // Physical domain |
499 | Box<3, float> box( { 0.0, 0.0, 0.0 }, { 1.0, 1.0, 1.0 }); |
500 | size_t div[3]; |
501 | size_t div_sub[3]; |
502 | |
503 | // Get the number of processor and calculate the number of sub-domain |
504 | // for each processor (SUB_UNIT_FACTOR=64) |
505 | size_t n_proc = vcl.getProcessingUnits(); |
506 | size_t n_sub = n_proc * SUB_UNIT_FACTOR*4*4*4; |
507 | |
508 | // Set the number of sub-domains on each dimension (in a scalable way) |
509 | for (int i = 0; i < 3; i++) |
510 | {div[i] = openfpm::math::round_big_2(pow(n_sub,1.0/3));} |
511 | |
512 | // create a sub_distribution grid |
513 | for (int i = 0; i < 3; i++) |
514 | {div_sub[i] = div[i] / 4;} |
515 | |
516 | grid_sm<3,void> gsub(div_sub); |
517 | |
518 | // Define ghost |
519 | Ghost<3, float> g(0.01); |
520 | |
521 | // Boundary conditions |
522 | size_t bc[] = { NON_PERIODIC, NON_PERIODIC, NON_PERIODIC }; |
523 | |
524 | // Decompose |
525 | dec.setParameters(div,box,bc,g,gsub); |
526 | dec.decompose(); |
527 | |
528 | // For each calculated ghost box |
529 | for (size_t i = 0; i < dec.getNIGhostBox(); i++) |
530 | { |
531 | SpaceBox<3,float> b = dec.getIGhostBox(i); |
532 | size_t proc = dec.getIGhostBoxProcessor(i); |
533 | |
534 | // sample one point inside the box |
535 | Point<3,float> p = b.rnd(); |
536 | |
537 | // Check that ghost_processorsID return that processor number |
538 | const openfpm::vector<size_t> & pr = dec.ghost_processorID<CartDecomposition<3,float>::processor_id>(p); |
539 | |
540 | bool found = false; |
541 | |
542 | for (size_t j = 0; j < pr.size(); j++) |
543 | { |
544 | if (pr.get(j) == proc) |
545 | { found = true; break;} |
546 | } |
547 | |
548 | if (found == false) |
549 | { |
550 | const openfpm::vector<size_t> pr2 = dec.ghost_processorID<CartDecomposition<3,float>::processor_id>(p); |
551 | } |
552 | |
553 | BOOST_REQUIRE_EQUAL(found,true); |
554 | } |
555 | |
556 | // Check the consistency |
557 | |
558 | bool val = dec.check_consistency(); |
559 | BOOST_REQUIRE_EQUAL(val,true); |
560 | } |
561 | |
562 | BOOST_AUTO_TEST_CASE( CartDecomposition_nsub_algo_functions_test) |
563 | { |
564 | size_t n_sub = 64*2; |
565 | size_t div[3]; |
566 | |
567 | nsub_to_div2<3>(div,n_sub,3); |
568 | |
569 | BOOST_REQUIRE_EQUAL(div[0],8ul); |
570 | BOOST_REQUIRE_EQUAL(div[1],8ul); |
571 | BOOST_REQUIRE_EQUAL(div[2],8ul); |
572 | |
573 | nsub_to_div2<3>(div,n_sub,2); |
574 | |
575 | BOOST_REQUIRE_EQUAL(div[0],16ul); |
576 | BOOST_REQUIRE_EQUAL(div[1],16ul); |
577 | BOOST_REQUIRE_EQUAL(div[2],1ul); |
578 | |
579 | nsub_to_div2<3>(div,n_sub,1); |
580 | |
581 | BOOST_REQUIRE_EQUAL(div[0],128ul); |
582 | BOOST_REQUIRE_EQUAL(div[1],1ul); |
583 | BOOST_REQUIRE_EQUAL(div[2],1ul); |
584 | |
585 | n_sub = 64*3; |
586 | nsub_to_div<3>(div,n_sub,3); |
587 | |
588 | BOOST_REQUIRE_EQUAL(div[0],5ul); |
589 | BOOST_REQUIRE_EQUAL(div[1],5ul); |
590 | BOOST_REQUIRE_EQUAL(div[2],5ul); |
591 | |
592 | nsub_to_div<3>(div,n_sub,2); |
593 | |
594 | BOOST_REQUIRE_EQUAL(div[0],13ul); |
595 | BOOST_REQUIRE_EQUAL(div[1],13ul); |
596 | BOOST_REQUIRE_EQUAL(div[2],1ul); |
597 | |
598 | nsub_to_div<3>(div,n_sub,1); |
599 | |
600 | BOOST_REQUIRE_EQUAL(div[0],192ul); |
601 | BOOST_REQUIRE_EQUAL(div[1],1ul); |
602 | BOOST_REQUIRE_EQUAL(div[2],1ul); |
603 | |
604 | // Test high dimension cart decomposition subdivision |
605 | |
606 | Box<50,double> domain; |
607 | size_t bc[50]; |
608 | Ghost<50,double> ghost(0.01); |
609 | |
610 | for(size_t i = 0 ; i < 50 ; i++) |
611 | { |
612 | domain.setLow(i,0.0); |
613 | domain.setHigh(i,1.0); |
614 | bc[i] = NON_PERIODIC; |
615 | } |
616 | |
617 | CartDecomposition<50,double> dec(create_vcluster()); |
618 | |
619 | dec.setGoodParameters(domain,bc,ghost,64); |
620 | |
621 | size_t div2[50]; |
622 | dec.getParameters(div2); |
623 | |
624 | auto & v_cl = create_vcluster(); |
625 | if (v_cl.size() == 1) |
626 | { |
627 | for (size_t i = 0 ; i < 50 ; i++) |
628 | { |
629 | if (i < 6) |
630 | {BOOST_REQUIRE_EQUAL(div2[i],2ul);} |
631 | else |
632 | {BOOST_REQUIRE_EQUAL(div2[i],1ul);} |
633 | } |
634 | } |
635 | |
636 | if (v_cl.size() == 2) |
637 | { |
638 | for (size_t i = 0 ; i < 50 ; i++) |
639 | { |
640 | if (i < 7) |
641 | {BOOST_REQUIRE_EQUAL(div2[i],2ul);} |
642 | else |
643 | {BOOST_REQUIRE_EQUAL(div2[i],1ul);} |
644 | } |
645 | } |
646 | |
647 | if (v_cl.size() == 3) |
648 | { |
649 | for (size_t i = 0 ; i < 50 ; i++) |
650 | { |
651 | if (i < 2) |
652 | {BOOST_REQUIRE_EQUAL(div2[i],13ul);} |
653 | else |
654 | {BOOST_REQUIRE_EQUAL(div2[i],1ul);} |
655 | } |
656 | } |
657 | |
658 | if (v_cl.size() == 4) |
659 | { |
660 | for (size_t i = 0 ; i < 50 ; i++) |
661 | { |
662 | if (i < 8) |
663 | {BOOST_REQUIRE_EQUAL(div2[i],2ul);} |
664 | else |
665 | {BOOST_REQUIRE_EQUAL(div2[i],1ul);} |
666 | } |
667 | } |
668 | |
669 | if (v_cl.size() == 5) |
670 | { |
671 | for (size_t i = 0 ; i < 50 ; i++) |
672 | { |
673 | if (i < 8) |
674 | {BOOST_REQUIRE_EQUAL(div2[i],2ul);} |
675 | else |
676 | {BOOST_REQUIRE_EQUAL(div2[i],1ul);} |
677 | } |
678 | } |
679 | |
680 | if (v_cl.size() == 6) |
681 | { |
682 | for (size_t i = 0 ; i < 50 ; i++) |
683 | { |
684 | if (i < 3) |
685 | {BOOST_REQUIRE_EQUAL(div2[i],7ul);} |
686 | else |
687 | {BOOST_REQUIRE_EQUAL(div2[i],1ul);} |
688 | } |
689 | } |
690 | } |
691 | |
692 | BOOST_AUTO_TEST_SUITE_END() |
693 | |
694 | |