FDScheme_unit_tests.cpp 18.9 KB
Newer Older
incardon's avatar
incardon committed
1 2 3 4 5 6 7 8 9 10
/*
 * FDScheme_unit_tests.hpp
 *
 *  Created on: Oct 5, 2015
 *      Author: i-bird
 */

#ifndef OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_FDSCHEME_UNIT_TESTS_HPP_
#define OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_FDSCHEME_UNIT_TESTS_HPP_

incardon's avatar
incardon committed
11 12 13
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>

incardon's avatar
incardon committed
14 15
#include "FiniteDifference/Derivative.hpp"
#include "FiniteDifference/Laplacian.hpp"
16
#include "Decomposition/CartDecomposition.hpp"
incardon's avatar
incardon committed
17
#include "util/grid_dist_testing.hpp"
18
#include "FiniteDifference/Average.hpp"
19
#include "FiniteDifference/sum.hpp"
20
#include "eq.hpp"
incardon's avatar
incardon committed
21 22 23

constexpr unsigned int x = 0;
constexpr unsigned int y = 1;
24
constexpr unsigned int z = 2;
incardon's avatar
incardon committed
25 26 27 28
constexpr unsigned int V = 0;

struct sys_nn
{
29
	//! dimensionaly of the equation (2D problem 3D problem ...)
incardon's avatar
incardon committed
30
	static const unsigned int dims = 2;
31
	//! number of degree of freedoms
incardon's avatar
incardon committed
32
	static const unsigned int nvar = 1;
33

incardon's avatar
incardon committed
34 35
	static const unsigned int ord = EQS_FIELD;

36
	//! boundary at X and Y
incardon's avatar
incardon committed
37 38
	static const bool boundary[];

39
	//! type of space float, double, ...
incardon's avatar
incardon committed
40
	typedef float stype;
41

42
	//! Base grid
incardon's avatar
incardon committed
43
	typedef grid_dist_id<dims,stype,aggregate<float>,CartDecomposition<2,stype> > b_grid;
44

45
	//! specify that we are on testing
46
	typedef void testing;
incardon's avatar
incardon committed
47 48 49 50 51 52
};

const bool sys_nn::boundary[] = {NON_PERIODIC,NON_PERIODIC};

struct sys_pp
{
53
	//! dimensionaly of the equation (2D problem 3D problem ...)
incardon's avatar
incardon committed
54
	static const unsigned int dims = 2;
55
	//! number of degree of freedom in the system
incardon's avatar
incardon committed
56 57 58
	static const unsigned int nvar = 1;
	static const unsigned int ord = EQS_FIELD;

59
	//! boundary at X and Y
incardon's avatar
incardon committed
60 61
	static const bool boundary[];

62
	//! type of space float, double, ...
incardon's avatar
incardon committed
63
	typedef float stype;
64

65
	//! Base grid
incardon's avatar
incardon committed
66
	typedef grid_dist_id<dims,stype,aggregate<float>,CartDecomposition<2,stype> > b_grid;
67

68
	//! Indicate we are on testing
69
	typedef void testing;
incardon's avatar
incardon committed
70 71 72 73 74 75 76 77
};

const bool sys_pp::boundary[] = {PERIODIC,PERIODIC};

//////////////////////// STAGGERED CASE //////////////////////////////////

struct syss_nn
{
78
	//! dimensionaly of the equation (2D problem 3D problem ...)
incardon's avatar
incardon committed
79
	static const unsigned int dims = 2;
80
	//! Degree of freedom in the system
incardon's avatar
incardon committed
81
	static const unsigned int nvar = 1;
82

incardon's avatar
incardon committed
83 84
	static const unsigned int ord = EQS_FIELD;

85
	//! Indicate that the type of grid is staggered
86
	static const unsigned int grid_type = STAGGERED_GRID;
incardon's avatar
incardon committed
87

88
	//! boundary at X and Y
incardon's avatar
incardon committed
89 90
	static const bool boundary[];

91
	//! type of space float, double, ...
incardon's avatar
incardon committed
92
	typedef float stype;
93

94
	//! Base grid
incardon's avatar
incardon committed
95
	typedef grid_dist_id<dims,stype,aggregate<float>,CartDecomposition<2,stype> > b_grid;
96

97
	//! Indicate we are on testing
98
	typedef void testing;
incardon's avatar
incardon committed
99 100 101 102 103 104
};

const bool syss_nn::boundary[] = {NON_PERIODIC,NON_PERIODIC};

