CartDecomposition_unit_test.hpp 8.78 KB
Newer Older
incardon's avatar
incardon committed
1 2 3 4
#ifndef CARTDECOMPOSITION_UNIT_TEST_HPP
#define CARTDECOMPOSITION_UNIT_TEST_HPP

#include "CartDecomposition.hpp"
5
#include "util/mathutil.hpp"
incardon's avatar
incardon committed
6

7
BOOST_AUTO_TEST_SUITE (CartDecomposition_test)
incardon's avatar
incardon committed
8

9
#define SUB_UNIT_FACTOR 1024
incardon's avatar
incardon committed
10

11
void setComputationCosts(CartDecomposition<2, float> &dec, size_t n_v, Point<2, float> center, float radius, size_t weight_h, size_t weight_l)
incardon's avatar
incardon committed
12
{
tonynsyde's avatar
tonynsyde committed
13 14 15 16
	float radius2 = pow(radius, 2);
	float eq;

	// Position structure for the single vertex
17
	float pos[2];
tonynsyde's avatar
tonynsyde committed
18

19
	for (size_t i = 0; i < n_v; i++)
tonynsyde's avatar
tonynsyde committed
20 21 22 23 24 25 26 27 28 29 30 31 32 33
	{
		dec.getSubSubDomainPosition(i, pos);

		eq = pow((pos[0] - center.get(0)), 2) + pow((pos[1] - center.get(1)), 2);

		if (eq <= radius2)
			dec.setSubSubDomainComputationCost(i, weight_h);
		else
			dec.setSubSubDomainComputationCost(i, weight_l);
	}
}

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
	float radius2 = radius * radius;
tonynsyde's avatar
tonynsyde committed
35 36 37 38 39
	float eq;

	// Position structure for the single vertex
	float pos[3];

40
	for (size_t i = 0; i < n_v; i++)
tonynsyde's avatar
tonynsyde committed
41 42 43 44 45 46 47 48 49 50 51 52 53 54
	{
		dec.getSubSubDomainPosition(i, pos);

		eq = pow((pos[0] - center.get(0)), 2) + pow((pos[1] - center.get(1)), 2) + pow((pos[2] - center.get(2)), 2);

		if (eq <= radius2)
			dec.setSubSubDomainComputationCost(i, weight_h);
		else
			dec.setSubSubDomainComputationCost(i, weight_l);
	}
}



55
BOOST_AUTO_TEST_CASE( CartDecomposition_non_periodic_test)
Pietro Incardona's avatar
Pietro Incardona committed
56 57
{
	// Vcluster
58
	Vcluster & vcl = create_vcluster();
Pietro Incardona's avatar
Pietro Incardona committed
59

60
	CartDecomposition<3, float> dec(vcl);
Pietro Incardona's avatar
Pietro Incardona committed
61 62

	// Physical domain
63
	Box<3, float> box( { 0.0, 0.0, 0.0 }, { 1.0, 1.0, 1.0 });
Pietro Incardona's avatar
Pietro Incardona committed
64 65 66 67 68 69 70 71
	size_t div[3];

	// Get the number of processor and calculate the number of sub-domain
	// for each processor (SUB_UNIT_FACTOR=64)
	size_t n_proc = vcl.getProcessingUnits();
	size_t n_sub = n_proc * SUB_UNIT_FACTOR;

	// Set the number of sub-domains on each dimension (in a scalable way)
72 73
	for (int i = 0; i < 3; i++)
	{	div[i] = openfpm::math::round_big_2(pow(n_sub,1.0/3));}
Pietro Incardona's avatar
Pietro Incardona committed
74 75

	// Define ghost
76
	Ghost<3, float> g(0.01);
Pietro Incardona's avatar
Pietro Incardona committed
77 78

	// Boundary conditions
79
	size_t bc[] = { NON_PERIODIC, NON_PERIODIC, NON_PERIODIC };
Pietro Incardona's avatar
Pietro Incardona committed
80

incardon's avatar
incardon committed
81
	// Decompose
Pietro Incardona's avatar
Pietro Incardona committed
82
	dec.setParameters(div,box,bc,g);
Pietro Incardona's avatar
Pietro Incardona committed
83
	dec.decompose();
incardon's avatar
incardon committed
84

85
	// For each calculated ghost box
86
	for (size_t i = 0; i < dec.getNIGhostBox(); i++)
87 88 89 90 91 92 93 94 95 96 97 98
	{
		SpaceBox<3,float> b = dec.getIGhostBox(i);
		size_t proc = dec.getIGhostBoxProcessor(i);

		// sample one point inside the box
		Point<3,float> p = b.rnd();

		// Check that ghost_processorsID return that processor number
		const openfpm::vector<size_t> & pr = dec.template ghost_processorID<CartDecomposition<3,float>::processor_id>(p);

		bool found = false;

99
		for (size_t j = 0; j < pr.size(); j++)
100 101
		{
			if (pr.get(j) == proc)
102
			{	found = true; break;}
103 104 105 106 107 108 109 110 111
		}

		if (found == false)
		{
			const openfpm::vector<size_t> pr2 = dec.template ghost_processorID<CartDecomposition<3,float>::processor_id>(p);
		}

		BOOST_REQUIRE_EQUAL(found,true);
	}
incardon's avatar
incardon committed
112 113

	// Check the consistency
114

incardon's avatar
incardon committed
115 116
	bool val = dec.check_consistency();
	BOOST_REQUIRE_EQUAL(val,true);
117 118

	// We duplicate the decomposition
119
	CartDecomposition<3, float> dec2 = dec.duplicate();
incardon's avatar
incardon committed
120 121
	dec2.check_consistency();

122
	// check that dec and dec2 contain the same information
incardon's avatar
incardon committed
123 124
	bool ret = dec.is_equal(dec2);

incardon's avatar
incardon committed
125
	// We check if the two decomposition are equal
incardon's avatar
incardon committed
126
	BOOST_REQUIRE_EQUAL(ret,true);
incardon's avatar
incardon committed
127

128 129 130
	// We duplicate the decomposition redefining the ghost

	// Define ghost
131
	Ghost<3, float> g3(0.005);
132

133
	// We duplicate the decomposition redefining the ghost
134
	CartDecomposition<3, float> dec3 = dec.duplicate(g3);
incardon's avatar
incardon committed
135 136 137 138

	ret = dec3.check_consistency();
	BOOST_REQUIRE_EQUAL(ret,true);

139
	// Check that dec3 is equal to dec2 with the exception of the ghost part
incardon's avatar
incardon committed
140 141
	ret = dec3.is_equal_ng(dec2);
	BOOST_REQUIRE_EQUAL(ret,true);
incardon's avatar
incardon committed
142 143
}

