Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
sort_refined_ids_recursive.py
Go to the documentation of this file.
1import numpy as np
2import pdb
3import time
4
5def findParent(id, gridSize, debug):
6
7 nIndicesInRefLvl = list()
8 for refLvl in np.arange(1,10):
9 nIndicesInRefLvl.append(gridSize * 2 ** ((refLvl - 1) * 3))
10
11 for i in np.arange(len(nIndicesInRefLvl)):
12 if id <= sum(nIndicesInRefLvl[:i+1]):
13 refLvl = i
14 break
15 if refLvl == 0:
16 if id > 0:
17 print("cell {:3d}".format(id)+" does not have a parent")
18 pass
19
20 return 0, refLvl
21
22 id2 = id - sum(nIndicesInRefLvl[:refLvl])
23 ix = (id2 - 1) % (xdim * 2 ** refLvl) + 1
24 iy = (id2 - 1) / (xdim * 2 ** refLvl) % (ydim * 2 ** refLvl) + 1
25 iz = (id2 - 1) / (xdim * 2 ** refLvl * ydim * 2 ** refLvl) + 1
26 parentId = (int(np.ceil(iz / 2.0) - 1) * xdim * 2 ** (refLvl - 1) * ydim * 2 ** (refLvl - 1) +
27 int(np.ceil(iy / 2.0) - 1) * xdim * 2 ** (refLvl - 1) +
28 int(np.ceil(ix / 2.0)) +
29 sum(nIndicesInRefLvl[:refLvl-1]))
30 if debug:
31 print("id = {:3d}".format(id)+", id2 = {:3d}".format(id2)+
32 ", col = {:2d}".format(ix)+", row = {:2d}".format(iy)+
33 ", plane = {:2d}".format(iz)+", parentId = {:2d}".format(parentId)+
34 ", refLvl = {:1d}".format(refLvl))
35 else:
36 print("cell {:3d}".format(id)+" is the child of cell {:2d}".format(parentId))
37 pass
38
39 return parentId, refLvl
40
41def getChildren(children, parentId, dimension = 0, up = True, left = True):
42
43 down = not up
44 right = not left
45
46 N = 8
47
48 myChildren = list()
49
50 # Select 2/8 children per parent according to the logical parameters up, down, left, right.
51 # The names depict sides of the four children seen when looking along the direction of the
52 # pencil.
53
54 # ---- ----
55 # / /| / /|
56 # ---- | ---- |
57 # |UU| | |LR| |
58 # |DD|/ |LR|/
59 # ---- ----
60 #
61 if dimension == 0:
62 if up and left:
63 i1 = 0
64 i2 = 1
65 if down and left:
66 i1 = 2
67 i2 = 3
68 if up and right:
69 i1 = 4
70 i2 = 5
71 if down and right:
72 i1 = 6
73 i2 = 7
74
75 if dimension == 1:
76 if up and left:
77 i1 = 0
78 i2 = 2
79 if down and left:
80 i1 = 1
81 i2 = 3
82 if up and right:
83 i1 = 4
84 i2 = 6
85 if down and right:
86 i1 = 5
87 i2 = 7
88
89 if dimension == 2:
90 if up and left:
91 i1 = 0
92 i2 = 4
93 if down and left:
94 i1 = 1
95 i2 = 5
96 if up and right:
97 i1 = 2
98 i2 = 6
99 if down and right:
100 i1 = 3
101 i2 = 7
102
103 if parentId in children.keys():
104 myChildren.extend(children[parentId][i1::N])
105 myChildren.extend(children[parentId][i2::N])
106 else:
107 # If no children were found, return the parent
108 myChildren.extend(parentId)
109
110 #print(up,left,myChildren)
111 return myChildren
112
113def buildPencils(pencils,initialPencil,idsIn,dimension = 0,path = list()):
114
115 # pencils - list of completed pencils
116 # initalPencil - list of ids that have already been added to the pencil being built
117 # idsIn - candidate cell ids to be added to the pencil being built (unless they contain refinement)
118 # dimension - dimension along which the pencils are built
119 # path - the steps (up/down, left/right) taken while building the current pencil
120
121 # Global arrays that are accessed read-only
122 # isRefined - global array that contains how many times each cell has been refined
123 # refLvls - global array that contains the refinement level of each cell
124 # children - global array that contains the children of each refined cell
125 import copy
126
127 # (Hard) Copy the input ids to a working set of ids
128 ids = copy.copy(idsIn)
129
130 # (Hard) Copy the already computed pencil to the output list
131 idsOut = copy.copy(initialPencil)
132
133 # Walk along the input pencil
134 for i,id in enumerate(ids):
135
136 i1 = i + 1
137 # Check if the current cell contains refined cells
138 if isRefined[id] > 0:
139
140 # Check if we have encountered this refinement level before and stored
141 # The path this builder followed
142 if len(path) > refLvls[id]:
143
144 # Get children using the stored path
145 myChildren = getChildren(children,id,dimension,
146 path[refLvls[id]][0],path[refLvls[id]][1])
147
148 # Add the children to the working set
149 ids[i1:i1] = myChildren
150
151 else:
152
153 # Spawn new builders to construct pencils at the new refinement level
154 for up in [True, False]:
155 for left in [True, False]:
156
157 # Store the path this builder has chosen
158 myPath = copy.copy(path)
159 myPath.append((up,left))
160
161 # Get children along my path
162 myChildren = getChildren(children,id,dimension,up,left)
163 myIds = ids[i1:]
164
165 # The current builder will continue along the bottom-right path
166 if not up and not left:
167
168 # Add the children to the working set. Next iteration of the
169 # main looop (over ids) will start on the first child
170 ids[i1:i1] = myChildren
171 path = myPath
172 #print('building pencil for'+str(ids[i1:]))
173 pass
174
175 # Other paths will spawn a new builder
176 else:
177
178 # Create a new working set by adding the remainder of the old
179 # working set to the current children.
180 myChildren.extend(myIds)
181
182 buildPencils(pencils,idsOut,myChildren,dimension,myPath)
183
184 # Add unrefined cells to the pencil directly
185 else:
186
187 idsOut.append(id)
188
189 pass
190
191 pencils.append(idsOut)
192 return pencils
193
194 #print(idsOut)
195 #print(pencils)
196
197import argparse
198
199parser = argparse.ArgumentParser(description='Create pencils on a refined grid.')
200parser.add_argument('--dimension', metavar = 'N', type=int, nargs=1,
201 default=[0], help='Dimension (x = 0, y = 1, z = 2)')
202parser.add_argument('--filename', metavar = 'fn', type=str, nargs=1,
203 default=['test.vtk'], help='Input vtk file name')
204parser.add_argument('--debug', metavar = 'd', type=int, nargs=1,
205 default=[0], help='Debug printouts (no = 0, yes = 1)')
206args = parser.parse_args()
207
208if args.dimension[0] > 0 and args.dimension[0] <= 2:
209 dimension = args.dimension[0]
210else:
211 dimension = 0
212
213debug = bool(args.debug[0])
214
215#filename = 'test.vtk'
216filename = args.filename[0]
217fh = open(filename)
218lines = fh.readlines()
219fh.close()
220
221ids = list()
222
223xdim = 1
224ydim = 1
225zdim = 1
226for i,line in enumerate(lines):
227 if 'DATASET UNSTRUCTURED_GRID' in line:
228 n = int(lines[i+1].split()[1])
229 for j in np.arange(n):
230 xyz = lines[i+j+2].split()
231 xdim = max(xdim,float(xyz[0]))
232 ydim = max(ydim,float(xyz[1]))
233 zdim = max(zdim,float(xyz[2]))
234 if 'SCALARS id int' in line:
235 n = int(lines[i-1].split()[1])
236 for j in np.arange(n):
237 ids.append(int(lines[i+j+2]))
238
239xdim = int(xdim)
240ydim = int(ydim)
241zdim = int(zdim)
242
243print('grid dimensions are {:2d} x {:2d} x {:2d}'.format(xdim,ydim,zdim))
244gridSize = xdim*ydim*zdim
245
246#debug = True
247
248t1 = time.time()
249
250parents = dict()
251children = dict()
252refLvls = dict()
253hasChildren = list()
254
255for id in ids:
256
257 # Find the parent of cell id
258 parentId, refLvl = findParent(id,gridSize,debug)
259
260 parents[id] = parentId
261 refLvls[id] = refLvl
262
263 # Parents are not stored in the id array by default, let's add them
264 # For completeness
265 if not parentId in ids and parentId > 0:
266 ids.append(parentId)
267
268 # Make a list of cells that have been refined at least once
269 if parentId > 0:
270 if not parentId in hasChildren:
271 children[parentId] = list()
272 hasChildren.append(parentId)
273
274 # Make a list of children for each cell
275 children[parentId].append(id)
276
277# Sort the id and children lists, this is needed when adding cells to pencils
278# to get the order right
279for key in children.keys():
280 children[key].sort()
281ids.sort()
282
283# Second pass to count how many times each cell has been refined
284isRefined = dict()
285for id in ids:
286 isRefined[id] = 0
287 if refLvls[id] > 0:
288 parentId = parents[id]
289 while parentId is not 0:
290 isRefined[parentId] = refLvls[id] - refLvls[parentId]
291 parentId = parents[parentId]
292
293# Begin sorting, select the dimension by which we sort
294# dimension = 0
295# dimensions = ('x','y','z')
296print
297print('Building pencils along dimension {:1d}'.format(dimension))
298print
299
300#sortedIds = list()
301mapping = dict()
302for id in ids:
303 # Sort the unrefined mesh ids following Sebastians c++ code
304 if dimension == 0:
305
306 dims = (zdim, ydim, xdim)
307
308 idMapped = id
309
310 if dimension == 1:
311
312 dims = (zdim, xdim, ydim)
313
314 x_index = (id-1) % xdim
315 y_index = ((id-1) / xdim) % ydim
316 idMapped = id - (x_index + y_index * xdim) + y_index + x_index * ydim
317
318 if dimension == 2:
319
320 dims = (ydim, xdim, zdim)
321
322 x_index = (id-1) % xdim
323 y_index = ((id-1) / xdim) % ydim
324 z_index = ((id-1) / (xdim * ydim))
325 idMapped = 1 + z_index + y_index * zdim + x_index * ydim * zdim
326
327 if refLvls[id] == 0:
328 mapping[idMapped] = id
329
330# Create pencils of unrefined cells, store the level of refinement for each cell
331unrefinedPencils = list()
332for i in np.arange(dims[0]):
333 for j in np.arange(dims[1]):
334 ibeg = 1 + i * dims[2] * dims[1] + j * dims[2]
335 iend = 1 + i * dims[2] * dims[1] + (j + 1) * dims[2]
336 myIsRefined = list()
337 myIds = list()
338 for k in np.arange(ibeg,iend):
339 myIds.append(mapping[k])
340 myIsRefined.append(isRefined[mapping[k]])
341 unrefinedPencils.append({'ids' : myIds,
342 'refLvl' : myIsRefined})
343
344# Refine the unrefined pencils that contain refined cells
345
346pencils = list()
347
348# Loop over the unrefined pencils
349for unrefinedPencil in unrefinedPencils:
350
351 pencils = buildPencils(pencils,[],unrefinedPencil['ids'],dimension)
352
353t2 = time.time()
354
355print('I have created the following pencils:')
356print
357for pencil in pencils:
358 print(pencil)
359
360print
361print('Execution time was {:.4f} seconds'.format(t2-t1))
getChildren(children, parentId, dimension=0, up=True, left=True)
buildPencils(pencils, initialPencil, idsIn, dimension=0, path=list())
static ARCH_HOSTDEV VecSimple< T > max(VecSimple< T > const &l, VecSimple< T > const &r)