struct syss_pp
{
105
	//! dimensionaly of the equation (2D problem 3D problem ...)
incardon's avatar
incardon committed
106
	static const unsigned int dims = 2;
107
	//! number of fields in the system
incardon's avatar
incardon committed
108 109 110
	static const unsigned int nvar = 1;
	static const unsigned int ord = EQS_FIELD;

111
	//! Indicate the grid is staggered
112
	static const unsigned int grid_type = STAGGERED_GRID;
incardon's avatar
incardon committed
113

114
	//! boundary at X and Y
incardon's avatar
incardon committed
115 116
	static const bool boundary[];

117
	//! type of space float, double, ...
incardon's avatar
incardon committed
118
	typedef float stype;
119

120
	//! Base grid
incardon's avatar
incardon committed
121
	typedef grid_dist_id<dims,stype,aggregate<float>,CartDecomposition<2,stype> > b_grid;
122

123
	//! Indicate we are on testing
124
	typedef void testing;
incardon's avatar
incardon committed
125 126 127 128 129 130
};

const bool syss_pp::boundary[] = {PERIODIC,PERIODIC};

BOOST_AUTO_TEST_SUITE( fd_test )

131 132 133 134
// Derivative central, composed central derivative,
// and central bulk + one-sided non periodic

BOOST_AUTO_TEST_CASE( der_central_non_periodic)
incardon's avatar
incardon committed
135
{
136 137
	//! [Usage of stencil derivative]

incardon's avatar
incardon committed
138 139 140
	// grid size
	size_t sz[2]={16,16};

incardon's avatar
incardon committed
141 142 143
	// grid_dist_testing
	grid_dist_testing<2> g_map(sz);

incardon's avatar
incardon committed
144 145 146
	// grid_sm
	grid_sm<2,void> ginfo(sz);

147 148 149
	// spacing
	float spacing[2] = {0.5,0.3};

incardon's avatar
incardon committed
150 151 152 153 154
	// Create several keys
	grid_dist_key_dx<2> key11(0,grid_key_dx<2>(1,1));
	grid_dist_key_dx<2> key00(0,grid_key_dx<2>(0,0));
	grid_dist_key_dx<2> key22(0,grid_key_dx<2>(2,2));
	grid_dist_key_dx<2> key1515(0,grid_key_dx<2>(15,15));
incardon's avatar
incardon committed
155 156 157 158 159

	// filled colums
	std::unordered_map<long int,float> cols_x;
	std::unordered_map<long int,float> cols_y;

160 161
	D<x,Field<V,sys_nn>,sys_nn>::value(g_map,key11,ginfo,spacing,cols_x,1);
	D<y,Field<V,sys_nn>,sys_nn>::value(g_map,key11,ginfo,spacing,cols_y,1);
incardon's avatar
incardon committed
162

163 164
	BOOST_REQUIRE_EQUAL(cols_x.size(),2ul);
	BOOST_REQUIRE_EQUAL(cols_y.size(),2ul);
incardon's avatar
incardon committed
165

166 167
	BOOST_REQUIRE_EQUAL(cols_x[17+1],1/spacing[0]/2.0);
	BOOST_REQUIRE_EQUAL(cols_x[17-1],-1/spacing[0]/2.0);
incardon's avatar
incardon committed
168

169 170
	BOOST_REQUIRE_EQUAL(cols_y[17+16],1/spacing[1]/2.0);
	BOOST_REQUIRE_EQUAL(cols_y[17-16],-1/spacing[1]/2.0);
incardon's avatar
incardon committed
171

172 173
	//! [Usage of stencil derivative]

incardon's avatar
incardon committed
174 175 176 177 178 179 180 181 182
	// filled colums

	std::unordered_map<long int,float> cols_xx;
	std::unordered_map<long int,float> cols_xy;
	std::unordered_map<long int,float> cols_yx;
	std::unordered_map<long int,float> cols_yy;

	// Composed derivative

183 184 185 186
	D<x,D<x,Field<V,sys_nn>,sys_nn>,sys_nn>::value(g_map,key22,ginfo,spacing,cols_xx,1);
	D<x,D<y,Field<V,sys_nn>,sys_nn>,sys_nn>::value(g_map,key22,ginfo,spacing,cols_xy,1);
	D<y,D<x,Field<V,sys_nn>,sys_nn>,sys_nn>::value(g_map,key22,ginfo,spacing,cols_yx,1);
	D<y,D<y,Field<V,sys_nn>,sys_nn>,sys_nn>::value(g_map,key22,ginfo,spacing,cols_yy,1);
incardon's avatar
incardon committed
187

188 189 190 191
	BOOST_REQUIRE_EQUAL(cols_xx.size(),3ul);
	BOOST_REQUIRE_EQUAL(cols_xy.size(),4ul);
	BOOST_REQUIRE_EQUAL(cols_yx.size(),4ul);
	BOOST_REQUIRE_EQUAL(cols_yy.size(),3ul);
incardon's avatar
incardon committed
192

193 194 195
	BOOST_REQUIRE_EQUAL(cols_xx[32],1/spacing[0]/spacing[0]/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_xx[34],-2/spacing[0]/spacing[0]/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_xx[36],1/spacing[0]/spacing[0]/2.0/2.0);
incardon's avatar
incardon committed
196

197 198 199 200
	BOOST_REQUIRE_EQUAL(cols_xy[17],1/spacing[0]/spacing[1]/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_xy[19],-1/spacing[0]/spacing[1]/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_xy[49],-1/spacing[0]/spacing[1]/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_xy[51],1/spacing[0]/spacing[1]/2.0/2.0);
incardon's avatar
incardon committed
201

202 203 204 205
	BOOST_REQUIRE_EQUAL(cols_yx[17],1/spacing[0]/spacing[1]/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_yx[19],-1/spacing[0]/spacing[1]/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_yx[49],-1/spacing[0]/spacing[1]/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_xy[51],1/spacing[0]/spacing[1]/2.0/2.0);
incardon's avatar
incardon committed
206

207 208 209
	BOOST_REQUIRE_EQUAL(cols_yy[2],1/spacing[1]/spacing[1]/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_yy[34],-2/spacing[1]/spacing[1]/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_yy[66],1/spacing[1]/spacing[1]/2.0/2.0);
incardon's avatar
incardon committed
210 211 212 213 214 215

	// Non periodic with one sided

	cols_x.clear();
	cols_y.clear();

216 217
	D<x,Field<V,sys_nn>,sys_nn,CENTRAL_B_ONE_SIDE>::value(g_map,key11,ginfo,spacing,cols_x,1);
	D<y,Field<V,sys_nn>,sys_nn,CENTRAL_B_ONE_SIDE>::value(g_map,key11,ginfo,spacing,cols_y,1);
incardon's avatar
incardon committed
218

219 220
	BOOST_REQUIRE_EQUAL(cols_x.size(),2ul);
	BOOST_REQUIRE_EQUAL(cols_y.size(),2ul);
incardon's avatar
incardon committed
221

222 223
	BOOST_REQUIRE_EQUAL(cols_x[17+1],1/spacing[0]);
	BOOST_REQUIRE_EQUAL(cols_x[17-1],-1/spacing[0]);
incardon's avatar
incardon committed
224

225 226
	BOOST_REQUIRE_EQUAL(cols_y[17+16],1/spacing[1]);
	BOOST_REQUIRE_EQUAL(cols_y[17-16],-1/spacing[1]);
incardon's avatar
incardon committed
227 228 229 230 231 232

	// Border left

	cols_x.clear();
	cols_y.clear();

233 234
	D<x,Field<V,sys_nn>,sys_nn,CENTRAL_B_ONE_SIDE>::value(g_map,key00,ginfo,spacing,cols_x,1);
	D<y,Field<V,sys_nn>,sys_nn,CENTRAL_B_ONE_SIDE>::value(g_map,key00,ginfo,spacing,cols_y,1);
incardon's avatar
incardon committed
235

236 237
	BOOST_REQUIRE_EQUAL(cols_x.size(),3ul);
	BOOST_REQUIRE_EQUAL(cols_y.size(),3ul);
incardon's avatar
incardon committed
238

239 240 241
	BOOST_REQUIRE_EQUAL(cols_x[0],-1.5/spacing[0]);
	BOOST_REQUIRE_EQUAL(cols_x[1],2/spacing[0]);
	BOOST_REQUIRE_EQUAL(cols_x[2],-0.5/spacing[0]);
incardon's avatar
incardon committed
242

243 244 245
	BOOST_REQUIRE_CLOSE(cols_y[0],-1.5/spacing[1],0.001);
	BOOST_REQUIRE_CLOSE(cols_y[16],2/spacing[1],0.001);
	BOOST_REQUIRE_CLOSE(cols_y[32],-0.5/spacing[1],0.001);
incardon's avatar
incardon committed
246 247 248 249 250 251

	// Border Top right

	cols_x.clear();
	cols_y.clear();

252 253
	D<x,Field<V,sys_nn>,sys_nn,CENTRAL_B_ONE_SIDE>::value(g_map,key1515,ginfo,spacing,cols_x,1);
	D<y,Field<V,sys_nn>,sys_nn,CENTRAL_B_ONE_SIDE>::value(g_map,key1515,ginfo,spacing,cols_y,1);
incardon's avatar
incardon committed
254

255 256
	BOOST_REQUIRE_EQUAL(cols_x.size(),3ul);
	BOOST_REQUIRE_EQUAL(cols_y.size(),3ul);
incardon's avatar
incardon committed
257

258 259 260
	BOOST_REQUIRE_EQUAL(cols_x[15*16+15],1.5/spacing[0]);
	BOOST_REQUIRE_EQUAL(cols_x[15*16+14],-2/spacing[0]);
	BOOST_REQUIRE_EQUAL(cols_x[15*16+13],0.5/spacing[0]);
incardon's avatar
incardon committed
261

262 263 264
	BOOST_REQUIRE_CLOSE(cols_y[15*16+15],1.5/spacing[1],0.001);
	BOOST_REQUIRE_CLOSE(cols_y[14*16+15],-2/spacing[1],0.001);
	BOOST_REQUIRE_CLOSE(cols_y[13*16+15],0.5/spacing[1],0.001);
incardon's avatar
incardon committed
265 266
}

