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.
Files changed (100) hide show
  1. pyparticles/__init__.py +26 -0
  2. pyparticles/__main__.py +7 -0
  3. pyparticles/animation/__init__.py +21 -0
  4. pyparticles/animation/animated_cli.py +53 -0
  5. pyparticles/animation/animated_ogl.py +691 -0
  6. pyparticles/animation/animated_ogl_compat.py +243 -0
  7. pyparticles/animation/animated_scatter.py +94 -0
  8. pyparticles/animation/animation.py +251 -0
  9. pyparticles/animation/test_animation.py +310 -0
  10. pyparticles/demo/__init__.py +33 -0
  11. pyparticles/demo/bubble.py +106 -0
  12. pyparticles/demo/electromagnetic_demo.py +128 -0
  13. pyparticles/demo/electrostatic_demo.py +126 -0
  14. pyparticles/demo/fountain.py +478 -0
  15. pyparticles/demo/gas_lennard_jones.py +87 -0
  16. pyparticles/demo/gravity_clusters.py +73 -0
  17. pyparticles/demo/solar_system.py +222 -0
  18. pyparticles/demo/springs.py +141 -0
  19. pyparticles/demo/springs_constr.py +135 -0
  20. pyparticles/demo/test.py +34 -0
  21. pyparticles/forces/__init__.py +21 -0
  22. pyparticles/forces/const_force.py +140 -0
  23. pyparticles/forces/damping.py +174 -0
  24. pyparticles/forces/drag.py +167 -0
  25. pyparticles/forces/electromagnetic.py +105 -0
  26. pyparticles/forces/electromagnetic_field.py +95 -0
  27. pyparticles/forces/electrostatic.py +72 -0
  28. pyparticles/forces/force.py +75 -0
  29. pyparticles/forces/force_constrained.py +32 -0
  30. pyparticles/forces/fused_const_drag.py +445 -0
  31. pyparticles/forces/gravity.py +345 -0
  32. pyparticles/forces/lennard_jones.py +74 -0
  33. pyparticles/forces/linear_spring.py +86 -0
  34. pyparticles/forces/linear_spring_constrained.py +72 -0
  35. pyparticles/forces/multiple_force.py +134 -0
  36. pyparticles/forces/pseudo_bubble.py +226 -0
  37. pyparticles/forces/van_der_waals_force.py +60 -0
  38. pyparticles/forces/vector_field_force.py +52 -0
  39. pyparticles/geometry/__init__.py +21 -0
  40. pyparticles/geometry/dist.py +24 -0
  41. pyparticles/geometry/intersection.py +62 -0
  42. pyparticles/geometry/transformations.py +387 -0
  43. pyparticles/main/__init__.py +21 -0
  44. pyparticles/main/main.py +466 -0
  45. pyparticles/measures/__init__.py +21 -0
  46. pyparticles/measures/elastic_potential_energy.py +67 -0
  47. pyparticles/measures/gravitational_potential_energy.py +69 -0
  48. pyparticles/measures/kinetic_energy.py +68 -0
  49. pyparticles/measures/mass.py +59 -0
  50. pyparticles/measures/measure.py +156 -0
  51. pyparticles/measures/momentum.py +144 -0
  52. pyparticles/measures/total_energy.py +68 -0
  53. pyparticles/ode/__init__.py +21 -0
  54. pyparticles/ode/euler_solver.py +214 -0
  55. pyparticles/ode/euler_solver_constrained.py +49 -0
  56. pyparticles/ode/leapfrog_solver.py +37 -0
  57. pyparticles/ode/leapfrog_solver_constrained.py +53 -0
  58. pyparticles/ode/midpoint_solver.py +43 -0
  59. pyparticles/ode/midpoint_solver_constrained.py +60 -0
  60. pyparticles/ode/ode_solver.py +134 -0
  61. pyparticles/ode/ode_solver_constrained.py +43 -0
  62. pyparticles/ode/runge_kutta_solver.py +79 -0
  63. pyparticles/ode/runge_kutta_solver_constrained.py +98 -0
  64. pyparticles/ode/sim_time.py +56 -0
  65. pyparticles/ode/stormer_verlet_solver.py +50 -0
  66. pyparticles/ode/stormer_verlet_solver_constrained.py +73 -0
  67. pyparticles/ogl/__init__.py +21 -0
  68. pyparticles/ogl/axis_ogl.py +210 -0
  69. pyparticles/ogl/draw_particles_ogl.py +313 -0
  70. pyparticles/ogl/draw_particles_ogl_compat.py +509 -0
  71. pyparticles/ogl/draw_vector_field.py +221 -0
  72. pyparticles/ogl/opencl_gl_vbo.py +485 -0
  73. pyparticles/ogl/trackball.py +131 -0
  74. pyparticles/ogl/translate_scene.py +87 -0
  75. pyparticles/pset/__init__.py +21 -0
  76. pyparticles/pset/boundary.py +69 -0
  77. pyparticles/pset/cluster.py +28 -0
  78. pyparticles/pset/constrained_force_interactions.py +63 -0
  79. pyparticles/pset/constrained_x.py +158 -0
  80. pyparticles/pset/constraint.py +42 -0
  81. pyparticles/pset/default_boundary.py +43 -0
  82. pyparticles/pset/file_cluster.py +131 -0
  83. pyparticles/pset/logger.py +152 -0
  84. pyparticles/pset/octree.py +451 -0
  85. pyparticles/pset/opencl_context.py +374 -0
  86. pyparticles/pset/particles_set.py +499 -0
  87. pyparticles/pset/periodic_boundary.py +36 -0
  88. pyparticles/pset/rand_cluster.py +188 -0
  89. pyparticles/pset/rebound_boundary.py +68 -0
  90. pyparticles/utils/__init__.py +21 -0
  91. pyparticles/utils/parse_args.py +72 -0
  92. pyparticles/utils/problem_config.py +608 -0
  93. pyparticles/utils/pypart_global.py +122 -0
  94. pyparticles/utils/time_formatter.py +50 -0
  95. pyparticles3-0.4.0.dist-info/METADATA +395 -0
  96. pyparticles3-0.4.0.dist-info/RECORD +100 -0
  97. pyparticles3-0.4.0.dist-info/WHEEL +5 -0
  98. pyparticles3-0.4.0.dist-info/entry_points.txt +3 -0
  99. pyparticles3-0.4.0.dist-info/licenses/LICENSE-gpl-3.0.txt +674 -0
  100. pyparticles3-0.4.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,226 @@
