main.cpp 10.1 KB
Newer Older
incardon's avatar
incardon committed
1
#include "Grid/grid_dist_id.hpp"
2
#include "data_type/aggregate.hpp"
incardon's avatar
incardon committed
3

Pietro Incardona's avatar
Pietro Incardona committed
4
5
6
/*! \page grid Grid
 *
 * \subpage grid_0_simple
incardon's avatar
incardon committed
7
 * \subpage grid_1_save_load
Pietro Incardona's avatar
Pietro Incardona committed
8
9
 * \subpage Grid_1_stencil
 * \subpage Grid_2_solve_eq
Pietro Incardona's avatar
Pietro Incardona committed
10
 * \subpage Grid_3_gs
incardon's avatar
incardon committed
11
 * \subpage Grid_3_gs_3D
incardon's avatar
incardon committed
12
13
14
 *
 */

incardon's avatar
incardon committed
15
/*! \page grid_0_simple Simple usage
Pietro Incardona's avatar
Pietro Incardona committed
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

  [TOC]

  # Simple grid example # {#simple_grid_example}

  This example show several basic functionalities of the distributed grid

\htmlonly
<a href="#" onclick="if (document.getElementById('grid-video-1').style.display == 'none') {document.getElementById('grid-video-1').style.display = 'block'} else {document.getElementById('grid-video-1').style.display = 'none'}" >Video</a>
<div style="display:none" id="grid-video-1">
<video id="vid1" width="1200" height="576" controls> <source src="http://ppmcore.mpi-cbg.de/upload/video/Lesson1-1.mp4" type="video/mp4"></video><script>document.getElementById('vid1').addEventListener('loadedmetadata', function() {this.currentTime = 236;}, false);</script>
</div>
\endhtmlonly

*/
incardon's avatar
incardon committed
31
32
33