144 145
BOOST_AUTO_TEST_CASE( CartDecomposition_periodic_test)
{
146
	// Vcluster
147
	Vcluster & vcl = create_vcluster();
148

149
	//! [Create CartDecomposition]
150
	CartDecomposition<3, float> dec(vcl);
151 152

	// Physical domain
153
	Box<3, float> box( { 0.0, 0.0, 0.0 }, { 1.0, 1.0, 1.0 });
154 155 156 157 158 159 160
	size_t div[3];

	// Get the number of processor and calculate the number of sub-domain
	// for each processor (SUB_UNIT_FACTOR=64)
	size_t n_proc = vcl.getProcessingUnits();
	size_t n_sub = n_proc * SUB_UNIT_FACTOR;

161
	// Set the number of sub-domains on each dimension (in a scalable way)
162 163
	for (int i = 0; i < 3; i++)
	{	div[i] = openfpm::math::round_big_2(pow(n_sub,1.0/3));}
164

165
	// Define ghost
166
	Ghost<3, float> g(0.01);
167 168

	// Boundary conditions
169
	size_t bc[] = { PERIODIC, PERIODIC, PERIODIC };
170 171 172

	// Decompose
	dec.setParameters(div,box,bc,g);
Pietro Incardona's avatar
Pietro Incardona committed
173
	dec.decompose();
174

175 176 177
	//! [Create CartDecomposition]

	// For each calculated ghost box
178
	for (size_t i = 0; i < dec.getNIGhostBox(); i++)
179 180 181
	{
		SpaceBox<3,float> b = dec.getIGhostBox(i);
		size_t proc = dec.getIGhostBoxProcessor(i);
182

183 184
		// sample one point inside the box
		Point<3,float> p = b.rnd();
185

186 187
		// Check that ghost_processorsID return that processor number
		const openfpm::vector<size_t> & pr = dec.template ghost_processorID<CartDecomposition<3,float>::processor_id>(p);
188

189
		bool found = false;
190

191
		for (size_t j = 0; j < pr.size(); j++)
192 193
		{
			if (pr.get(j) == proc)
194
			{	found = true; break;}
195
		}
196

197
		if (found == false)
198
		{
199
			const openfpm::vector<size_t> pr2 = dec.template ghost_processorID<CartDecomposition<3,float>::processor_id>(p);
200 201
		}

202 203
		BOOST_REQUIRE_EQUAL(found,true);
	}
204

205 206 207
	// Check the consistency
	bool val = dec.check_consistency();
	BOOST_REQUIRE_EQUAL(val,true);
208

209
	// We duplicate the decomposition
210
	CartDecomposition<3, float> dec2 = dec.duplicate();
211
	dec2.check_consistency();
212

213
	bool ret = dec.is_equal(dec2);
214

215 216
	// We check if the two decomposition are equal
	BOOST_REQUIRE_EQUAL(ret,true);
217

218
	// check that dec and dec2 contain the same information
219

220
	// We duplicate the decomposition redefining the ghost
221

222
	// Define ghost
223
	Ghost<3, float> g3(0.005);
224

225
	// We duplicate the decomposition refefining the ghost
226
	CartDecomposition<3, float> dec3 = dec.duplicate(g3);
227

228 229
	ret = dec3.check_consistency();
	BOOST_REQUIRE_EQUAL(ret,true);
230

231 232 233
	// Check that g3 is equal to dec2 with the exception of the ghost part
	ret = dec3.is_equal_ng(dec2);
	BOOST_REQUIRE_EQUAL(ret,true);
234 235
}