267 268 269 270 271 272 273
// Derivative forward and backward non periodic

BOOST_AUTO_TEST_CASE( der_forward_backward_non_periodic )
{
	// grid size
	size_t sz[2]={16,16};

274 275 276
	// spacing
	float spacing[2] = {0.5,0.3};

277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
	// grid_dist_testing
	grid_dist_testing<2> g_map(sz);

	// grid_sm
	grid_sm<2,void> ginfo(sz);

	// Create several keys
	grid_dist_key_dx<2> key11(0,grid_key_dx<2>(1,1));
	grid_dist_key_dx<2> key00(0,grid_key_dx<2>(0,0));
	grid_dist_key_dx<2> key22(0,grid_key_dx<2>(2,2));
	grid_dist_key_dx<2> key1515(0,grid_key_dx<2>(15,15));

	// filled colums
	std::unordered_map<long int,float> cols_x;
	std::unordered_map<long int,float> cols_y;

293 294
	D<x,Field<V,sys_nn>,sys_nn,FORWARD>::value(g_map,key11,ginfo,spacing,cols_x,1);
	D<y,Field<V,sys_nn>,sys_nn,FORWARD>::value(g_map,key11,ginfo,spacing,cols_y,1);
295

296 297
	BOOST_REQUIRE_EQUAL(cols_x.size(),2ul);
	BOOST_REQUIRE_EQUAL(cols_y.size(),2ul);
298

299 300
	BOOST_REQUIRE_EQUAL(cols_x[17+1],1/spacing[0]);
	BOOST_REQUIRE_EQUAL(cols_x[17],-1/spacing[0]);
301

302 303
	BOOST_REQUIRE_EQUAL(cols_y[17+16],1/spacing[1]);
	BOOST_REQUIRE_EQUAL(cols_y[17],-1/spacing[1]);
304 305 306 307

	cols_x.clear();
	cols_y.clear();

308 309
	D<x,Field<V,sys_nn>,sys_nn,BACKWARD>::value(g_map,key11,ginfo,spacing,cols_x,1);
	D<y,Field<V,sys_nn>,sys_nn,BACKWARD>::value(g_map,key11,ginfo,spacing,cols_y,1);
310

311 312
	BOOST_REQUIRE_EQUAL(cols_x.size(),2ul);
	BOOST_REQUIRE_EQUAL(cols_y.size(),2ul);
313

314 315
	BOOST_REQUIRE_EQUAL(cols_x[17],1/spacing[0]);
	BOOST_REQUIRE_EQUAL(cols_x[17-1],-1/spacing[0]);
316

317 318
	BOOST_REQUIRE_EQUAL(cols_y[17],1/spacing[1]);
	BOOST_REQUIRE_EQUAL(cols_y[17-16],-1/spacing[1]);
319 320 321 322 323
}