int main(int argc, char* argv[])
{
incardon's avatar
incardon committed
34
	/*! \page grid_0_simple Simple usage
Pietro Incardona's avatar
Pietro Incardona committed
35
36
37
38
39
40
41
42
43
44
45
46
	 *
	 * ## Initialization ## {#e0_s_initialization}
	 *
	 * Here we:
	 * * Initialize the library
	 * * Create A 3D box that define our the domain
	 * * an array of 3 unsigned integer that will define the size of the grid on each dimensions
	 * * A Ghost object that will define the extension of the ghost part in physical units
	 *
	 * \snippet Grid/0_simple/main.cpp initialization
	 *
	 */
incardon's avatar
incardon committed
47
	
Pietro Incardona's avatar
Pietro Incardona committed
48
49
50
51
52
53
	//! \cond [initialization] \endcond

	// Initialize the library
	openfpm_init(&argc,&argv);

	// 3D physical domain
incardon's avatar
incardon committed
54
55
	Box<3,float> domain({0.0,0.0,0.0},{1.0,1.0,1.0});
	
Pietro Incardona's avatar
Pietro Incardona committed
56
57
58
59
	// Grid size on eaxh dimension
	size_t sz[3] = {100,100,100};

	// Ghost part
incardon's avatar
incardon committed
60
	Ghost<3,float> g(0.1);
incardon's avatar
incardon committed
61
	
Pietro Incardona's avatar
Pietro Incardona committed
62
63
	//! \cond [initialization] \endcond

incardon's avatar
incardon committed
64
	/*! \page grid_0_simple Simple usage
Pietro Incardona's avatar
Pietro Incardona committed
65
66
67
	 *
	 * ## Grid instantiation ## {#e0_s_grid_inst}
	 *
incardon's avatar
incardon committed
68
	 * Here we are creating a distributed grid defined by the following parameters
Pietro Incardona's avatar
Pietro Incardona committed
69
70
	 *
	 * * 3 dimensionality of the grid
incardon's avatar
incardon committed
71
	 * * float type used for the spatial coordinates
Pietro Incardona's avatar
Pietro Incardona committed
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
	 * * each grid point contain a vector of dimension 3 (float[3]),
	 * * float[3] is the information stored by each grid point a float[3]
	 *   the list of properties must be put into an aggregate data structure aggregate<prop1,prop2,prop3, ... >
	 *
	 * Constructor parameters:
	 *
	 * * sz: size of the grid on each dimension
	 * * domain: where the grid is defined
	 * * g: ghost extension
	 *
	 * \snippet Grid/0_simple/main.cpp grid instantiation
	 *
	 */

	//! \cond [grid instantiation] \endcond

88
	grid_dist_id<3, float, aggregate<float[3]>> g_dist(sz,domain,g);
incardon's avatar
incardon committed
89
	
Pietro Incardona's avatar
Pietro Incardona committed
90
91
92
	//! \cond [grid instantiation] \endcond

	/*!
incardon's avatar
incardon committed
93
	 * \page grid_0_simple Simple usage
Pietro Incardona's avatar
Pietro Incardona committed
94
95
96
97
	 *
	 * ## Loop over grid points ## {#e0_s_loop_gp}
	 *
	 * Get an iterator that go through all the grid points. In this
incardon's avatar
incardon committed
98
	 * example we use iterators. Iterators are convenient way to explore/iterate data-structures.
Pietro Incardona's avatar
Pietro Incardona committed
99
100
101
102
103
104
105
	 *
	 *  \snippet Grid/0_simple/main.cpp get iterator
	 *  \snippet Grid/0_simple/main.cpp get iterator2
	 *
	 */

	//! \cond [get iterator] \endcond
incardon's avatar
incardon committed
106

Pietro Incardona's avatar
Pietro Incardona committed
107
108
	// Get the iterator (No ghost)
	auto dom = g_dist.getDomainIterator();
incardon's avatar
incardon committed
109
	
Pietro Incardona's avatar
Pietro Incardona committed
110
	// Counter
incardon's avatar
incardon committed
111
112
	size_t count = 0;
	
Pietro Incardona's avatar
Pietro Incardona committed
113
	// Iterate over all the grid points
incardon's avatar
incardon committed
114
115
	while (dom.isNext())
	{
Pietro Incardona's avatar
Pietro Incardona committed
116
117
118
		//! \cond [get iterator] \endcond

		/*!
incardon's avatar
incardon committed
119
		 * \page grid_0_simple Simple usage
Pietro Incardona's avatar
Pietro Incardona committed
120
121
122
123
124
125
126
127
128
129
130
131
132
133
		 *
		 * ## Grid coordinates ## {#e0_s_grid_coord}
		 *
		 * Get the local grid key, one local grid key* identify one point in the grid and store the local grid coordinates of such point
		 *
		 * <sub><sup>(*)Internally a local grid store the sub-domain id (each sub-domain contain a grid) and the local grid point id identified by 2 integers in 2D 3 integer in 3D and so on. These two distinct elements are available with key.getSub() and key.getKey().</sup></sub>
		 *
		 * \snippet Grid/0_simple/main.cpp local grid
		 *
		 */

		//! \cond [local grid] \endcond

		// local grid key from iterator
incardon's avatar
incardon committed
134
135
		auto key = dom.get();
		
Pietro Incardona's avatar
Pietro Incardona committed
136
137
138
		//! \cond [local grid] \endcond

		/*!
incardon's avatar
incardon committed
139
		 * \page grid_0_simple Simple usage
Pietro Incardona's avatar
Pietro Incardona committed
140
141
142
143
144
145
146
147
		 *
		 * **Short explanation**
		 *
		 * In oder to get the real/global coordinates of the grid point we have to convert the object key with getGKey
		 *
		 */
		 /*!
		  *
incardon's avatar
incardon committed
148
		  * \page grid_0_simple Simple usage
Pietro Incardona's avatar
Pietro Incardona committed
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
		  *
		 \htmlonly <a href="#" onclick="if (document.getElementById('long-explanation-div').style.display == 'none') {document.getElementById('long-explanation-div').style.display = 'block'} else {document.getElementById('long-explanation-div').style.display = 'none'}" >Long Explanation</a> \endhtmlonly
		 *
		 *
\htmlonly
<div style="display:none" id="long-explanation-div">
<p>Even if the local grid key identify an unique point in the grid, it does not store the real/global coordinates of the points in grid units.</p>
<p>Consider this scheme</p>
<pre class="fragment">
   +-----+-----+--*--+-----+-----+-----+ (6,6)
   |              |     P1,3           |
   |     P1,1     *--------------------*
   |              |     P1,2           |
   +     +     +  |  +     +     +     +
   |              *--------------------*
   *--------------*                    |
   |              |                    |
   +     +     +  |  +     +     +     +
   |              |                    |
   |     P0,2     |      P1,0          |
   |              |                    |
   +     +     +  |  #     +     +     +
   |              |                    |
   *--------------*                    |
   |              *--------------------*
   +     +     +  |  +     +     +     +
   |              |                    |
   |   P0,0       |      P0,1          |
   |              |                    |
   +-----+-----+--*--+-----+-----+-----+
  (0,0)                               (6,0)

+,# = grid point

*--*
|  | = uderline decomposition in sub-domain
*--*

PX,Y Processor X, sub-domain Y</pre><p>The point # has</p>
<ul>
incardon's avatar
incardon committed
189
<li>Global/Real coordinates (3,2)</li>
Pietro Incardona's avatar
Pietro Incardona committed
190
191
192
193
194
195
196
<li>Local grid coordinates are Sub-domain = 0, grid position = (0,0)</li>
</ul>
<p>Here we convert the local grid coordinates, into global coordinates. key_g internally store 3 integers that identify the position of the grid point in global coordinates</p>
<p>
</div>
\endhtmlonly
*/
incardon's avatar
incardon committed
197
		/*! \page grid_0_simple Simple usage
Pietro Incardona's avatar
Pietro Incardona committed
198
199
200
201
202
203
204
		 *
		 * \snippet Grid/0_simple/main.cpp global coord
		 *
		 */

		//! \cond [global coord] \endcond

incardon's avatar
incardon committed
205
206
		auto key_g = g_dist.getGKey(key);

Pietro Incardona's avatar
Pietro Incardona committed
207
208
209
		//! \cond [global coord] \endcond

		/*!
incardon's avatar
incardon committed
210
		 * \page grid_0_simple Simple usage
Pietro Incardona's avatar
Pietro Incardona committed
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
		 *
		 * ## Assign properties ## {#grid_assign}
		 *
		 * Each grid point has a vector property we write on the vector coordinates the global coordinate of the grid point.
		 * At the same time we also count the points
		 *
		 * \snippet Grid/0_simple/main.cpp assign
		 *
		 */

		//! \cond [assign] \endcond

		g_dist.template get<0>(key)[0] = key_g.get(0);
		g_dist.template get<0>(key)[1] = key_g.get(1);
		g_dist.template get<0>(key)[2] = key_g.get(2);
incardon's avatar
incardon committed
226
227
228
229
		
		// Count the points
		count++;

Pietro Incardona's avatar
Pietro Incardona committed
230
231
232
233
		//! \cond [assign] \endcond

		//! \cond [get iterator2] \endcond

incardon's avatar
incardon committed
234
235
236
237
		// next point
		++dom;
	}

Pietro Incardona's avatar
Pietro Incardona committed
238
239
240
	//! \cond [get iterator2] \endcond

	/*!
incardon's avatar
incardon committed
241
	 * \page grid_0_simple Simple usage
Pietro Incardona's avatar
Pietro Incardona committed
242
243
244
245
246
247
248
249
250
251
252
	 *
	 * Each sub-domain has an extended part, that is materially contained in
	 * another processor. The function ghost_get guarantee (after return) that this extended part
	 * is perfectly synchronized with the other processor.
	 *
	 * \snippet Grid/0_simple/main.cpp ghost get
	 *
	 */

	//! \cond [ghost get] \endcond

incardon's avatar
incardon committed
253
254
	g_dist.template ghost_get<0>();
	
Pietro Incardona's avatar
Pietro Incardona committed
255
256
257
	//! \cond [ghost get] \endcond

	/*!
incardon's avatar
incardon committed
258
	 * \page grid_0_simple Simple usage
Pietro Incardona's avatar
Pietro Incardona committed
259
260
261
262
263
264
265
266
267
268
269
	 *
	 * count contain the number of points the local processor contain, if we are interested to count the total number across the processor
	 * we can use the function sum, to sum numbers across processors. First we have to get an instance of Vcluster, queue an operation of sum with
	 * the variable count and finally execute. All the operation are asynchronous, execute work like a barrier and ensure that all the
	 * queued operations are executed
	 *
	 * \snippet Grid/0_simple/main.cpp reduce
	 *
	 */

	//! \cond [reduce] \endcond
incardon's avatar
incardon committed
270

Pietro Incardona's avatar
Pietro Incardona committed
271
272
273
274
	// Get the VCluster object
	Vcluster & vcl = create_vcluster();

	// queue an operation of sum for the counter count
incardon's avatar
incardon committed
275
	vcl.sum(count);
Pietro Incardona's avatar
Pietro Incardona committed
276
277

	// execute the operation
incardon's avatar
incardon committed
278
279
280
281
282
283
	vcl.execute();
	
	// only master output
	if (vcl.getProcessUnitID() == 0)
	  std::cout << "Number of points: " << count << "\n";

Pietro Incardona's avatar
Pietro Incardona committed
284
285
286
	//! \cond [reduce] \endcond

	/*!
incardon's avatar
incardon committed
287
	 * \page grid_0_simple Simple usage
Pietro Incardona's avatar
Pietro Incardona committed
288
289
290
291
292
293
294
	 *
	 * ## VTK and visualization ## {#e0_s_VTK_vis}
	 *
	 * Finally we want a nice output to visualize the information stored by the distributed grid.
	 * The function write by default produce VTK files. One for each processor that can be visualized
	 * with the programs like paraview
	 *
incardon's avatar
incardon committed
295
296
297
298
	 * \htmlonly
	 * <img src="http://ppmcore.mpi-cbg.de/web/images/examples/0_simple_grid/0_simple_grid_init.jpg"/>
	 * \endhtmlonly
	 *
Pietro Incardona's avatar
Pietro Incardona committed
299
300
301
302
303
304
	 * \snippet Grid/0_simple/main.cpp write
	 *
	 */

	//! \cond [write] \endcond

incardon's avatar
incardon committed
305
306
	g_dist.write("output");
	
Pietro Incardona's avatar
Pietro Incardona committed
307
308
309
	//! \cond [write] \endcond

	/*!
incardon's avatar
incardon committed
310
	 * \page grid_0_simple Simple usage
Pietro Incardona's avatar
Pietro Incardona committed
311
312
313
314
315
316
317
318
	 *
	 * ## Decomposition ## {#grid_dec}
	 *
	 * For debugging purpose and demonstration we also output the decomposition of the
	 * space across processor. This function produce VTK files that can be visualized with Paraview
	 *
	 * \snippet Grid/0_simple/main.cpp out_dec
	 *
incardon's avatar
incardon committed
319
320
321
322
323
324
325
326
327
	 * \htmlonly
	 * <img src="http://ppmcore.mpi-cbg.de/web/images/examples/0_simple_grid/0_simple_grid_dec.jpg"/>
	 * \endhtmlonly
	 *
	 * Here we see the decomposition in 3D for 2 processors. The red box in wire-frame is the processor 0
	 * subdomain. The blu one is the processor 1 sub-domain. The red solid box is the extended part for processor 0
	 * the blu solid part is the extended part for processor 1
	 *
	 *
Pietro Incardona's avatar
Pietro Incardona committed
328
329
330
331
	 */

	//! \cond [out_dec] \endcond

incardon's avatar
incardon committed
332
	g_dist.getDecomposition().write("out_dec");
incardon's avatar
incardon committed
333
	
Pietro Incardona's avatar
Pietro Incardona committed
334
335
336
	//! \cond [out_dec] \endcond

	/*!
incardon's avatar
incardon committed
337
	 * \page grid_0_simple Simple usage
Pietro Incardona's avatar
Pietro Incardona committed
338
339
340
341
342
343
344
345
346
347
348
	 *
	 * ## Finalize ## {#finalize}
	 *
	 *  At the very end of the program we have always to de-initialize the library
	 *
	 * \snippet Vector/0_simple/main.cpp finalize
	 *
	 */

	//! \cond [finalize] \endcond

Pietro Incardona's avatar
Pietro Incardona committed
349
	openfpm_finalize();
Pietro Incardona's avatar
Pietro Incardona committed
350
351
352
353

	//! \cond [finalize] \endcond

	/*!
incardon's avatar
incardon committed
354
	 * \page grid_0_simple Simple usage
Pietro Incardona's avatar
Pietro Incardona committed
355
356
357
358
359
360
	 *
	 * # Full code # {#code}
	 *
	 * \include Grid/0_simple/main.cpp
	 *
	 */
incardon's avatar
incardon committed
361
}