Pietro Incardona's avatar
Pietro Incardona committed
236 237 238 239 240 241

////////////////////////// CartDecomposition extended

BOOST_AUTO_TEST_CASE( CartDecomposition_ext_non_periodic_test)
{
	// Vcluster
242
	Vcluster & vcl = create_vcluster();
Pietro Incardona's avatar
Pietro Incardona committed
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273

	CartDecomposition<3,float> dec(vcl);

	// Physical domain
	Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0});
	size_t div[3];

	// Get the number of processor and calculate the number of sub-domain
	// for each processor (SUB_UNIT_FACTOR=64)
	size_t n_proc = vcl.getProcessingUnits();
	size_t n_sub = n_proc * SUB_UNIT_FACTOR;

	// Set the number of sub-domains on each dimension (in a scalable way)
	for (int i = 0 ; i < 3 ; i++)
	{div[i] = openfpm::math::round_big_2(pow(n_sub,1.0/3));}

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

	// Boundary conditions
	size_t bc[] = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};

	// Decompose
	dec.setParameters(div,box,bc,g);
	dec.decompose();

	//! [Extend CartDecomposition]

	Box<3,float> box_ext({-0.1,-0.1,-0.1},{1.1,1.1,1.1});

	// Use the old decomposition to extend on a bigger domain
274 275 276
	CartDecomposition_ext<3,float> dec_ext(vcl);

	dec_ext.setParameters(dec,g,box_ext);
Pietro Incardona's avatar
Pietro Incardona committed
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294

	//! [Extend CartDecomposition]

	// Check the new decomposition is fully contained in the new one, and there are
	// box not fully contained i the old box

	BOOST_REQUIRE_EQUAL(dec_ext.getNSubDomain(),dec.getNSubDomain());

	double volume = 0.0;
	for (size_t i = 0; i < dec_ext.getNSubDomain() ; i++)
	{
		volume += dec_ext.getSubDomain(i).getVolume();
		BOOST_REQUIRE_EQUAL(dec_ext.getSubDomain(i).isContained(dec.getSubDomain(i)),true);
	}

	vcl.sum(volume);
	vcl.execute();

295
	BOOST_REQUIRE_CLOSE(volume,1.728,0.0001);
Pietro Incardona's avatar
Pietro Incardona committed
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316

	BOOST_REQUIRE_EQUAL(dec.getNNProcessors(),dec_ext.getNNProcessors());

	double volume_g = 0.0;
	double volume_ge = 0.0;
	for (size_t p = 0; p < dec.getNNProcessors(); p++)
	{
		BOOST_REQUIRE_EQUAL(dec.getProcessorNEGhost(p),dec_ext.getProcessorNEGhost(p));
		for (size_t i = 0; i < dec.getProcessorNEGhost(p); i++)
		{
			volume_g += dec.getProcessorEGhostBox(p,i).getVolume();
			volume_ge += dec_ext.getProcessorEGhostBox(p,i).getVolume();

			BOOST_REQUIRE_EQUAL(dec_ext.getProcessorEGhostBox(p,i).isContained(dec_ext.getProcessorEGhostBox(p,i)),true);
		}
	}

	vcl.sum(volume_g);
	vcl.sum(volume_ge);
	vcl.execute();

Pietro Incardona's avatar
Pietro Incardona committed
317 318 319 320
	if (vcl.getProcessingUnits() > 1)
	{
		BOOST_REQUIRE(volume_ge > volume_g*1.05);
	}
Pietro Incardona's avatar
Pietro Incardona committed
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337

	volume_g = 0.0;
	volume_ge = 0.0;
	for (size_t p = 0; p < dec.getNNProcessors(); p++)
	{
		for (size_t i = 0; i< dec.getProcessorNIGhost(p); i++)
		{
			volume_g += dec.getProcessorIGhostBox(p,i).getVolume();
			volume_ge += dec_ext.getProcessorIGhostBox(p,i).getVolume();
			BOOST_REQUIRE_EQUAL(dec_ext.getProcessorIGhostBox(p,i).isContained(dec.getProcessorIGhostBox(p,i)),true);
		}
	}

	vcl.sum(volume_g);
	vcl.sum(volume_ge);
	vcl.execute();

Pietro Incardona's avatar
Pietro Incardona committed
338 339 340 341
	if (vcl.getProcessingUnits() > 1)
	{
		BOOST_REQUIRE(volume_ge > volume_g*1.05);
	}
Pietro Incardona's avatar
Pietro Incardona committed
342 343 344
}


incardon's avatar
incardon committed
345 346 347
BOOST_AUTO_TEST_SUITE_END()

#endif