Skip to content
Snippets Groups Projects
CartDecomposition_unit_test.hpp 9.38 KiB
Newer Older
Pietro Incardona's avatar
Pietro Incardona committed
#ifndef CARTDECOMPOSITION_UNIT_TEST_HPP
#define CARTDECOMPOSITION_UNIT_TEST_HPP

#include "CartDecomposition.hpp"
#include "util/mathutil.hpp"
BOOST_AUTO_TEST_SUITE (CartDecomposition_test)
#define SUB_UNIT_FACTOR 1024
void setComputationCosts(CartDecomposition<2, float> &dec, size_t n_v, Point<2, float> center, float radius, size_t weight_h, size_t weight_l)
Pietro Incardona's avatar
Pietro Incardona committed
{
	float radius2 = pow(radius, 2);
	float eq;

	// Position structure for the single vertex
	for (size_t i = 0; i < n_v; i++)
	{
		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)
{
	float radius2 = radius * radius;
	float eq;

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

	for (size_t i = 0; i < n_v; i++)
	{
		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);
	}
}



BOOST_AUTO_TEST_CASE( CartDecomposition_non_periodic_test)
{
	// Vcluster
	Vcluster & vcl = *global_v_cluster;

	// Initialize the global VCluster
	init_global_v_cluster(&boost::unit_test::framework::master_test_suite().argc,&boost::unit_test::framework::master_test_suite().argv);

	//! [Create CartDecomposition]
	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);
Pietro Incardona's avatar
Pietro Incardona committed
	dec.decompose();
	//! [Create CartDecomposition]

	// For each calculated ghost box
	for (size_t i = 0; i < dec.getNIGhostBox(); i++)
	{
		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;

		for (size_t j = 0; j < pr.size(); j++)
			{	found = true; break;}
		}

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

		BOOST_REQUIRE_EQUAL(found,true);
	}

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

	// We duplicate the decomposition
	CartDecomposition<3, float> dec2 = dec.duplicate();
Pietro Incardona's avatar
Pietro Incardona committed
	dec2.check_consistency();

	// check that dec and dec2 contain the same information
	bool ret = dec.is_equal(dec2);

Pietro Incardona's avatar
Pietro Incardona committed
	// We check if the two decomposition are equal
	BOOST_REQUIRE_EQUAL(ret,true);
Pietro Incardona's avatar
Pietro Incardona committed

	// We duplicate the decomposition redefining the ghost

	// Define ghost
	Ghost<3, float> g3(0.005);
	// We duplicate the decomposition redefining the ghost
	CartDecomposition<3, float> dec3 = dec.duplicate(g3);

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

	// Check that dec3 is equal to dec2 with the exception of the ghost part
	ret = dec3.is_equal_ng(dec2);
	BOOST_REQUIRE_EQUAL(ret,true);
BOOST_AUTO_TEST_CASE( CartDecomposition_periodic_test)
{
	// Vcluster
	Vcluster & vcl = *global_v_cluster;

	// Initialize the global VCluster
	init_global_v_cluster(&boost::unit_test::framework::master_test_suite().argc,&boost::unit_test::framework::master_test_suite().argv);

	//! [Create CartDecomposition]
	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));}
	Ghost<3, float> g(0.01);

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

	// Decompose
	dec.setParameters(div,box,bc,g);
Pietro Incardona's avatar
Pietro Incardona committed
	dec.decompose();
	//! [Create CartDecomposition]

	// For each calculated ghost box
	for (size_t i = 0; i < dec.getNIGhostBox(); i++)
	{
		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;
		for (size_t j = 0; j < pr.size(); j++)
		{
			if (pr.get(j) == proc)
			{	found = true; break;}
		if (found == false)
			const openfpm::vector<size_t> pr2 = dec.template ghost_processorID<CartDecomposition<3,float>::processor_id>(p);
		BOOST_REQUIRE_EQUAL(found,true);
	}
	// Check the consistency
	bool val = dec.check_consistency();
	BOOST_REQUIRE_EQUAL(val,true);
	// We duplicate the decomposition
	CartDecomposition<3, float> dec2 = dec.duplicate();
	dec2.check_consistency();
	bool ret = dec.is_equal(dec2);
	// We check if the two decomposition are equal
	BOOST_REQUIRE_EQUAL(ret,true);
	// check that dec and dec2 contain the same information
	// We duplicate the decomposition redefining the ghost
	Ghost<3, float> g3(0.005);
	// We duplicate the decomposition refefining the ghost
	CartDecomposition<3, float> dec3 = dec.duplicate(g3);
	ret = dec3.check_consistency();
	BOOST_REQUIRE_EQUAL(ret,true);
	// 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);
Pietro Incardona's avatar
Pietro Incardona committed

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

BOOST_AUTO_TEST_CASE( CartDecomposition_ext_non_periodic_test)
{
	// Vcluster
	Vcluster & vcl = *global_v_cluster;

	// Initialize the global VCluster
	init_global_v_cluster(&boost::unit_test::framework::master_test_suite().argc,&boost::unit_test::framework::master_test_suite().argv);

	//! [Create CartDecomposition]
	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
	CartDecomposition_ext<3,float> dec_ext(vcl);

	dec_ext.setParameters(dec,g,box_ext);
Pietro Incardona's avatar
Pietro Incardona committed

	//! [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();

	BOOST_REQUIRE_CLOSE(volume,1.728,0.0001);
Pietro Incardona's avatar
Pietro Incardona committed

	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();

	if (vcl.getProcessingUnits() > 1)
	{
		BOOST_REQUIRE(volume_ge > volume_g*1.05);
	}
Pietro Incardona's avatar
Pietro Incardona committed

	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();

	if (vcl.getProcessingUnits() > 1)
	{
		BOOST_REQUIRE(volume_ge > volume_g*1.05);
	}
Pietro Incardona's avatar
Pietro Incardona committed
BOOST_AUTO_TEST_SUITE_END()

#endif