// Average central non periodic

BOOST_AUTO_TEST_CASE( avg_central_non_periodic)
324 325 326 327
{
	// grid size
	size_t sz[2]={16,16};

328 329 330
	// spacing
	float spacing[2] = {0.5,0.3};

331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
	// grid_dist_testing
	grid_dist_testing<2> g_map(sz);

	// grid_sm
	grid_sm<2,void> ginfo(sz);

	// Create several keys
	grid_dist_key_dx<2> key11(0,grid_key_dx<2>(1,1));
	grid_dist_key_dx<2> key00(0,grid_key_dx<2>(0,0));
	grid_dist_key_dx<2> key22(0,grid_key_dx<2>(2,2));
	grid_dist_key_dx<2> key1515(0,grid_key_dx<2>(15,15));

	// filled colums
	std::unordered_map<long int,float> cols_x;
	std::unordered_map<long int,float> cols_y;

347 348
	Avg<x,Field<V,sys_nn>,sys_nn>::value(g_map,key11,ginfo,spacing,cols_x,1);
	Avg<y,Field<V,sys_nn>,sys_nn>::value(g_map,key11,ginfo,spacing,cols_y,1);
349

350 351
	BOOST_REQUIRE_EQUAL(cols_x.size(),2ul);
	BOOST_REQUIRE_EQUAL(cols_y.size(),2ul);
352

353 354
	BOOST_REQUIRE_EQUAL(cols_x[17+1],0.5);
	BOOST_REQUIRE_EQUAL(cols_x[17-1],0.5);
355

356 357
	BOOST_REQUIRE_EQUAL(cols_y[17+16],0.5);
	BOOST_REQUIRE_EQUAL(cols_y[17-16],0.5);
358 359 360 361 362 363 364 365 366 367

	// filled colums

	std::unordered_map<long int,float> cols_xx;
	std::unordered_map<long int,float> cols_xy;
	std::unordered_map<long int,float> cols_yx;
	std::unordered_map<long int,float> cols_yy;

	// Composed derivative

368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394
	Avg<x,Avg<x,Field<V,sys_nn>,sys_nn>,sys_nn>::value(g_map,key22,ginfo,spacing,cols_xx,1);
	Avg<x,Avg<y,Field<V,sys_nn>,sys_nn>,sys_nn>::value(g_map,key22,ginfo,spacing,cols_xy,1);
	Avg<y,Avg<x,Field<V,sys_nn>,sys_nn>,sys_nn>::value(g_map,key22,ginfo,spacing,cols_yx,1);
	Avg<y,Avg<y,Field<V,sys_nn>,sys_nn>,sys_nn>::value(g_map,key22,ginfo,spacing,cols_yy,1);

	BOOST_REQUIRE_EQUAL(cols_xx.size(),3ul);
	BOOST_REQUIRE_EQUAL(cols_xy.size(),4ul);
	BOOST_REQUIRE_EQUAL(cols_yx.size(),4ul);
	BOOST_REQUIRE_EQUAL(cols_yy.size(),3ul);

	BOOST_REQUIRE_EQUAL(cols_xx[32],1/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_xx[34],2/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_xx[36],1/2.0/2.0);

	BOOST_REQUIRE_EQUAL(cols_xy[17],1/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_xy[19],1/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_xy[49],1/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_xy[51],1/2.0/2.0);

	BOOST_REQUIRE_EQUAL(cols_yx[17],1/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_yx[19],1/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_yx[49],1/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_xy[51],1/2.0/2.0);

	BOOST_REQUIRE_EQUAL(cols_yy[2],1/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_yy[34],2/2.0/2.0);
	BOOST_REQUIRE_EQUAL(cols_yy[66],1/2.0/2.0);
395
}
incardon's avatar
incardon committed
396

