Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
grid_test_neighbors.cpp
Go to the documentation of this file.
1#include "dccrg.hpp"
2#include "mpi.h"
3#include <iostream>
4#include <fstream>
5#include <vector>
6#include <iterator>
7#include <algorithm>
8#include "../../definitions.h"
9#include "../../parameters.h"
10
11using namespace std;
12
13struct grid_data {
14
15 int value = 0;
16
17 std::tuple<void*, int, MPI_Datatype> get_mpi_datatype()
18 {
19 return std::make_tuple(this, 0, MPI_BYTE);
20 }
21
22};
23
24struct setOfPencils {
25
26 uint N; // Number of pencils in the set
28 std::vector<uint> lengthOfPencils; // Lengths of pencils
29 std::vector<CellID> ids; // List of cells
30 std::vector<Real> x,y; // x,y - position
31
33 N = 0;
34 sumOfLengths = 0;
35 }
36
37 void addPencil(std::vector<CellID> idsIn, Real xIn, Real yIn) {
38
39 N += 1;
40 sumOfLengths += idsIn.size();
41 lengthOfPencils.push_back(idsIn.size());
42 ids.insert(ids.end(),idsIn.begin(),idsIn.end());
43 x.push_back(xIn);
44 y.push_back(yIn);
45
46 }
47
48 std::vector<CellID> getIds(uint pencilId) {
49
50 if (pencilId > N) {
51 vector<CellID> foo;
52 return foo;
53 }
54
55 CellID ibeg = 0;
56 for (uint i = 0; i < pencilId; i++) {
57 ibeg += lengthOfPencils[i];
58 }
59 CellID iend = ibeg + lengthOfPencils[pencilId];
60
61 vector<CellID> idsOut;
62
63 for (uint i = ibeg; i <= iend; i++) {
64 idsOut.push_back(ids[i]);
65 }
66
67 return idsOut;
68 }
69
70};
71
72
73CellID selectNeighbor(dccrg::Dccrg<grid_data> &grid, CellID id, int dimension = 0, uint path = 0) {
74
75 vector < CellID > myNeighbors;
76 // Collect neighbor ids in the positive direction of the chosen dimension.
77 // Note that dimension indexing starts from 1 (of course it does)
78 for (const auto& [neighbor, dir] : grid.get_face_neighbors_of(id)) {
79 if (cell.second == dimension + 1)
80 myNeighbors.push_back(cell.first);
81 }
82
83 CellID neighbor;
84
85 switch( myNeighbors.size() ) {
86 // Since refinement can only increase by 1 level the only possibilities
87 // Should be 0 neighbors, 1 neighbor or 4 neighbors.
88 case 0 : {
89 // did not find neighbors
90 neighbor = INVALID_CELLID;
91 break;
92 }
93 case 1 : {
94 neighbor = myNeighbors[0];
95 break;
96 }
97 case 4 : {
98 neighbor = myNeighbors[path];
99 break;
100 }
101 default: {
102 // something is wrong
103 neighbor = INVALID_CELLID;
104 throw "Invalid neighbor count!";
105 break;
106 }
107 }
108
109 return neighbor;
110
111}
112
113setOfPencils buildPencilsWithNeighbors( dccrg::Dccrg<grid_data> &grid,
114 setOfPencils &pencils, CellID startingId,
115 vector<CellID> ids, uint dimension,
116 vector<uint> path) {
117
118 const bool debug = false;
119 CellID nextNeighbor;
120 uint id = startingId;
121 uint startingRefLvl = grid.get_refinement_level(id);
122
123 if( ids.size() == 0 )
124 ids.push_back(startingId);
125
126 // If the cell where we start is refined, we need to figure out which path
127 // to follow in future refined cells. This is a bit hacky but we have to
128 // use the order or the children of the parent cell to figure out which
129 // corner we are in.
130 // Maybe you could use physical coordinates here?
131 if( startingRefLvl > path.size() ) {
132 for ( uint i = path.size(); i < startingRefLvl; i++) {
133 auto parent = grid.mapping.get_parent(id);
134
135 std::array<uint64_t, 8> childrenarr = mpiGrid.mapping.get_all_children(parent);
136 vector<CellID> children(childrenarr.begin(), childrenarr.end());
137 auto it = std::find(children.begin(),children.end(),id);
138 auto index = std::distance(children.begin(),it);
139 auto index2 = index;
140
141 switch( dimension ) {
142 case 0: {
143 index2 = index / 2;
144 break;
145 }
146 case 1: {
147 index2 = index - index / 2;
148 break;
149 }
150 case 2: {
151 index2 = index % 4;
152 break;
153 }
154 }
155 path.insert(path.begin(),index2);
156 id = parent;
157 }
158 }
159
160 id = startingId;
161
162 while (id > 0) {
163
164 // Find the refinement level in the neighboring cell. Any neighbor will do
165 // since refinement level can only increase by 1 between neighbors.
166 nextNeighbor = selectNeighbor(grid,id,dimension);
167
168 // If there are no neighbors, we can stop.
169 if (nextNeighbor == 0)
170 break;
171
172 uint refLvl = grid.get_refinement_level(nextNeighbor);
173
174 if (refLvl > 0) {
175
176 // If we have encountered this refinement level before and stored
177 // the path this builder follows, we will just take the same path
178 // again.
179 if ( path.size() >= refLvl ) {
180
181 if(debug) {
182 std::cout << "I am cell " << id << ". ";
183 std::cout << "I have seen refinement level " << refLvl << " before. Path is ";
184 for (auto k = path.begin(); k != path.end(); ++k)
185 std::cout << *k << " ";
186 std::cout << std::endl;
187 }
188
189 nextNeighbor = selectNeighbor(grid,id,dimension,path[refLvl-1]);
190
191 } else {
192
193 if(debug) {
194 std::cout << "I am cell " << id << ". ";
195 std::cout << "I have NOT seen refinement level " << refLvl << " before. Path is ";
196 for (auto k = path.begin(); k != path.end(); ++k)
197 std::cout << *k << ' ';
198 std::cout << std::endl;
199 }
200
201 // New refinement level, create a path through each neighbor cell
202 for ( uint i : {0,1,2,3} ) {
203
204 vector < uint > myPath = path;
205 myPath.push_back(i);
206
207 nextNeighbor = selectNeighbor(grid,id,dimension,myPath.back());
208
209 if ( i == 3 ) {
210
211 // This builder continues with neighbor 3
212 ids.push_back(nextNeighbor);
213 path = myPath;
214
215 } else {
216
217 // Spawn new builders for neighbors 0,1,2
218 buildPencilsWithNeighbors(grid,pencils,id,ids,dimension,myPath);
219
220 }
221
222 }
223
224 }
225
226 } else {
227 if(debug) {
228 std::cout << "I am cell " << id << ". ";
229 std::cout << " I am on refinement level 0." << std::endl;
230 }
231 }// Closes if (refLvl == 0)
232
233 // If we found a neighbor, add it to the list of ids for this pencil.
234 if(nextNeighbor != INVALID_CELLID) {
235 if (debug) {
236 std::cout << " Next neighbor is " << nextNeighbor << "." << std::endl;
237 }
238 ids.push_back(nextNeighbor);
239 }
240
241 // Move to the next cell.
242 id = nextNeighbor;
243
244 } // Closes while loop
245
246 // Get the x,y - coordinates of the pencil (in the direction perpendicular to the pencil)
247 const auto coordinates = grid.get_center(ids[0]);
248 double x,y;
249 uint ix,iy,iz;
250 switch(dimension) {
251 case 0:
252 ix = 1;
253 iy = 2;
254 iz = 0;
255 break;
256
257 case 1:
258 ix = 2;
259 iy = 0;
260 iz = 1;
261 break;
262
263 case 2:
264 ix = 0;
265 iy = 1;
266 iz = 2;
267 break;
268
269 default:
270 ix = 0;
271 iy = 1;
272 iz = 2;
273 break;
274
275 }
276
277 x = coordinates[ix];
278 y = coordinates[iy];
279 // z = vector<Real>;
280
281 // for( auto id: ids ) {
282 // coordinates = grid.get_center(id);
283 // z.push_back(coordinates[iz])
284 // }
285
286 pencils.addPencil(ids,x,y);
287 return pencils;
288
289}
290
291
292void printVector(vector<CellID> v) {
293
294 for (auto k = v.begin(); k != v.end(); ++k)
295 std::cout << *k << ' ';
296 std::cout << "\n";
297
298}
299
300int main(int argc, char* argv[]) {
301
302 if (MPI_Init(&argc, &argv) != MPI_SUCCESS) {
303 // cerr << "Coudln't initialize MPI." << endl;
304 abort();
305 }
306
307 MPI_Comm comm = MPI_COMM_WORLD;
308
309 int rank = 0, comm_size = 0;
310 MPI_Comm_rank(comm, &rank);
311 MPI_Comm_size(comm, &comm_size);
312
313 dccrg::Dccrg<grid_data> grid;
314
315 // paremeters
316 const uint xDim = 9;
317 const uint yDim = 3;
318 const uint zDim = 1;
319 const std::array<uint64_t, 3> grid_size = {{xDim,yDim,zDim}};
320 const int dimension = 0;
321 const bool doRefine = true;
322 const std::array<uint,4> refinementIds = {{10,14,64,72}};
323
324 grid.initialize(grid_size, comm, "RANDOM", 1);
325
326 typedef dccrg::Types<3>::neighborhood_item_t neigh_t;
327 std::vector<neigh_t> neighborhood_x;
328 std::vector<neigh_t> neighborhood_y;
329
330 int neighborhood_width = 2;
331 for (int d = -neighborhood_width; d <= neighborhood_width; d++) {
332 if (d != 0) {
333 neighborhood_x.push_back({{d, 0, 0}});
334 neighborhood_y.push_back({{0, d, 0}});
335 }
336 }
337 grid.add_neighborhood(1, neighborhood_x);
338 grid.add_neighborhood(2, neighborhood_y);
339
340 grid.balance_load();
341
342 if(doRefine) {
343 for(uint i = 0; i < refinementIds.size(); i++) {
344 if(refinementIds[i] > 0) {
345 grid.refine_completely(refinementIds[i]);
346 grid.stop_refining();
347 }
348 }
349 }
350
351 grid.balance_load();
352
353 auto cells = grid.cells;
354 sort(cells.begin(), cells.end());
355
356 vector<CellID> ids;
357 vector<CellID> startingIds;
358
359 for (const auto& cell: cells) {
360 // std::cout << "Data of cell " << cell.id << " is stored at " << cell.data << std::endl;
361 // Collect a list of cell ids.
362 ids.push_back(cell.id);
363
364 // Collect a list of cell ids that do not have a neighbor in the negative direction
365 vector<CellID> negativeNeighbors;
366 for (auto neighbor : grid.get_face_neighbors_of(cell.id)) {
367
368 if (neighbor.second == - (dimension + 1))
369 negativeNeighbors.push_back(neighbor.first);
370 }
371 if (negativeNeighbors.size() == 0)
372 startingIds.push_back(cell.id);
373 }
374
375 std::cout << "Starting cell ids for pencils are ";
376 printVector(startingIds);
377
378 sort(ids.begin(),ids.end());
379
380 vector<CellID> idsInitial;
381 vector<uint> path;
382 setOfPencils pencils;
383
384 for (auto id : startingIds) {
385 pencils = buildPencilsWithNeighbors(grid,pencils,id,idsInitial,dimension,path);
386 }
387
388 uint ibeg = 0;
389 uint iend = 0;
390
391 std::cout << "I have created " << pencils.N << " pencils along dimension " << dimension << ":\n";
392 std::cout << "(x, y): indices " << std::endl;
393 std::cout << "-----------------------------------------------------------------" << std::endl;
394 for (uint i = 0; i < pencils.N; i++) {
395 iend += pencils.lengthOfPencils[i];
396 std::cout << "(" << pencils.x[i] << ", " << pencils.y[i] << "): ";
397 for (auto j = pencils.ids.begin() + ibeg; j != pencils.ids.begin() + iend; ++j) {
398 std::cout << *j << " ";
399 }
400 ibeg = iend;
401 std::cout << std::endl;
402 }
403
404
405 CellID id = 3;
406 const vector<CellID>* neighbors = grid.get_neighbors_of(id, 1);
407 if (neighbors != NULL) {
408 std::cout << "Neighbors of cell " << id << std::endl;
409 for (auto neighbor : *neighbors) {
410 std::cout << neighbor << std::endl;
411 }
412 }
413
414
415
416 std::ofstream outfile;
417
418 grid.write_vtk_file("test.vtk");
419
420 outfile.open("test.vtk", std::ofstream::app);
421 // write each cells id
422 outfile << "CELL_DATA " << cells.size() << std::endl;
423 outfile << "SCALARS id int 1" << std::endl;
424 outfile << "LOOKUP_TABLE default" << std::endl;
425 for (const auto& cell: cells) {
426 outfile << cell.id << std::endl;
427 }
428 outfile.close();
429
430 MPI_Finalize();
431
432 return 0;
433
434}
for i
Definition Dispersion.m:24
float Real
Definition definitions.h:41
uint64_t CellID
Definition definitions.h:54
const int j
const int k
setOfPencils buildPencilsWithNeighbors(dccrg::Dccrg< grid_data > &grid, setOfPencils &pencils, CellID startingId, vector< CellID > ids, uint dimension, vector< uint > path)
void printVector(vector< CellID > v)
CellID selectNeighbor(dccrg::Dccrg< grid_data > &grid, CellID id, int dimension=0, uint path=0)
#define index(i, j, k)
uint32_t uint
const uint64_t INVALID_CELLID
Definition parameters.h:35
std::tuple< void *, int, MPI_Datatype > get_mpi_datatype()
std::vector< Real > x
Definition grid_test.cpp:32
void addPencil(std::vector< CellID > idsIn, Real xIn, Real yIn)
std::vector< CellID > getIds(uint pencilId)
std::vector< Real > y
Definition grid_test.cpp:32
std::vector< CellID > ids
Definition grid_test.cpp:31
std::vector< uint > lengthOfPencils
Definition grid_test.cpp:30
int main()