PyParticles3 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyparticles/__init__.py +26 -0
- pyparticles/__main__.py +7 -0
- pyparticles/animation/__init__.py +21 -0
- pyparticles/animation/animated_cli.py +53 -0
- pyparticles/animation/animated_ogl.py +691 -0
- pyparticles/animation/animated_ogl_compat.py +243 -0
- pyparticles/animation/animated_scatter.py +94 -0
- pyparticles/animation/animation.py +251 -0
- pyparticles/animation/test_animation.py +310 -0
- pyparticles/demo/__init__.py +33 -0
- pyparticles/demo/bubble.py +106 -0
- pyparticles/demo/electromagnetic_demo.py +128 -0
- pyparticles/demo/electrostatic_demo.py +126 -0
- pyparticles/demo/fountain.py +478 -0
- pyparticles/demo/gas_lennard_jones.py +87 -0
- pyparticles/demo/gravity_clusters.py +73 -0
- pyparticles/demo/solar_system.py +222 -0
- pyparticles/demo/springs.py +141 -0
- pyparticles/demo/springs_constr.py +135 -0
- pyparticles/demo/test.py +34 -0
- pyparticles/forces/__init__.py +21 -0
- pyparticles/forces/const_force.py +140 -0
- pyparticles/forces/damping.py +174 -0
- pyparticles/forces/drag.py +167 -0
- pyparticles/forces/electromagnetic.py +105 -0
- pyparticles/forces/electromagnetic_field.py +95 -0
- pyparticles/forces/electrostatic.py +72 -0
- pyparticles/forces/force.py +75 -0
- pyparticles/forces/force_constrained.py +32 -0
- pyparticles/forces/fused_const_drag.py +445 -0
- pyparticles/forces/gravity.py +345 -0
- pyparticles/forces/lennard_jones.py +74 -0
- pyparticles/forces/linear_spring.py +86 -0
- pyparticles/forces/linear_spring_constrained.py +72 -0
- pyparticles/forces/multiple_force.py +134 -0
- pyparticles/forces/pseudo_bubble.py +226 -0
- pyparticles/forces/van_der_waals_force.py +60 -0
- pyparticles/forces/vector_field_force.py +52 -0
- pyparticles/geometry/__init__.py +21 -0
- pyparticles/geometry/dist.py +24 -0
- pyparticles/geometry/intersection.py +62 -0
- pyparticles/geometry/transformations.py +387 -0
- pyparticles/main/__init__.py +21 -0
- pyparticles/main/main.py +466 -0
- pyparticles/measures/__init__.py +21 -0
- pyparticles/measures/elastic_potential_energy.py +67 -0
- pyparticles/measures/gravitational_potential_energy.py +69 -0
- pyparticles/measures/kinetic_energy.py +68 -0
- pyparticles/measures/mass.py +59 -0
- pyparticles/measures/measure.py +156 -0
- pyparticles/measures/momentum.py +144 -0
- pyparticles/measures/total_energy.py +68 -0
- pyparticles/ode/__init__.py +21 -0
- pyparticles/ode/euler_solver.py +214 -0
- pyparticles/ode/euler_solver_constrained.py +49 -0
- pyparticles/ode/leapfrog_solver.py +37 -0
- pyparticles/ode/leapfrog_solver_constrained.py +53 -0
- pyparticles/ode/midpoint_solver.py +43 -0
- pyparticles/ode/midpoint_solver_constrained.py +60 -0
- pyparticles/ode/ode_solver.py +134 -0
- pyparticles/ode/ode_solver_constrained.py +43 -0
- pyparticles/ode/runge_kutta_solver.py +79 -0
- pyparticles/ode/runge_kutta_solver_constrained.py +98 -0
- pyparticles/ode/sim_time.py +56 -0
- pyparticles/ode/stormer_verlet_solver.py +50 -0
- pyparticles/ode/stormer_verlet_solver_constrained.py +73 -0
- pyparticles/ogl/__init__.py +21 -0
- pyparticles/ogl/axis_ogl.py +210 -0
- pyparticles/ogl/draw_particles_ogl.py +313 -0
- pyparticles/ogl/draw_particles_ogl_compat.py +509 -0
- pyparticles/ogl/draw_vector_field.py +221 -0
- pyparticles/ogl/opencl_gl_vbo.py +485 -0
- pyparticles/ogl/trackball.py +131 -0
- pyparticles/ogl/translate_scene.py +87 -0
- pyparticles/pset/__init__.py +21 -0
- pyparticles/pset/boundary.py +69 -0
- pyparticles/pset/cluster.py +28 -0
- pyparticles/pset/constrained_force_interactions.py +63 -0
- pyparticles/pset/constrained_x.py +158 -0
- pyparticles/pset/constraint.py +42 -0
- pyparticles/pset/default_boundary.py +43 -0
- pyparticles/pset/file_cluster.py +131 -0
- pyparticles/pset/logger.py +152 -0
- pyparticles/pset/octree.py +451 -0
- pyparticles/pset/opencl_context.py +374 -0
- pyparticles/pset/particles_set.py +499 -0
- pyparticles/pset/periodic_boundary.py +36 -0
- pyparticles/pset/rand_cluster.py +188 -0
- pyparticles/pset/rebound_boundary.py +68 -0
- pyparticles/utils/__init__.py +21 -0
- pyparticles/utils/parse_args.py +72 -0
- pyparticles/utils/problem_config.py +608 -0
- pyparticles/utils/pypart_global.py +122 -0
- pyparticles/utils/time_formatter.py +50 -0
- pyparticles3-0.4.0.dist-info/METADATA +395 -0
- pyparticles3-0.4.0.dist-info/RECORD +100 -0
- pyparticles3-0.4.0.dist-info/WHEEL +5 -0
- pyparticles3-0.4.0.dist-info/entry_points.txt +3 -0
- pyparticles3-0.4.0.dist-info/licenses/LICENSE-gpl-3.0.txt +674 -0
- pyparticles3-0.4.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
# PyParticles : Particles simulation in python
|
|
2
|
+
# Copyright (C) 2012 Simone Riva simone.rva {at} gmail {dot} com
|
|
3
|
+
#
|
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
# (at your option) any later version.
|
|
8
|
+
#
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU General Public License
|
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
|
|
17
|
+
import pyparticles.pset.particles_set as ps
|
|
18
|
+
from pyparticles.geometry.intersection import box_intersects_sphere
|
|
19
|
+
from pyparticles.geometry.dist import distance
|
|
20
|
+
|
|
21
|
+
import multiprocessing as mpr
|
|
22
|
+
|
|
23
|
+
import numpy as np
|
|
24
|
+
|
|
25
|
+
from collections import deque
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class TreeElement( object ):
|
|
29
|
+
"""
|
|
30
|
+
The element of a tree node
|
|
31
|
+
"""
|
|
32
|
+
def __init__( self ):
|
|
33
|
+
|
|
34
|
+
self.__particle = None
|
|
35
|
+
|
|
36
|
+
self.__ref_vertex = np.zeros((3))
|
|
37
|
+
self.__edge_len = 0.0
|
|
38
|
+
|
|
39
|
+
self.__M = 0.0
|
|
40
|
+
self.__centre_of_mass = np.zeros((3))
|
|
41
|
+
|
|
42
|
+
self.__part_cnt = 0
|
|
43
|
+
|
|
44
|
+
self.__tree = None
|
|
45
|
+
|
|
46
|
+
self.__left = np.int8( np.array([ 1 , 0 , 0 , 1 , 1 , 0 , 0 , 1 ]) )
|
|
47
|
+
self.__right = np.int8( np.array([ 0 , 1 , 1 , 0 , 0 , 1 , 1 , 0 ]) )
|
|
48
|
+
|
|
49
|
+
self.__near = np.int8( np.array([ 1 , 1 , 0 , 0 , 1 , 1 , 0 , 0 ]) )
|
|
50
|
+
self.__far = np.int8( np.array([ 0 , 0 , 1 , 1 , 0 , 0 , 1 , 1 ]) )
|
|
51
|
+
|
|
52
|
+
self.__up = np.int8( np.array([ 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 ]) )
|
|
53
|
+
self.__down = np.int8( np.array([ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 ]) )
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def get_particle( self ) :
|
|
58
|
+
return self.__particle
|
|
59
|
+
|
|
60
|
+
particle = property( get_particle , doc="Get the particle index of the tree element" )
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def get_min_vertex( self ):
|
|
64
|
+
return self.__ref_vertex
|
|
65
|
+
|
|
66
|
+
min_vertex = property( get_min_vertex , doc="get the minimal vertex of the cube" )
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def get_max_vertex( self ):
|
|
70
|
+
return self.__ref_vertex + np.array( [ self.__edge_len , self.__edge_len , self.__edge_len ] )
|
|
71
|
+
|
|
72
|
+
max_vertex = property( get_max_vertex , doc="get the maximal vertex of the cube" )
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def getM(self):
|
|
76
|
+
return self.__M
|
|
77
|
+
|
|
78
|
+
M = property( getM , doc="getter: return the total mass of the current element ")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def get_centre_of_mass( self ):
|
|
82
|
+
return self.__centre_of_mass
|
|
83
|
+
|
|
84
|
+
centre_of_mass = property( get_centre_of_mass , doc="return the centre of mass of the particle" )
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def set_local_boundary( self , ref_vertex , edge_len ) :
|
|
88
|
+
self.__ref_vertex[:] = ref_vertex
|
|
89
|
+
self.__edge_len = edge_len
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def add_sub_trees( self ):
|
|
93
|
+
self.__tree = list( TreeElement() for i in range(8) )
|
|
94
|
+
|
|
95
|
+
## I - I
|
|
96
|
+
self.__tree[0].set_local_boundary( self.__ref_vertex , self.__edge_len / 2.0 )
|
|
97
|
+
|
|
98
|
+
d = np.array([ self.right[0] , 0.0 , 0.0 ]) * self.__edge_len
|
|
99
|
+
self.__tree[1].set_local_boundary( self.__ref_vertex + d , self.__edge_len / 2.0 )
|
|
100
|
+
|
|
101
|
+
d = np.array([ self.right[0] , self.far[0] , 0.0 ]) * self.__edge_len
|
|
102
|
+
self.__tree[2].set_local_boundary( self.__ref_vertex + d , self.__edge_len / 2.0 )
|
|
103
|
+
|
|
104
|
+
d = np.array([ self.left[0] , self.far[0] , 0.0 ]) * self.__edge_len
|
|
105
|
+
self.__tree[3].set_local_boundary( self.__ref_vertex + d , self.__edge_len / 2.0 )
|
|
106
|
+
|
|
107
|
+
## II
|
|
108
|
+
d = np.array([ self.left[0] , self.near[0] , self.up[0] ]) * self.__edge_len
|
|
109
|
+
self.__tree[4].set_local_boundary( self.__ref_vertex + d , self.__edge_len / 2.0 )
|
|
110
|
+
|
|
111
|
+
d = np.array([ self.right[0] , self.near[0] , self.up[0] ]) * self.__edge_len
|
|
112
|
+
self.__tree[5].set_local_boundary( self.__ref_vertex + d , self.__edge_len / 2.0 )
|
|
113
|
+
|
|
114
|
+
d = np.array([ self.right[0] , self.far[0] , self.up[0] ]) * self.__edge_len
|
|
115
|
+
self.__tree[6].set_local_boundary( self.__ref_vertex + d , self.__edge_len / 2.0 )
|
|
116
|
+
|
|
117
|
+
d = np.array([ self.left[0] , self.far[0] , self.up[0] ]) * self.__edge_len
|
|
118
|
+
self.__tree[7].set_local_boundary( self.__ref_vertex + d , self.__edge_len / 2.0 )
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def is_in( self , coord ):
|
|
122
|
+
a = coord >= self.__ref_vertex
|
|
123
|
+
b = coord < ( self.__ref_vertex + self.__edge_len )
|
|
124
|
+
|
|
125
|
+
return np.all( np.logical_and( a , b ) )
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def insert_particle_mp( self , pset , i ):
|
|
129
|
+
pass
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def insert_particle( self , pset , i ) :
|
|
133
|
+
if self.particle == None and self.__tree == None :
|
|
134
|
+
self.__particle = i
|
|
135
|
+
self.__M = pset.M[i]
|
|
136
|
+
self.__centre_of_mass = pset.X[i,:]
|
|
137
|
+
self.__part_cnt = 1
|
|
138
|
+
return
|
|
139
|
+
|
|
140
|
+
elif self.particle != None and self.__tree == None :
|
|
141
|
+
self.add_sub_trees()
|
|
142
|
+
|
|
143
|
+
elif self.particle != None and self.__tree != None :
|
|
144
|
+
pass ## it's only for testing the coherence of the tree structure
|
|
145
|
+
|
|
146
|
+
else :
|
|
147
|
+
raise
|
|
148
|
+
|
|
149
|
+
# update mass
|
|
150
|
+
self.__M += pset.M[i]
|
|
151
|
+
|
|
152
|
+
# update centre of mass
|
|
153
|
+
self.__centre_of_mass = ( self.__centre_of_mass * self.__part_cnt + pset.X[i,:] ) / ( self.__part_cnt + 1 )
|
|
154
|
+
self.__part_cnt += 1
|
|
155
|
+
|
|
156
|
+
# Old version, a bit slower.
|
|
157
|
+
#j = 0
|
|
158
|
+
#jj = 0
|
|
159
|
+
#for st in self.__tree :
|
|
160
|
+
# if st.is_in( pset.X[i,:] ) :
|
|
161
|
+
# jj = j
|
|
162
|
+
# st.insert_particle( pset , i )
|
|
163
|
+
# break
|
|
164
|
+
# j += 1
|
|
165
|
+
|
|
166
|
+
#return
|
|
167
|
+
|
|
168
|
+
indx = np.int8( np.array( [0,1,2,3,4,5,6,7] ) )
|
|
169
|
+
|
|
170
|
+
if pset.X[i,0] >= self.__ref_vertex[0] and pset.X[i,0] < self.__ref_vertex[0] + self.__edge_len/2.0 :
|
|
171
|
+
# Left
|
|
172
|
+
indx[:] = indx * self.__left
|
|
173
|
+
elif pset.X[i,0] >= self.__ref_vertex[0] + self.__edge_len/2.0 and pset.X[i,0] < self.__ref_vertex[0] + self.__edge_len :
|
|
174
|
+
# Right
|
|
175
|
+
indx[:] = indx * self.__right
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
if pset.X[i,1] >= self.__ref_vertex[1] and pset.X[i,1] < self.__ref_vertex[1] + self.__edge_len/2.0 :
|
|
179
|
+
# near
|
|
180
|
+
indx[:] = indx * self.__near
|
|
181
|
+
elif pset.X[i,1] >= self.__ref_vertex[1] + self.__edge_len/2.0 and pset.X[i,1] < self.__ref_vertex[1] + self.__edge_len :
|
|
182
|
+
# far
|
|
183
|
+
indx[:] = indx * self.__far
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
if pset.X[i,2] >= self.__ref_vertex[2] and pset.X[i,2] < self.__ref_vertex[2] + self.__edge_len/2.0 :
|
|
187
|
+
# down
|
|
188
|
+
indx[:] = indx * self.__down
|
|
189
|
+
elif pset.X[i,2] >= self.__ref_vertex[2] + self.__edge_len/2.0 and pset.X[i,2] < self.__ref_vertex[2] + self.__edge_len :
|
|
190
|
+
# up
|
|
191
|
+
indx[:] = indx * self.__up
|
|
192
|
+
|
|
193
|
+
ix = np.sum( indx )
|
|
194
|
+
self.__tree[ix].insert_particle( pset , i )
|
|
195
|
+
|
|
196
|
+
#print ( indx )
|
|
197
|
+
#print("")
|
|
198
|
+
#print ( "ix %d" % ix )
|
|
199
|
+
#print ( "jj %d" % jj )
|
|
200
|
+
#print ( "----------" )
|
|
201
|
+
|
|
202
|
+
#if jj != ix :
|
|
203
|
+
# print ("Fatal!!!!")
|
|
204
|
+
# exit()
|
|
205
|
+
#
|
|
206
|
+
return
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def search_neighbour( self , cand_queue , res_list , pset , X , r ):
|
|
210
|
+
"""
|
|
211
|
+
Search the elements included in the volume centred in *X* with the radius *r* and append the results in the list *res_list*.
|
|
212
|
+
*res_list* contains the indicies of the particles included in the the sphere.
|
|
213
|
+
"""
|
|
214
|
+
while len(cand_queue) :
|
|
215
|
+
tree = cand_queue.pop()
|
|
216
|
+
|
|
217
|
+
if distance( pset.X[tree.particle,:] , X ) <= r :
|
|
218
|
+
res_list.append( tree.particle )
|
|
219
|
+
|
|
220
|
+
if tree.__tree == None :
|
|
221
|
+
continue
|
|
222
|
+
|
|
223
|
+
for t in tree.__tree:
|
|
224
|
+
if t.particle != None and box_intersects_sphere( t.min_vertex , t.max_vertex , X , r ) :
|
|
225
|
+
cand_queue.append( t )
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def print_tree( self , pset , d=1 ):
|
|
229
|
+
"""
|
|
230
|
+
Print the structure of the tree and return the maximal depth
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
pset: the particles set
|
|
234
|
+
d: current depth (1 for the first node)
|
|
235
|
+
"""
|
|
236
|
+
if self.__particle == None :
|
|
237
|
+
return
|
|
238
|
+
|
|
239
|
+
vrtx = tuple(i for i in self.__ref_vertex)
|
|
240
|
+
cm = tuple(i for i in self.__centre_of_mass)
|
|
241
|
+
coord = tuple(i for i in pset.X[self.__particle,:] )
|
|
242
|
+
|
|
243
|
+
spc = " +"
|
|
244
|
+
|
|
245
|
+
print( "" )
|
|
246
|
+
print( "%s -------------------- " % ( spc*d ) )
|
|
247
|
+
print( "%s depth : %d " % ( spc*d , d ) )
|
|
248
|
+
print( "%s part indx: %d " % ( spc*d , self.__particle ) )
|
|
249
|
+
print( "%s part coord: %s " % ( spc*d , coord ) )
|
|
250
|
+
print( "%s vertex: %s " % ( spc*d , vrtx ) )
|
|
251
|
+
print( "%s edge: %s " % ( spc*d , self.__edge_len ) )
|
|
252
|
+
print( "%s centre of mass: %s " % ( spc*d , cm ) )
|
|
253
|
+
|
|
254
|
+
mx = d
|
|
255
|
+
if self.__tree != None:
|
|
256
|
+
for tr in self.__tree :
|
|
257
|
+
mx = max ( tr.print_tree( pset , d+1 ) , mx )
|
|
258
|
+
|
|
259
|
+
return mx
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def depth( self , d = 1 ):
|
|
263
|
+
"""
|
|
264
|
+
Compute and returns the maximal depth of the octree
|
|
265
|
+
"""
|
|
266
|
+
mx = d
|
|
267
|
+
if self.__tree != None:
|
|
268
|
+
for tr in self.__tree :
|
|
269
|
+
mx = max ( tr.depth( d+1 ) , mx )
|
|
270
|
+
|
|
271
|
+
return mx
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def get_up(self):
|
|
275
|
+
"""
|
|
276
|
+
Z axis
|
|
277
|
+
"""
|
|
278
|
+
return ( 0.5 , 1.0 )
|
|
279
|
+
|
|
280
|
+
def get_down(self):
|
|
281
|
+
return ( 0.0 , 0.5 )
|
|
282
|
+
|
|
283
|
+
def get_left(self):
|
|
284
|
+
return ( 0.0 , 0.5 )
|
|
285
|
+
|
|
286
|
+
def get_right(self):
|
|
287
|
+
return ( 0.5 , 1.0 )
|
|
288
|
+
|
|
289
|
+
def get_near(self):
|
|
290
|
+
return ( 0.0 , 0.5 )
|
|
291
|
+
|
|
292
|
+
def get_far(self):
|
|
293
|
+
return ( 0.5 , 1.0 )
|
|
294
|
+
|
|
295
|
+
up = property( get_up , doc="relative domanin for the up 'sub-space' " )
|
|
296
|
+
down = property( get_down , doc="relative domanin for the down 'sub-space' " )
|
|
297
|
+
left = property( get_left , doc="relative domanin for the left 'sub-space' " )
|
|
298
|
+
right = property( get_right , doc="relative domanin for the right 'sub-space' " )
|
|
299
|
+
near = property( get_near , doc="relative domanin for the near 'sub-space' " )
|
|
300
|
+
far = property( get_far , doc="relative domanin for the far 'sub-space' " )
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
class OcTree ( object ):
|
|
305
|
+
"""
|
|
306
|
+
|OcTree particles container class
|
|
307
|
+
"""
|
|
308
|
+
def __init__( self ):
|
|
309
|
+
self.__tree = None
|
|
310
|
+
self.__pset = None
|
|
311
|
+
self.__ref_vertex = np.zeros((3))
|
|
312
|
+
self.__edge_len = 1.0
|
|
313
|
+
|
|
314
|
+
def set_global_boundary( self ,
|
|
315
|
+
ref_vertex = np.array([ 0.0 , 0.0 , 0.0 ]) ,
|
|
316
|
+
edge_len = 1.0 ) :
|
|
317
|
+
|
|
318
|
+
"""
|
|
319
|
+
Define the size of the octree cube
|
|
320
|
+
|
|
321
|
+
========== =================================
|
|
322
|
+
Arguments
|
|
323
|
+
========== =================================
|
|
324
|
+
ref_vertex the ( down , near , left ) vertex
|
|
325
|
+
edge_len leght of the edge
|
|
326
|
+
========== =================================
|
|
327
|
+
"""
|
|
328
|
+
|
|
329
|
+
self.__ref_vertex[:] = ref_vertex
|
|
330
|
+
self.__edge_len = edge_len
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
def get_centre_of_mass( self ):
|
|
334
|
+
return self.__tree.centre_of_mass
|
|
335
|
+
|
|
336
|
+
centre_of_mass = property( get_centre_of_mass , doc="return the centre of mass of the particles set" )
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
def search_neighbour( self , X , r ):
|
|
340
|
+
"""
|
|
341
|
+
return an array containing the indecies of the the particles included in the sheric region centred in *X* with a radius *r*
|
|
342
|
+
"""
|
|
343
|
+
|
|
344
|
+
res_list = []
|
|
345
|
+
|
|
346
|
+
if self.__tree == None :
|
|
347
|
+
return np.array(res_list)
|
|
348
|
+
|
|
349
|
+
if not self.__tree.is_in( X ):
|
|
350
|
+
return np.array(res_list)
|
|
351
|
+
|
|
352
|
+
cq = deque( [ self.__tree ] )
|
|
353
|
+
|
|
354
|
+
self.__tree.search_neighbour( cq , res_list , self.__pset , X , r )
|
|
355
|
+
|
|
356
|
+
return np.array(res_list)
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
def __build_tree_mp( self , pset ) :
|
|
360
|
+
"""
|
|
361
|
+
Build the octree with the given particles set with a parrallel processig procedure
|
|
362
|
+
|
|
363
|
+
Arguments:
|
|
364
|
+
==== ============================================
|
|
365
|
+
pset a ParticlesSet object used to build the tree
|
|
366
|
+
==== ============================================
|
|
367
|
+
"""
|
|
368
|
+
|
|
369
|
+
if self.__tree == None :
|
|
370
|
+
self.__tree = TreeElement()
|
|
371
|
+
else :
|
|
372
|
+
del self.__tree
|
|
373
|
+
self.__tree = TreeElement()
|
|
374
|
+
|
|
375
|
+
self.__tree.set_local_boundary( self.__ref_vertex , self.__edge_len )
|
|
376
|
+
|
|
377
|
+
self.__pset = pset
|
|
378
|
+
|
|
379
|
+
cpu = mpr.cpu_count()
|
|
380
|
+
jobs_queue = mpr.Queue()
|
|
381
|
+
|
|
382
|
+
parent_conn = list( None for i in range(cpu) )
|
|
383
|
+
child_conn = list( None for i in range(cpu) )
|
|
384
|
+
|
|
385
|
+
procs = list( None for i in range(cpu) )
|
|
386
|
+
|
|
387
|
+
for i in range( cpu ) :
|
|
388
|
+
( parent_conn[i] , child_conn[i] ) = mpr.Pipe()
|
|
389
|
+
procs[i] = mpr.Process(target=self.__build_tree_process , args=( jobs_queue , child_conn[i] ) )
|
|
390
|
+
parent_conn[i].send( [ pset , self.__tree ] )
|
|
391
|
+
|
|
392
|
+
for i in range( pset.size ):
|
|
393
|
+
jobs_queue.put( i )
|
|
394
|
+
|
|
395
|
+
for i in range( cpu ) :
|
|
396
|
+
procs[i].start()
|
|
397
|
+
|
|
398
|
+
for p in procs :
|
|
399
|
+
p.join()
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
def __build_tree_process( self , queue , child_conn ) :
|
|
403
|
+
|
|
404
|
+
t_args = child_conn.recv()
|
|
405
|
+
pset = t_args[0]
|
|
406
|
+
tree = t_args[1]
|
|
407
|
+
|
|
408
|
+
# get the first job.
|
|
409
|
+
|
|
410
|
+
flag = True
|
|
411
|
+
while flag :
|
|
412
|
+
if queue.empty() :
|
|
413
|
+
flag = False
|
|
414
|
+
continue
|
|
415
|
+
i = queue.get()
|
|
416
|
+
print( i )
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
def build_tree( self , pset ) :
|
|
420
|
+
"""
|
|
421
|
+
Build the octree with the given particles set
|
|
422
|
+
|
|
423
|
+
========= ============================================
|
|
424
|
+
Arguments
|
|
425
|
+
========= ============================================
|
|
426
|
+
pset a ParticlesSet object used to build the tree
|
|
427
|
+
========= ============================================
|
|
428
|
+
"""
|
|
429
|
+
|
|
430
|
+
if self.__tree == None :
|
|
431
|
+
self.__tree = TreeElement()
|
|
432
|
+
else :
|
|
433
|
+
del self.__tree
|
|
434
|
+
self.__tree = TreeElement()
|
|
435
|
+
|
|
436
|
+
self.__tree.set_local_boundary( self.__ref_vertex , self.__edge_len )
|
|
437
|
+
|
|
438
|
+
self.__pset = pset
|
|
439
|
+
|
|
440
|
+
for i in range( pset.size ):
|
|
441
|
+
self.__tree.insert_particle( pset , i )
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
def print_tree( self ):
|
|
445
|
+
mx = self.__tree.print_tree( self.__pset , 1 )
|
|
446
|
+
|
|
447
|
+
print("")
|
|
448
|
+
print("Max depth: %d " % mx )
|
|
449
|
+
print("")
|
|
450
|
+
|
|
451
|
+
|