397 398 399


BOOST_AUTO_TEST_CASE( der_central_staggered_non_periodic)
400 401 402 403
{
	// grid size
	size_t sz[2]={16,16};

404 405 406
	// spacing
	float spacing[2] = {0.5,0.3};

407 408 409
	// grid_sm
	grid_sm<2,void> ginfo(sz);

incardon's avatar
incardon committed
410 411 412 413 414 415 416
	// grid_dist_testing
	grid_dist_testing<2> g_map(sz);

	// Create several keys
	grid_dist_key_dx<2> key11(0,grid_key_dx<2>(1,1));
	grid_dist_key_dx<2> key22(0,grid_key_dx<2>(2,2));
	grid_dist_key_dx<2> key1515(0,grid_key_dx<2>(15,15));
417 418 419 420 421

	// filled colums
	std::unordered_map<long int,float> cols_x;
	std::unordered_map<long int,float> cols_y;

422 423
	D<x,Field<V,syss_nn>,syss_pp>::value(g_map,key11,ginfo,spacing,cols_x,1);
	D<y,Field<V,syss_nn>,syss_pp>::value(g_map,key11,ginfo,spacing,cols_y,1);
424

425 426
	BOOST_REQUIRE_EQUAL(cols_x.size(),2ul);
	BOOST_REQUIRE_EQUAL(cols_y.size(),2ul);
427

428 429
	BOOST_REQUIRE_EQUAL(cols_x[17],1/spacing[0]);
	BOOST_REQUIRE_EQUAL(cols_x[17-1],-1/spacing[0]);
430

431 432
	BOOST_REQUIRE_EQUAL(cols_y[17],1/spacing[1]);
	BOOST_REQUIRE_EQUAL(cols_y[17-16],-1/spacing[1]);
433 434 435 436 437

	cols_x.clear();
	cols_y.clear();
}

