Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
cpu_acc_sort_blocks.cpp
Go to the documentation of this file.
1/*
2 * This file is part of Vlasiator.
3 * Copyright 2010-2016 Finnish Meteorological Institute
4 *
5 * For details of usage, see the COPYING file and read the "Rules of the Road"
6 * at http://www.physics.helsinki.fi/vlasiator/
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23
24#include <algorithm>
25#include <cmath>
26#include <utility>
27#include <vector>
28
30
31using namespace std;
32using namespace spatial_cell;
33
34// Comparator function for sorting vector of pairs
35inline bool paircomparator( const std::pair<uint, uint> & l, const std::pair<uint, uint> & r ) {
36 return l.first < r.first;
37}
38
39/*
40 This function returns a sorted list of blocks in a cell.
41
42 The sorted list is sorted according to the location, along the given dimension.
43
44*/
45// TODO unfinished documentation
46void sortBlocklistByDimension( //const spatial_cell::SpatialCell* spatial_cell,
48 const uint dimension,
49 uint* blocks,
50 std::vector<uint> & columnBlockOffsets,
51 std::vector<uint> & columnNumBlocks,
52 std::vector<uint> & setColumnOffsets,
53 std::vector<uint> & setNumColumns) {
54 //const uint nBlocks = spatial_cell->get_number_of_velocity_blocks(); // Number of blocks
55 const vmesh::LocalID nBlocks = vmesh->size();
56
57 // Copy block data to vector
58 std::vector<std::pair<vmesh::GlobalID,vmesh::GlobalID> > block_pairs;
59 block_pairs.resize( nBlocks );
60 for (vmesh::LocalID i = 0; i < nBlocks; ++i ) {
61 //const vmesh::GlobalID block = spatial_cell->get_velocity_block_global_id(i);
62 const vmesh::GlobalID block = vmesh->getGlobalID(i);
63 switch( dimension ) {
64 case 0: {
65 const vmesh::GlobalID blockId_mapped = block; // Mapping the block id to different coordinate system if dimension is not zero:
66 block_pairs[i] = std::make_pair( blockId_mapped, block );
67 }
68 break;
69 case 1: {
70 // Do operation:
71 // block = x + y*x_max + z*y_max*x_max
72 //=> block' = block - (x + y*x_max) + y + x*y_max = x + y*x_max + z*y_max*x_max - (x + y*x_max) + y + x*y_max
73 // = y + x*y_max + z*y_max*x_max
74 //const uint x_indice = block%SpatialCell::get_velocity_grid_length()[0];
75 //const uint y_indice = (block/SpatialCell::get_velocity_grid_length()[0])%SpatialCell::SpatialCell::get_velocity_grid_length()[1];
76 const vmesh::LocalID x_index = block % vmesh->getGridLength()[0];
77 const vmesh::LocalID y_index = (block / vmesh->getGridLength()[0]) % vmesh->getGridLength()[1];
78
79 // Mapping the block id to different coordinate system if dimension is not zero:
80 //const uint blockId_mapped
81 // = block - (x_indice + y_indice*SpatialCell::get_velocity_grid_length()[0])
82 // + y_indice
83 // + x_indice * SpatialCell::SpatialCell::get_velocity_grid_length()[1];
84 const vmesh::GlobalID blockId_mapped
85 = block - (x_index + y_index*vmesh->getGridLength()[0])
86 + y_index
87 + x_index * vmesh->getGridLength()[1];
88 block_pairs[i] = std::make_pair( blockId_mapped, block );
89 }
90 break;
91 case 2: {
92 // Do operation:
93 // block = x + y*x_max + z*y_max*x_max
94 //=> block' = z + y*z_max + x*z_max*y_max
95 //const uint x_indice = block%SpatialCell::get_velocity_grid_length()[0];
96 //const uint y_indice = (block/SpatialCell::get_velocity_grid_length()[0])%SpatialCell::SpatialCell::get_velocity_grid_length()[1];
97 //const uint z_indice = (block/(SpatialCell::get_velocity_grid_length()[0]*SpatialCell::SpatialCell::get_velocity_grid_length()[1]));
98 const vmesh::LocalID x_index = block % vmesh->getGridLength()[0];
99 const vmesh::LocalID y_index = (block / vmesh->getGridLength()[0]) % vmesh->getGridLength()[1];
100 const vmesh::LocalID z_index = (block / (vmesh->getGridLength()[0]*vmesh->getGridLength()[1]));
101
102 // Mapping the block id to different coordinate system if dimension is not zero:
103 //const uint blockId_mapped
104 // = z_indice
105 // + y_indice * SpatialCell::SpatialCell::get_velocity_grid_length()[2]
106 // + x_indice*SpatialCell::SpatialCell::get_velocity_grid_length()[1]*SpatialCell::SpatialCell::get_velocity_grid_length()[2];
107 const vmesh::GlobalID blockId_mapped
108 = z_index
109 + y_index*vmesh->getGridLength()[2]
110 + x_index*vmesh->getGridLength()[1]*vmesh->getGridLength()[2];
111 block_pairs[i] = std::make_pair( blockId_mapped, block );
112 }
113 break;
114 }
115 }
116 // Sort the list:
117 std::sort( block_pairs.begin(), block_pairs.end(), paircomparator );
118
119 // Put in the sorted blocks, and also compute column offsets and lengths:
120 columnBlockOffsets.push_back(0); //first offset
121 setColumnOffsets.push_back(0); //first offset
122 uint prev_column_id, prev_dimension_id;
123
124 for (vmesh::LocalID i=0; i<nBlocks; ++i) {
125 // identifies a particular column
126 vmesh::LocalID column_id = block_pairs[i].first / vmesh->getGridLength()[dimension];
127
128 // identifies a particular block in a column (along the dimension)
129 vmesh::LocalID dimension_id = block_pairs[i].first % vmesh->getGridLength()[dimension];
130
131 //sorted list
132 blocks[i] = block_pairs[i].second;
133
134 if ( i > 0 && ( column_id != prev_column_id || dimension_id != (prev_dimension_id + 1) )){
135 //encountered new column! For i=0, we already entered the correct offset (0).
136 //We also identify it as a new column if there is a break in the column (e.g., gap between two populations)
137 /*add offset where the next column will begin*/
138 columnBlockOffsets.push_back(i);
139 /*add length of the current column that now ended*/
140 columnNumBlocks.push_back(columnBlockOffsets[columnBlockOffsets.size()-1] - columnBlockOffsets[columnBlockOffsets.size()-2]);
141
142 if (column_id != prev_column_id ){
143 //encountered new set of columns, add offset to new set starting at present column
144 setColumnOffsets.push_back(columnBlockOffsets.size() - 1);
145 /*add length of the previous column set that ended*/
146 setNumColumns.push_back(setColumnOffsets[setColumnOffsets.size()-1] - setColumnOffsets[setColumnOffsets.size()-2]);
147 }
148 }
149 prev_column_id = column_id;
150 prev_dimension_id = dimension_id;
151 }
152
153 columnNumBlocks.push_back(nBlocks - columnBlockOffsets[columnBlockOffsets.size()-1]);
154 setNumColumns.push_back(columnNumBlocks.size() - setColumnOffsets[setColumnOffsets.size()-1]);
155}
for i
Definition Dispersion.m:24
bool paircomparator(const std::pair< uint, uint > &l, const std::pair< uint, uint > &r)
void sortBlocklistByDimension(const vmesh::VelocityMesh *vmesh, const uint dimension, uint *blocks, std::vector< uint > &columnBlockOffsets, std::vector< uint > &columnNumBlocks, std::vector< uint > &setColumnOffsets, std::vector< uint > &setNumColumns)
bool paircomparator(const std::pair< ID, uint > &l, const std::pair< ID, uint > &r)
uint32_t LocalID
Definition definitions.h:60
uint32_t GlobalID
Definition definitions.h:59