1
+ # PyParticles : Particles simulation in python
2
+ # Copyright (C) 2012 Simone Riva
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
+ import numpy as np
10
+ import scipy.spatial.distance as dist
11
+
12
+ import pyparticles.forces.force as fr
13
+ import pyparticles.pset.opencl_context as occ
14
+
15
+ try:
16
+ import pyopencl as cl
17
+ except ImportError:
18
+ cl = None
19
+
20
+
21
+ class PseudoBubble(fr.Force):
22
+ r"""Pseudo-bubble interaction used by the bubble demo."""
23
+
24
+ def __init__(self, size, dim=3, m=None, Consts=(0.3, 2.0)):
25
+ self.__dim = int(dim)
26
+ self.__size = int(size)
27
+ self.__R = float(Consts[0])
28
+ self.__B = float(Consts[1])
29
+
30
+ self.__A = np.zeros((size, dim))
31
+ self.__M = np.zeros((size, 1))
32
+ self.__F = np.zeros((size, size))
33
+ self.__D = np.zeros((size, size))
34
+ self.__V = np.zeros((size, size))
35
+
36
+ if m is not None:
37
+ self.set_masses(m)
38
+
39
+ def set_masses(self, m):
40
+ self.__M[:] = m
41
+
42
+ def update_force(self, pset):
43
+ D = self.__D
44
+ D[:] = dist.squareform(dist.pdist(pset.X))
45
+ n, m = np.where(np.logical_and(D <= self.__R, D != 0.0))
46
+
47
+ self.__F[:] = 0.0
48
+ self.__F[n, m] = (-(self.__B / self.__R) * D[n, m] + self.__B) / D[n, m]
49
+
50
+ for i in range(pset.dim):
51
+ self.__V[:, :] = pset.X[:, i]
52
+ self.__V[:, :] = (self.__V.T - pset.X[:, i]).T
53
+ self.__A[:, i] = np.sum(
54
+ self.__F * self.__V / self.__M.T,
55
+ axis=0,
56
+ )
57
+
58
+ return self.__A
59
+
60
+ def getA(self):
61
+ return self.__A
62
+
63
+ A = property(getA)
64
+
65
+ def getF(self):
66
+ return self.__A * self.__M
67
+
68
+ F = property(getF)
69
+
70
+
71
+ class PseudoBubbleOCL(fr.Force):
72
+ """OpenCL implementation of the pseudo-bubble interaction."""
73
+
74
+ def __init__(self, size, dim=3, m=None, Consts=(0.3, 2.0), ocl_context=None):
75
+ if cl is None:
76
+ raise RuntimeError("PyOpenCL is required for PseudoBubbleOCL")
77
+ if int(dim) != 3:
78
+ raise ValueError("PseudoBubbleOCL currently supports only 3 dimensions")
79
+
80
+ self.__dim = int(dim)
81
+ self.__size = int(size)
82
+
83
+ if ocl_context is None:
84
+ self.__occ = occ.OpenCLcontext(
85
+ size,
86
+ dim,
87
+ occ.OCLC_X | occ.OCLC_A | occ.OCLC_M,
88
+ )
89
+ else:
90
+ self.__occ = ocl_context
91
+
92
+ self.__dtype = self.__occ.dtype
93
+ self.__R = self.__dtype(Consts[0])
94
+ self.__B = self.__dtype(Consts[1])
95
+ self.__A = np.zeros((size, dim), dtype=self.__dtype)
96
+ self.__M = np.zeros((size, 1), dtype=self.__dtype)
97
+
98
+ self.__init_prog_cl()
99
+ if m is not None:
100
+ self.set_masses(m)
101
+
102
+ def __init_prog_cl(self):
103
+ source = r"""
104
+ __kernel void pseudo_bubble(
105
+ __global const float *X,
106
+ __global const float *M,
107
+ float R,
108
+ float B,
109
+ int accumulate,
110
+ __global float *A)
111
+ {
112
+ int i = get_global_id(0);
113
+ int sz = get_global_size(0);
114
+
115
+ int i0 = 3*i;
116
+ int i1 = i0 + 1;
117
+ int i2 = i0 + 2;
118
+
119
+ float4 at = (float4)(0.0f, 0.0f, 0.0f, 0.0f);
120
+ float4 u = (float4)(0.0f, 0.0f, 0.0f, 0.0f);
121
+
122
+ for (int n = 0; n < sz; ++n)
123
+ {
124
+ if (n == i) continue;
125
+
126
+ u.x = X[i0] - X[3*n];
127
+ u.y = X[i1] - X[3*n+1];
128
+ u.z = X[i2] - X[3*n+2];
129
+
130
+ float d = length(u);
131
+ if (d >= R || d == 0.0f) continue;
132
+
133
+ float f = (-B/R * d + B) / d;
134
+ at.x += u.x * f / M[i];
135
+ at.y += u.y * f / M[i];
136
+ at.z += u.z * f / M[i];
137
+ }
138
+
139
+ if (accumulate)
140
+ {
141
+ A[i0] += at.x;
142
+ A[i1] += at.y;
143
+ A[i2] += at.z;
144
+ }
145
+ else
146
+ {
147
+ A[i0] = at.x;
148
+ A[i1] = at.y;
149
+ A[i2] = at.z;
150
+ }
151
+ }
152
+ """
153
+ self.__cl_program = cl.Program(self.__occ.CL_context, source).build()
154
+ self.__kernel = cl.Kernel(self.__cl_program, "pseudo_bubble")
155
+
156
+ def set_masses(self, m):
157
+ self.__M[:] = np.asarray(m, dtype=self.__dtype)
158
+ self.__occ.set_from_host("M", self.__M)
159
+
160
+ def update_force_device(self, pset, accumulate=False, host_authoritative=False):
161
+ if host_authoritative:
162
+ self.__occ.mark_host_modified("X")
163
+ self.__occ.sync_to_device("X", pset.X)
164
+
165
+ self.__kernel(
166
+ self.__occ.CL_queue,
167
+ (self.__size,),
168
+ None,
169
+ self.__occ.X_cla.data,
170
+ self.__occ.M_cla.data,
171
+ self.__R,
172
+ self.__B,
173
+ np.int32(bool(accumulate)),
174
+ self.__occ.A_cla.data,
175
+ )
176
+ self.__occ.mark_device_modified("A")
177
+ return self.__occ.A_cla
178
+
179
+ def update_force(self, pset):
180
+ self.update_force_device(pset, accumulate=False, host_authoritative=True)
181
+ self.__occ.sync_to_host("A", self.__A)
182
+ return self.__A
183
+
184
+ def getA(self):
185
+ return self.__A
186
+
187
+ A = property(getA)
188
+
189
+ def getF(self):
190
+ self.__occ.sync_to_host("A", self.__A)
191
+ return self.__A * self.__M
192
+
193
+ F = property(getF)
194
+
195
+ def get_ocl_context(self):
196
+ return self.__occ
197
+
198
+ ocl_context = property(get_ocl_context)
199
+
200
+
201
+ class PseudoBubbleFastOCL(PseudoBubbleOCL):
202
+ """
203
+ Compatibility implementation for the historical experimental fast class.
204
+
205
+ The original 0.3.5 implementation was incomplete and contained invalid
206
+ OpenCL source. Until a spatially tiled implementation is introduced, use
207
+ the validated PseudoBubbleOCL kernel while preserving the public API.
208
+ """
209
+
210
+ def __init__(
211
+ self,
212
+ size,
213
+ dim=3,
214
+ m=None,
215
+ Consts=(0.3, 2.0),
216
+ domain=(-5.5, 5.5),
217
+ ocl_context=None,
218
+ ):
219
+ self.domain = domain
220
+ super(PseudoBubbleFastOCL, self).__init__(
221
+ size,
222
+ dim=dim,
223
+ m=m,
224
+ Consts=Consts,
225
+ ocl_context=ocl_context,
226
+ )
@@ -0,0 +1,60 @@
1
+ # PyParticles : Particles simulation in python
2
+ # Copyright (C) 2012 Simone Riva
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 numpy as np
18
+ import sys
19
+ import scipy.spatial.distance as dist
20
+
21
+ import pyparticles.forces.force as fr
22
+
23
+ class VanDerWaals( fr.Force ) :
24
+ def __init__(self , size , dim=3 , m=None , Consts=1.0 ):
25
+
26
+ self.__dim = dim
27
+ self.__size = size
28
+
29
+ self.__C = Consts # Hamaker coefficient (A)
30
+
31
+ self.__A = np.zeros( ( size , dim ) )
32
+ self.__F = np.zeros( ( size , dim ) )
33
+ self.__Fm = np.zeros( ( size , size ) )
34
+
35
+ self.__R = np.zeros( ( size , 1 ) )
36
+ if m != None :
37
+ self.set_messes( m )
38
+
39
+
40
+ def set_masses( self , m ):
41
+ self.__R[:] = m
42
+
43
+
44
+ def update_force( self , p_set ):
45
+
46
+ self.__D[:] = dist.squareform( dist.pdist( p_set.X , 'euclidean' ) )
47
+
48
+ return self.__A
49
+
50
+ def getA(self):
51
+ return self.__A
52
+
53
+ A = property( getA )
54
+
55
+
56
+ def getF(self):
57
+ return self.__F
58
+
59
+ F = property( getF )
60
+
@@ -0,0 +1,52 @@
1
+ # PyParticles : Particles simulation in python
2
+ # Copyright (C) 2012 Simone Riva
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 numpy as np
18
+ import sys
19
+ import scipy.spatial.distance as dist
20
+
21
+ import pyparticles.forces.force as fr
22
+
23
+ class VectorFieldForce( fr.Force ) :
24
+ def __init__(self , size , dim=3 , m=None ):
25
+ self.__dim = dim
26
+ self.__size = size
27
+ self.__A = np.zeros( ( size , dim ) )
28
+ self.__M = np.zeros( ( size , size ) )
29
+ if m != None :
30
+ self.set_messes( m )
31
+
32
+
33
+ def set_masses( self , m ):
34
+ self.__M[:] = m
35
+
36
+ def update_force( self , p_set ):
37
+ self.__A[:] = self.vect_fun( p_set.X )
38
+ return self.__A
39
+
40
+ def vect_fun( self , X ):
41
+ NotImplementedError(" %s : is virtual and must be overridden." % sys._getframe().f_code.co_name )
42
+
43
+ def getA(self):
44
+ return self.__A
45
+
46
+ A = property( getA )
47
+
48
+
49
+ def getF(self):
50
+ return self.__A * self.__M[:]
51
+
52
+ F = property( getF )
@@ -0,0 +1,21 @@
1
+ # PyParticles : Particles simulation in python
2
+ #Copyright (C) 2012 Simone Riva
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
+
18
+ import os
19
+ import glob
20
+
21
+ __all__ = [ os.path.splitext( os.path.basename(f) )[0] for f in glob.glob(os.path.dirname(os.path.abspath(__file__))+"/*.py")]
@@ -0,0 +1,24 @@
1
+ # PyParticles : Particles simulation in python
2
+ # Copyright (C) 2012 Simone Riva
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
+
18
+ import numpy as np
19
+
20
+ def distance( x , y ):
21
+ """
22
+ return the euclideian distance between *x* and *y*
23
+ """
24
+ return np.sqrt( np.sum( (x-y)**2.0 ) )
@@ -0,0 +1,62 @@
1
+ # PyParticles : Particles simulation in python
2
+ # Copyright (C) 2012 Simone Riva
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 numpy as np
18
+ from numpy import linalg as LA
19
+
20
+ import pyparticles.geometry.dist as dist
21
+
22
+ def box_intersects_sphere( b_min , b_max , c , r ):
23
+ """
24
+ return True if the box defined by the opposite vertices *n_max*, *b max* intersect the sphere centred in *c* with a radius *r*
25
+ """
26
+
27
+ r2 = r**2.0
28
+ dmin = 0.0
29
+
30
+ if c[0] < b_min[0] :
31
+ dmin += ( c[0] - b_min[0] )**2.0
32
+ elif c[0] > b_max[0]:
33
+ dmin += ( c[0] - b_max[0] )**2.0
34
+
35
+ if c[1] < b_min[1] :
36
+ dmin += ( c[1] - b_min[1] )**2.0
37
+ elif c[1] > b_max[1]:
38
+ dmin += ( c[1] - b_max[1] )**2.0
39
+
40
+ if c[2] < b_min[2] :
41
+ dmin += ( c[2] - b_min[2] )**2.0
42
+ elif c[2] > b_max[2]:
43
+ dmin += ( c[2] - b_max[2] )**2.0
44
+
45
+ return dmin <= r2
46
+
47
+
48
+ def sphere_intersect_sphere( c1 , r1 , c2 , r2 ):
49
+ """
50
+ returns the average intersection point if the two spheres centred in *c1* and *c2* and radius *r1*, *r2* are intersecting, else it returns *None*
51
+ """
52
+ d = dist.distance( c1 , c2 )
53
+
54
+ if r1 + r2 >= d :
55
+
56
+ u = ( c2 - c1 ) / LA.norm( c2 - c1 )
57
+ p = ( ( c1 + u*r1 ) + ( c2 - u*r2 ) ) / 2.0
58
+
59
+ return p
60
+ else :
61
+ return None
62
+