438
BOOST_AUTO_TEST_CASE( avg_central_staggered_non_periodic)
439 440 441 442
{
	// grid size
	size_t sz[2]={16,16};

443 444 445
	// spacing
	float spacing[2] = {0.5,0.3};

446 447 448 449 450 451 452 453 454 455 456 457 458 459 460
	// grid_sm
	grid_sm<2,void> ginfo(sz);

	// grid_dist_testing
	grid_dist_testing<2> g_map(sz);

	// Create several keys
	grid_dist_key_dx<2> key11(0,grid_key_dx<2>(1,1));
	grid_dist_key_dx<2> key22(0,grid_key_dx<2>(2,2));
	grid_dist_key_dx<2> key1515(0,grid_key_dx<2>(15,15));

	// filled colums
	std::unordered_map<long int,float> cols_x;
	std::unordered_map<long int,float> cols_y;

461 462
	Avg<x,Field<V,syss_pp>,syss_pp>::value(g_map,key11,ginfo,spacing,cols_x,1);
	Avg<y,Field<V,syss_pp>,syss_pp>::value(g_map,key11,ginfo,spacing,cols_y,1);
463

464 465
	BOOST_REQUIRE_EQUAL(cols_x.size(),2ul);
	BOOST_REQUIRE_EQUAL(cols_y.size(),2ul);
466

467 468
	BOOST_REQUIRE_EQUAL(cols_x[17],1/2.0);
	BOOST_REQUIRE_EQUAL(cols_x[17-1],1/2.0);
469

470 471
	BOOST_REQUIRE_EQUAL(cols_y[17],1/2.0);
	BOOST_REQUIRE_EQUAL(cols_y[17-16],1/2.0);
472 473 474 475 476

	cols_x.clear();
	cols_y.clear();
}

incardon's avatar
incardon committed
477 478
/////////////// Laplacian test

479
BOOST_AUTO_TEST_CASE( lap_periodic)
incardon's avatar
incardon committed
480
{
481 482
	//! [Laplacian usage]

incardon's avatar
incardon committed
483 484 485 486 487 488
	// grid size
	size_t sz[2]={16,16};

	// grid_sm
	grid_sm<2,void> ginfo(sz);

489 490 491
	// spacing
	float spacing[2] = {0.5,0.3};

incardon's avatar
incardon committed
492 493 494 495 496 497 498
	// grid_dist_testing
	grid_dist_testing<2> g_map(sz);

	// Create several keys
	grid_dist_key_dx<2> key11(0,grid_key_dx<2>(1,1));
	grid_dist_key_dx<2> key22(0,grid_key_dx<2>(2,2));
	grid_dist_key_dx<2> key1414(0,grid_key_dx<2>(14,14));
incardon's avatar
incardon committed
499 500 501 502

	// filled colums
	std::unordered_map<long int,float> cols;

503
	Lap<Field<V,sys_pp>,sys_pp>::value(g_map,key11,ginfo,spacing,cols,1);
incardon's avatar
incardon committed
504

505
	BOOST_REQUIRE_EQUAL(cols.size(),5ul);
incardon's avatar
incardon committed
506

507 508 509 510
	BOOST_REQUIRE_EQUAL(cols[1],1/spacing[1]/spacing[1]);
	BOOST_REQUIRE_EQUAL(cols[17-1],1/spacing[0]/spacing[0]);
	BOOST_REQUIRE_EQUAL(cols[17+1],1/spacing[0]/spacing[0]);
	BOOST_REQUIRE_EQUAL(cols[17+16],1/spacing[1]/spacing[1]);
incardon's avatar
incardon committed
511

512
	BOOST_REQUIRE_EQUAL(cols[17],-2/spacing[0]/spacing[0] - 2/spacing[1]/spacing[1]);
incardon's avatar
incardon committed
513

514 515
	//! [Laplacian usage]

incardon's avatar
incardon committed
516 517
	cols.clear();

518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534
	Lap<Field<V,sys_pp>,sys_pp>::value(g_map,key1414,ginfo,spacing,cols,1);

	BOOST_REQUIRE_EQUAL(cols.size(),5ul);

	BOOST_REQUIRE_EQUAL(cols[14*16+13],1.0/spacing[0]/spacing[0]);
	BOOST_REQUIRE_EQUAL(cols[14*16+15],1.0/spacing[0]/spacing[0]);
	BOOST_REQUIRE_CLOSE(cols[13*16+14],1.0/spacing[1]/spacing[1],0.001);
	BOOST_REQUIRE_CLOSE(cols[15*16+14],1.0/spacing[1]/spacing[1],0.001);

	BOOST_REQUIRE_EQUAL(cols[14*16+14],-2/spacing[0]/spacing[0] - 2/spacing[1]/spacing[1]);
}

