main.cpp 3.92 KB
Newer Older
incardon's avatar
incardon committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#include "Vector/vector_dist.hpp"
#include "Decomposition/CartDecomposition.hpp"

/*
 * ### WIKI 1 ###
 *
 * ## Simple example
 * 
 * This example show several basic functionalities of the distributed vector
 * 
 * ### WIKI END ###
 * 
 */

15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
/*
 * ### WIKI 2 ###
 *
 * We define a particle structure it contain 4 scalars one vector with 3 components
 * and a tensor of rank 2 3x3
 *
 * ### WIKI END ###
 *
 */

template<typename T> class Particle
{
public:

	typedef boost::fusion::vector<T,T,T,T,T[3],T[3][3]> type;

	type data;

	static const unsigned int x = 0;
	static const unsigned int y = 1;
	static const unsigned int z = 2;
	static const unsigned int s = 3;
	static const unsigned int v = 4;
	static const unsigned int t = 5;
	static const unsigned int max_prop = 6;
};
incardon's avatar
incardon committed
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 81 82

int main(int argc, char* argv[])
{
	//
	// ### WIKI 2 ###
	//
	// Here we Initialize the library, than we create a uniform random generator between 0 and 1 to to generate particles
	// randomly in the domain, we create a Box that define our domain
	//
	init_global_v_cluster(&argc,&argv);
	Vcluster & v_cl = *global_v_cluster;
	
	typedef Point<2,float> s;

	// set the seed
	// create the random generator engine
	std::srand(v_cl.getProcessUnitID());
	std::default_random_engine eg;
	std::uniform_real_distribution<float> ud(0.0f, 1.0f);

	Box<2,float> box({0.0,0.0},{1.0,1.0});
	
	//
	// ### WIKI 3 ###
	//
	// Here we are creating a distributed vector defined by the following parameters
	// 
	// * Dimensionality of the space where the objects live 2D (1° template parameters)
	// * Type of the space, float (2° template parameters)
	// * Information stored by each object (3* template parameters), in this case a Point_test store 4 scalars
	//   1 vector and an asymmetric tensor of rank 2
	// * Strategy used to decompose the space
	// 
	// Constructor instead require:
	//
	// * Number of particles 4096 in this case
	// * Domain where is defined this structure
	//
	// The following construct a vector where each processor has 4096 / N_proc (N_proc = number of processor)
	// objects with an undefined position in space. This non-space decomposition is also called data-driven
	// decomposition
	//
83
	vector_dist<2,float, Particle<float>, CartDecomposition<2,float> > vd(4096,box);
incardon's avatar
incardon committed
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145

	//
	// ### WIKI 5 ###
	//
	// Get an iterator that go throught the objects, in an undefined position state and define its position
	//
	auto it = vd.getIterator();

	while (it.isNext())
	{
		auto key = it.get();

		vd.template getPos<s::x>(key)[0] = ud(eg);
		vd.template getPos<s::x>(key)[1] = ud(eg);

		++it;
	}

	//
	// ### WIKI 6 ###
	//
	// Once we define the position, we distribute them according to the default decomposition
	// The default decomposition is created even before assigning the position to the object
	// (This will probably change in future)
	//
	vd.map();

	//
	// ### WIKI 7 ###
	//
	// We get the object that store the decomposition, than we iterate again across all the objects, we count them
	// and we confirm that all the particles are local
	//
	size_t cnt = 0;
	auto & ct = vd.getDecomposition();
	it = vd.getIterator();

	while (it.isNext())
	{
		auto key = it.get();

		
		if (ct.isLocal(vd.template getPos<s::x>(key)) == false)
			std::cerr << "Error particle is not local" << "\n";

		cnt++;

		++it;
	}

	//
	// ### WIKI 8 ###
	//
	// cnt contain the number of object the local processor contain, if we are interested to count the total number across the processor
	// we can use the function add, to sum across processors. First we have to get an instance of Vcluster, queue an operation of add with
	// the variable count and finaly execute. All the operations are asynchronous, execute work like a barrier and ensure that all the 
	// queued operations are executed
	//
	v_cl.sum(cnt);
	v_cl.execute();
	
	//
146 147 148 149 150 151 152 153 154
	// ### WIKI 9 ###
	//
	// Output the particle position for each processor
	//

	vd.write("output");

	//
	// ### WIKI 10 ###
incardon's avatar
incardon committed
155 156 157
	//
	// Deinitialize the library
	//
incardon's avatar
incardon committed
158
	delete_global_v_cluster();
incardon's avatar
incardon committed
159
}