main.cpp 4.5 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
/*
 * ### 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:

Pietro Incardona's avatar
Pietro Incardona committed
29
	typedef boost::fusion::vector<T,T[3],T[3][3]> type;
30 31 32

	type data;

Pietro Incardona's avatar
Pietro Incardona committed
33 34 35 36
	static const unsigned int s = 0;
	static const unsigned int v = 1;
	static const unsigned int t = 2;
	static const unsigned int max_prop = 3;
37
};
incardon's avatar
incardon committed
38 39 40 41 42 43 44

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
Pietro Incardona's avatar
Pietro Incardona committed
45
	// randomly in the domain, we create a Box that define our domain, boundary conditions, and ghost
incardon's avatar
incardon committed
46 47 48 49 50 51 52 53 54 55 56 57
	//
	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);

Pietro Incardona's avatar
Pietro Incardona committed
58 59
	Box<2,float> domain({0.0,0.0},{1.0,1.0});
    size_t bc[2]={PERIODIC,PERIODIC};
Pietro Incardona's avatar
Pietro Incardona committed
60
	Ghost<2,float> g(0.01);
incardon's avatar
incardon committed
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
	
	//
	// ### 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
	// 
	// 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
	//
81
	vector_dist<2,float, Particle<float> > vd(4096,domain,bc,g);
incardon's avatar
incardon committed
82 83 84 85

	//
	// ### WIKI 5 ###
	//
Pietro Incardona's avatar
Pietro Incardona committed
86
	// Get an iterator that go through the particles, in an undefined position state and define its position
incardon's avatar
incardon committed
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
	//
	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();

Pietro Incardona's avatar
Pietro Incardona committed
123 124
		// The template parameter is unuseful and will probably disappear
		if (ct.isLocal(vd.template getPos<0>(key)) == false)
incardon's avatar
incardon committed
125 126
			std::cerr << "Error particle is not local" << "\n";

Pietro Incardona's avatar
Pietro Incardona committed
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
		// set the all the properties to 0.0

		// scalar
		vd.template getProp<0>(key) = 0.0;

		vd.template getProp<1>(key)[0] = 0.0;
		vd.template getProp<1>(key)[1] = 0.0;
		vd.template getProp<1>(key)[2] = 0.0;

		vd.template getProp<2>(key)[0][0] = 0.0;
		vd.template getProp<2>(key)[0][1] = 0.0;
		vd.template getProp<2>(key)[0][2] = 0.0;
		vd.template getProp<2>(key)[1][0] = 0.0;
		vd.template getProp<2>(key)[1][1] = 0.0;
		vd.template getProp<2>(key)[1][2] = 0.0;
		vd.template getProp<2>(key)[2][0] = 0.0;
		vd.template getProp<2>(key)[2][1] = 0.0;
		vd.template getProp<2>(key)[2][2] = 0.0;

incardon's avatar
incardon committed
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
		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();
	
	//
163 164 165 166 167 168 169 170 171
	// ### WIKI 9 ###
	//
	// Output the particle position for each processor
	//

	vd.write("output");

	//
	// ### WIKI 10 ###
incardon's avatar
incardon committed
172 173 174
	//
	// Deinitialize the library
	//
incardon's avatar
incardon committed
175
	delete_global_v_cluster();
incardon's avatar
incardon committed
176
}