// sum test


BOOST_AUTO_TEST_CASE( sum_periodic)
{
535 536
	//! [sum example]

537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562
	// grid size
	size_t sz[2]={16,16};

	// spacing
	float spacing[2] = {0.5,0.3};

	// grid_sm
	grid_sm<2,void> ginfo(sz);

	// grid_dist_testing
	grid_dist_testing<2> g_map(sz);

	// Create several keys
	grid_dist_key_dx<2> key11(0,grid_key_dx<2>(1,1));
	grid_dist_key_dx<2> key22(0,grid_key_dx<2>(2,2));
	grid_dist_key_dx<2> key1414(0,grid_key_dx<2>(14,14));

	// filled colums
	std::unordered_map<long int,float> cols;

	sum<Field<V,sys_pp>,Field<V,sys_pp>,sys_pp>::value(g_map,key11,ginfo,spacing,cols,1);

	BOOST_REQUIRE_EQUAL(cols.size(),1ul);

	BOOST_REQUIRE_EQUAL(cols[17],2);

563 564
	//! [sum example]

565 566 567 568 569 570 571 572 573
	cols.clear();

	sum<Field<V,sys_pp>, Field<V,sys_pp> , Field<V,sys_pp> ,sys_pp>::value(g_map,key11,ginfo,spacing,cols,1);

	BOOST_REQUIRE_EQUAL(cols.size(),1ul);

	BOOST_REQUIRE_EQUAL(cols[17],3);

	cols.clear();
incardon's avatar
incardon committed
574

575 576
	//! [minus example]

577
	sum<Field<V,sys_pp>, Field<V,sys_pp> , minus<Field<V,sys_pp>,sys_pp> ,sys_pp>::value(g_map,key11,ginfo,spacing,cols,1);
incardon's avatar
incardon committed
578

579
	BOOST_REQUIRE_EQUAL(cols.size(),1ul);
incardon's avatar
incardon committed
580

581
	BOOST_REQUIRE_EQUAL(cols[17],1ul);
582 583

	//! [minus example]
incardon's avatar
incardon committed
584 585 586 587 588 589 590
}

//////////////// Position ////////////////////

