| 1 | /* | 
| 2 |  * vector_dist_performance_common.hpp | 
| 3 |  * | 
| 4 |  *  Created on: Dec 25, 2016 | 
| 5 |  *      Author: i-bird | 
| 6 |  */ | 
| 7 |  | 
| 8 | #ifndef SRC_VECTOR_PERFORMANCE_VECTOR_DIST_PERFORMANCE_COMMON_HPP_ | 
| 9 | #define SRC_VECTOR_PERFORMANCE_VECTOR_DIST_PERFORMANCE_COMMON_HPP_ | 
| 10 |  | 
| 11 | #include "Vector/vector_dist.hpp" | 
| 12 |  | 
| 13 | /*! \brief Calculate and put particles' forces | 
| 14 |  * | 
| 15 |  * \param NN Cell list | 
| 16 |  * \param vd Distributed vector | 
| 17 |  * \param r_cut Cut-off radius | 
| 18 |  */ | 
| 19 | template<unsigned int dim, size_t prp = 0, typename T, typename V> void calc_forces(T & NN, V & vd, float r_cut) | 
| 20 | { | 
| 21 | 	auto it_v = vd.getDomainIterator(); | 
| 22 |  | 
| 23 | 	float sum[dim]; | 
| 24 |  | 
| 25 | 	for (size_t i = 0; i < dim; i++) | 
| 26 | 		sum[i] = 0; | 
| 27 |  | 
| 28 | 	while (it_v.isNext()) | 
| 29 | 	{ | 
| 30 | 		//key | 
| 31 | 		vect_dist_key_dx key = it_v.get(); | 
| 32 |  | 
| 33 |     	// Get the position of the particles | 
| 34 | 		Point<dim,float> p = vd.getPos(key); | 
| 35 |  | 
| 36 | 		for (size_t i = 0; i < dim; i++) | 
| 37 | 			sum[i] = 0; | 
| 38 |  | 
| 39 |     	// Get the neighborhood of the particle | 
| 40 |     	auto cell_it = NN.template getNNIterator<NO_CHECK>(NN.getCell(p)); | 
| 41 |  | 
| 42 |     	while(cell_it.isNext()) | 
| 43 |     	{ | 
| 44 |     		auto nnp = cell_it.get(); | 
| 45 |  | 
| 46 |     		// p != q | 
| 47 |     		if (nnp == key.getKey()) | 
| 48 |     		{ | 
| 49 |     			++cell_it; | 
| 50 |     			continue; | 
| 51 |     		} | 
| 52 |  | 
| 53 |     		Point<dim,float> q = vd.getPos(nnp); | 
| 54 |  | 
| 55 |     		if (p.distance2(q) < r_cut*r_cut) | 
| 56 |     		{ | 
| 57 | 				//Calculate the forces | 
| 58 |     			float num[dim]; | 
| 59 |     			for (size_t i = 0; i < dim; i++) | 
| 60 |     				num[i] = vd.getPos(key)[i] - vd.getPos(nnp)[i]; | 
| 61 |  | 
| 62 |     			float denom = 0; | 
| 63 |     			for (size_t i = 0; i < dim; i++) | 
| 64 | 					denom += num[i] * num[i]; | 
| 65 |  | 
| 66 |     			float res[dim]; | 
| 67 |     			for (size_t i = 0; i < dim; i++) | 
| 68 | 					res[i] = num[i] / denom; | 
| 69 |  | 
| 70 |     			for (size_t i = 0; i < dim; i++) | 
| 71 | 					sum[i] += res[i]; | 
| 72 |     		} | 
| 73 | 			//Next particle in a cell | 
| 74 | 			++cell_it; | 
| 75 | 		} | 
| 76 |  | 
| 77 | 		//Put the forces | 
| 78 | 		for (size_t i = 0; i < dim; i++) | 
| 79 | 			vd.template getProp<prp>(key)[i] += sum[i]; | 
| 80 |  | 
| 81 | 		//Next particle in cell list | 
| 82 | 		++it_v; | 
| 83 | 	} | 
| 84 | } | 
| 85 |  | 
| 86 | /*! \brief For each particle of vd calculate the accumulation of the distances of the neighborhood | 
| 87 |  *          particles inside vd2 | 
| 88 |  * | 
| 89 |  * | 
| 90 |  * \param NN Cell list vd | 
| 91 |  * \param NN2 Cell list vd2 | 
| 92 |  * \param vd Distributed vector | 
| 93 |  * \param vd2 Distributed vector 2 | 
| 94 |  * \param r_cut Cut-off radius | 
| 95 |  * | 
| 96 |  */ | 
| 97 | template<unsigned int dim, unsigned int prp, typename T, typename V> void cross_calc(T & NN, T & NN2, V & vd, V & vd2) | 
| 98 | { | 
| 99 | 	auto it_v = vd.getDomainIterator(); | 
| 100 |  | 
| 101 | 	while (it_v.isNext()) | 
| 102 | 	{ | 
| 103 | 		//key | 
| 104 | 		vect_dist_key_dx key = it_v.get(); | 
| 105 |  | 
| 106 |     	// Get the position of the particles | 
| 107 | 		Point<dim,float> p = vd.getPos(key); | 
| 108 |  | 
| 109 |     	// Get the neighborhood of the particle | 
| 110 |     	auto cell_it = NN2.template getNNIterator<NO_CHECK>(NN2.getCell(p)); | 
| 111 |  | 
| 112 |     	double sum = 0.0; | 
| 113 |  | 
| 114 |     	while(cell_it.isNext()) | 
| 115 |     	{ | 
| 116 |     		auto nnp = cell_it.get(); | 
| 117 |  | 
| 118 |     		Point<dim,float> q = vd2.getPos(nnp); | 
| 119 |  | 
| 120 |     		sum += norm(p - q); | 
| 121 |  | 
| 122 | 			//Next particle in a cell | 
| 123 | 			++cell_it; | 
| 124 | 		} | 
| 125 |  | 
| 126 | 		vd.template getProp<prp>(key) = sum; | 
| 127 |  | 
| 128 | 		//Next particle in cell list | 
| 129 | 		++it_v; | 
| 130 | 	} | 
| 131 | } | 
| 132 |  | 
| 133 | /*! \brief Initialize a distributed vector | 
| 134 |  * | 
| 135 |  * \param vd Distributed vector | 
| 136 |  */ | 
| 137 | template<unsigned int dim, typename v_dist> | 
| 138 | void vd_initialize(v_dist & vd, Vcluster<HeapMemory> & v_cl) | 
| 139 | { | 
| 140 | 	// The random generator engine | 
| 141 | 	std::default_random_engine eg(v_cl.getProcessUnitID()*4313); | 
| 142 | 	std::uniform_real_distribution<float> ud(0.0f, 1.0f); | 
| 143 |  | 
| 144 | 	//! [Create a vector of random elements on each processor 2D] | 
| 145 |  | 
| 146 | 	auto it = vd.getIterator(); | 
| 147 |  | 
| 148 | 	while (it.isNext()) | 
| 149 | 	{ | 
| 150 | 		auto key = it.get(); | 
| 151 |  | 
| 152 | 		for (size_t i = 0; i < dim; i++) | 
| 153 | 		{vd.getPos(key)[i] = ud(eg);} | 
| 154 |  | 
| 155 | 		++it; | 
| 156 | 	} | 
| 157 |  | 
| 158 | 	vd.map(); | 
| 159 | } | 
| 160 |  | 
| 161 | /*! \brief Initialize a distributed vector | 
| 162 |  * | 
| 163 |  * \param vd Distributed vector | 
| 164 |  * \param box where to initialize | 
| 165 |  * \param npart number of particles to add | 
| 166 |  * | 
| 167 |  */ | 
| 168 | template<unsigned int dim, typename v_dist> | 
| 169 | void vd_initialize_box_nomap(v_dist & vd, const Box<dim,typename v_dist::stype> & box, Vcluster<HeapMemory> & v_cl,int start, int stop) | 
| 170 | { | 
| 171 | 	// The random generator engine | 
| 172 | 	std::default_random_engine eg(v_cl.getProcessUnitID()*4313); | 
| 173 | 	std::uniform_real_distribution<float> ud(0.0f, 1.0f); | 
| 174 |  | 
| 175 | 	auto it = vd.getIterator(start,stop); | 
| 176 |  | 
| 177 | 	while (it.isNext()) | 
| 178 | 	{ | 
| 179 | 		auto key = it.get(); | 
| 180 |  | 
| 181 | 		for (size_t i = 0; i < dim; i++) | 
| 182 | 		{vd.getPos(key)[i] = (box.getHigh(i) - box.getLow(i))*ud(eg) + box.getLow(i);} | 
| 183 |  | 
| 184 | 		++it; | 
| 185 | 	} | 
| 186 | } | 
| 187 |  | 
| 188 |  | 
| 189 | /*! \brief Initialize 2 distributed vectors with equally positioned particles | 
| 190 |  * | 
| 191 |  * \param vd, vd2 Distributed vectors | 
| 192 |  * \param v_cl Global vcluster | 
| 193 |  * \param k_int Number of particles | 
| 194 |  */ | 
| 195 | template<unsigned int dim, typename v_dist> void vd_initialize_double(v_dist & vd,v_dist & vd2, Vcluster<> & v_cl, size_t k_int) | 
| 196 | { | 
| 197 | 	// The random generator engine | 
| 198 | 	std::default_random_engine eg(v_cl.getProcessUnitID()*4313); | 
| 199 | 	std::uniform_real_distribution<float> ud(0.0f, 1.0f); | 
| 200 |  | 
| 201 | 	//! [Create a vector of random elements on each processor 2D] | 
| 202 |  | 
| 203 | 	auto it = vd.getIterator(); | 
| 204 |  | 
| 205 | 	while (it.isNext()) | 
| 206 | 	{ | 
| 207 | 		auto key = it.get(); | 
| 208 |  | 
| 209 | 		for (size_t i = 0; i < dim; i++) | 
| 210 | 		{ | 
| 211 | 			vd.getPos(key)[i] = ud(eg); | 
| 212 | 			vd2.getPos(key)[i] = vd.getPos(key)[i]; | 
| 213 | 		} | 
| 214 |  | 
| 215 | 		++it; | 
| 216 | 	} | 
| 217 |  | 
| 218 | 	vd.map(); | 
| 219 | 	vd2.map(); | 
| 220 | } | 
| 221 |  | 
| 222 |  | 
| 223 |  | 
| 224 | /*! \brief Calculate and put particles' forces | 
| 225 |  * | 
| 226 |  * \param NN Cell list hilbert | 
| 227 |  * \param vd Distributed vector | 
| 228 |  * \param r_cut Cut-off radius | 
| 229 |  */ | 
| 230 | template<unsigned int dim, size_t prp = 0, typename T, typename V> void calc_forces_hilb(T & NN, V & vd, float r_cut) | 
| 231 | { | 
| 232 | 	auto it_cl = NN.getIterator(); | 
| 233 |  | 
| 234 | 	float sum[dim]; | 
| 235 |  | 
| 236 | 	for (size_t i = 0; i < dim; i++) | 
| 237 | 		sum[i] = 0; | 
| 238 |  | 
| 239 | 	while (it_cl.isNext()) | 
| 240 | 	{ | 
| 241 | 		//key | 
| 242 | 		auto key = it_cl.get(); | 
| 243 |  | 
| 244 |     	// Get the position of the particles | 
| 245 | 		Point<dim,float> p = vd.getPos(key); | 
| 246 |  | 
| 247 | 		for (size_t i = 0; i < dim; i++) | 
| 248 | 			sum[i] = 0; | 
| 249 |  | 
| 250 |     	// Get the neighborhood of the particle | 
| 251 |     	auto cell_it = NN.template getNNIterator<NO_CHECK>(NN.getCell(p)); | 
| 252 |  | 
| 253 |     	while(cell_it.isNext()) | 
| 254 |     	{ | 
| 255 |     		auto nnp = cell_it.get(); | 
| 256 |  | 
| 257 |     		// p != q | 
| 258 |     		if (nnp == key) | 
| 259 |     		{ | 
| 260 |     			++cell_it; | 
| 261 |     			continue; | 
| 262 |     		} | 
| 263 |  | 
| 264 |     		Point<dim,float> q = vd.getPos(nnp); | 
| 265 |  | 
| 266 |     		if (p.distance2(q) < r_cut*r_cut) | 
| 267 |     		{ | 
| 268 | 				//Calculate the forces | 
| 269 |     			float num[dim]; | 
| 270 |     			for (size_t i = 0; i < dim; i++) | 
| 271 |     				num[i] = vd.getPos(key)[i] - vd.getPos(nnp)[i]; | 
| 272 |  | 
| 273 |     			float denom = 0; | 
| 274 |     			for (size_t i = 0; i < dim; i++) | 
| 275 | 					denom += num[i] * num[i]; | 
| 276 |  | 
| 277 |     			float res[dim]; | 
| 278 |     			for (size_t i = 0; i < dim; i++) | 
| 279 | 					res[i] = num[i] / denom; | 
| 280 |  | 
| 281 |     			for (size_t i = 0; i < dim; i++) | 
| 282 | 					sum[i] += res[i]; | 
| 283 |     		} | 
| 284 | 			//Next particle in a cell | 
| 285 | 			++cell_it; | 
| 286 | 		} | 
| 287 |  | 
| 288 | 		//Put the forces | 
| 289 | 		for (size_t i = 0; i < dim; i++) | 
| 290 | 			vd.template getProp<prp>(key)[i] += sum[i]; | 
| 291 |  | 
| 292 | 		//Next particle in cell list | 
| 293 | 		++it_cl; | 
| 294 | 	} | 
| 295 | } | 
| 296 |  | 
| 297 | #endif /* SRC_VECTOR_PERFORMANCE_VECTOR_DIST_PERFORMANCE_COMMON_HPP_ */ | 
| 298 |  |