BOOST_AUTO_TEST_CASE( fd_test_use_staggered_position)
{
	// grid size
591 592 593 594
	size_t sz[2]={16,16};

	// grid_sm
	grid_sm<2,void> ginfo(sz);
incardon's avatar
incardon committed
595 596 597

	// Create a derivative row Matrix
	grid_key_dx<2> key00(0,0);
598
	grid_key_dx<2> key11(1,1);
incardon's avatar
incardon committed
599 600 601
	grid_key_dx<2> key22(2,2);
	grid_key_dx<2> key1515(15,15);

602 603
	comb<2> vx_c[] = {{0,-1}};
	comb<2> vy_c[] = {{-1,0}};
incardon's avatar
incardon committed
604

605 606 607 608
	grid_key_dx<2> key_ret_vx_x = D<x,Field<V,syss_nn>,syss_nn>::position(key00,ginfo,vx_c);
	grid_key_dx<2> key_ret_vx_y = D<y,Field<V,syss_nn>,syss_nn>::position(key00,ginfo,vx_c);
	grid_key_dx<2> key_ret_vy_x = D<x,Field<V,syss_nn>,syss_nn>::position(key00,ginfo,vy_c);
	grid_key_dx<2> key_ret_vy_y = D<y,Field<V,syss_nn>,syss_nn>::position(key00,ginfo,vy_c);
incardon's avatar
incardon committed
609

610 611 612 613 614 615 616 617
	BOOST_REQUIRE_EQUAL(key_ret_vx_x.get(0),0);
	BOOST_REQUIRE_EQUAL(key_ret_vx_x.get(1),0);
	BOOST_REQUIRE_EQUAL(key_ret_vx_y.get(0),-1);
	BOOST_REQUIRE_EQUAL(key_ret_vx_y.get(1),-1);
	BOOST_REQUIRE_EQUAL(key_ret_vy_y.get(0),0);
	BOOST_REQUIRE_EQUAL(key_ret_vy_y.get(1),0);
	BOOST_REQUIRE_EQUAL(key_ret_vy_x.get(0),-1);
	BOOST_REQUIRE_EQUAL(key_ret_vy_x.get(1),-1);
incardon's avatar
incardon committed
618 619 620

	// Composed derivative

621 622 623 624
	grid_key_dx<2> key_ret_xx = D<x,D<x,Field<V,syss_nn>,syss_nn>,syss_nn>::position(key00,ginfo,vx_c);
	grid_key_dx<2> key_ret_xy = D<x,D<y,Field<V,syss_nn>,syss_nn>,syss_nn>::position(key00,ginfo,vx_c);
	grid_key_dx<2> key_ret_yx = D<y,D<x,Field<V,syss_nn>,syss_nn>,syss_nn>::position(key00,ginfo,vx_c);
	grid_key_dx<2> key_ret_yy = D<y,D<y,Field<V,syss_nn>,syss_nn>,syss_nn>::position(key00,ginfo,vx_c);
incardon's avatar
incardon committed
625

626
	BOOST_REQUIRE_EQUAL(key_ret_xx.get(0),-1);
incardon's avatar
incardon committed
627 628 629
	BOOST_REQUIRE_EQUAL(key_ret_xx.get(1),0);

	BOOST_REQUIRE_EQUAL(key_ret_xy.get(0),0);
630
	BOOST_REQUIRE_EQUAL(key_ret_xy.get(1),-1);
incardon's avatar
incardon committed
631

632 633
	BOOST_REQUIRE_EQUAL(key_ret_yx.get(0),0);
	BOOST_REQUIRE_EQUAL(key_ret_yx.get(1),-1);
incardon's avatar
incardon committed
634

635 636
	BOOST_REQUIRE_EQUAL(key_ret_yy.get(0),-1);
	BOOST_REQUIRE_EQUAL(key_ret_yy.get(1),0);
incardon's avatar
incardon committed
637

638
	////////////////// Non periodic one sided
incardon's avatar
incardon committed
639

640 641 642 643
	key_ret_vx_x = D<x,Field<V,syss_nn>,syss_nn,CENTRAL_B_ONE_SIDE>::position(key00,ginfo,vx_c);
	key_ret_vx_y = D<y,Field<V,syss_nn>,syss_nn,CENTRAL_B_ONE_SIDE>::position(key00,ginfo,vx_c);
	key_ret_vy_x = D<x,Field<V,syss_nn>,syss_nn,CENTRAL_B_ONE_SIDE>::position(key00,ginfo,vy_c);
	key_ret_vy_y = D<y,Field<V,syss_nn>,syss_nn,CENTRAL_B_ONE_SIDE>::position(key00,ginfo,vy_c);
incardon's avatar
incardon committed
644

645 646 647 648 649 650 651 652
	BOOST_REQUIRE_EQUAL(key_ret_vx_x.get(0),-1);
	BOOST_REQUIRE_EQUAL(key_ret_vx_x.get(1),0);
	BOOST_REQUIRE_EQUAL(key_ret_vx_y.get(0),-1);
	BOOST_REQUIRE_EQUAL(key_ret_vx_y.get(1),0);
	BOOST_REQUIRE_EQUAL(key_ret_vy_y.get(0),0);
	BOOST_REQUIRE_EQUAL(key_ret_vy_y.get(1),-1);
	BOOST_REQUIRE_EQUAL(key_ret_vy_x.get(0),0);
	BOOST_REQUIRE_EQUAL(key_ret_vy_x.get(1),-1);
incardon's avatar
incardon committed
653 654 655 656 657 658 659 660

	// Border left*/
}

BOOST_AUTO_TEST_SUITE_END()


#endif /* OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_FDSCHEME_UNIT_TESTS_HPP_ */