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,310 @@
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 pyparticles.pset.particles_set as ps
18
+
19
+ import pyparticles.animation.animation as pan
20
+
21
+
22
+ import pyparticles.forces.gravity as gr
23
+ import pyparticles.ode.euler_solver as els
24
+ import pyparticles.ode.leapfrog_solver as lps
25
+ import pyparticles.ode.runge_kutta_solver as rks
26
+ import pyparticles.ode.midpoint_solver as mps
27
+ import pyparticles.ode.stormer_verlet_solver as svs
28
+
29
+ import pyparticles.ode.euler_solver_constrained as asc
30
+ import pyparticles.ode.leapfrog_solver_constrained as lpc
31
+ import pyparticles.ode.stormer_verlet_solver_constrained as svc
32
+ import pyparticles.ode.runge_kutta_solver_constrained as rkc
33
+ import pyparticles.ode.midpoint_solver_constrained as mdc
34
+
35
+
36
+ import matplotlib.pyplot as plt
37
+ import numpy as np
38
+
39
+ import pyparticles.forces.const_force as cf
40
+ import pyparticles.forces.drag as dr
41
+ import pyparticles.forces.multiple_force as mf
42
+ import pyparticles.forces.linear_spring as ls
43
+ import pyparticles.forces.damping as da
44
+
45
+ import pyparticles.pset.constrained_x as csx
46
+ import pyparticles.pset.constrained_force_interactions as cfi
47
+
48
+ from matplotlib.ticker import FuncFormatter
49
+
50
+
51
+
52
+ def free_fall( t , m=1. , g=10. , k=1. ):
53
+ z = (np.sqrt(2.*g*k)*t*m**2.-2.*m**(5./2.)*np.log((1./2.)*np.exp(np.sqrt(2.)*np.sqrt(g*k)*t/np.sqrt(m))+1./2.))/(m**(3./2.)*k)
54
+ return np.array( [ 0.0 , 0.0 , z ] )
55
+
56
+ def harmonic( t ):
57
+ a = np.cos( t ) / np.sqrt(3.0)
58
+ return np.array( [ a , a , a ] )
59
+
60
+ def damp_harmonic( t ):
61
+ a = (1./15.)*np.sqrt(15.)*np.exp(-(1./4.)*t)*np.sin((1./4.)*np.sqrt(15.)*t)+np.exp(-(1./4.)*t)*np.cos((1./4.)*np.sqrt(15.)*t)
62
+ a = a / np.sqrt(3.0)
63
+
64
+ return np.array( [ a , a , a ] )
65
+
66
+
67
+ class TestAnimation( pan.Animation ):
68
+ """
69
+ Test the free fall with the fluid drag
70
+ """
71
+ def __init__(self):
72
+ super( TestAnimation , self ).__init__()
73
+
74
+ self.__analytical_sol = free_fall
75
+
76
+ def set_analytical_sol( self , f ):
77
+ self.__analytical_sol = f
78
+
79
+ def get_analytical_sol( self ):
80
+ return self.__analytical_sol
81
+
82
+ analytical_sol = property( get_analytical_sol , set_analytical_sol )
83
+
84
+
85
+
86
+ def set_ip( self , i ):
87
+ self.__ip = i
88
+
89
+ def get_ip( self ):
90
+ return self.__ip
91
+
92
+ ip = property( get_ip , set_ip )
93
+
94
+
95
+ def init_pset(self):
96
+ self.pset.M[:] = 1.0
97
+ self.pset.V[:] = 0.0
98
+ self.pset.X[:] = 0.0
99
+
100
+ def build_animation(self):
101
+
102
+ self.steps = 3000
103
+
104
+ self.pset = ps.ParticlesSet( 1 , 3 )
105
+
106
+ self.ip = 0
107
+
108
+ self.pset.M[:] = 1.0
109
+ self.pset.V[:] = 0.0
110
+
111
+ self.t = np.zeros(( self.steps ))
112
+ self.x = np.zeros(( self.steps , self.pset.dim ))
113
+
114
+ self.xn = np.zeros(( self.steps , self.pset.dim ))
115
+
116
+ constf = cf.ConstForce( self.pset.size , u_force=[ 0 , 0 , -10.0 ] , dim=self.pset.dim )
117
+ drag = dr.Drag( self.pset.size , Consts=1.0 )
118
+
119
+ multi = mf.MultipleForce( self.pset.size )
120
+
121
+ multi.append_force( constf )
122
+ multi.append_force( drag )
123
+
124
+ multi.set_masses( self.pset.M )
125
+
126
+ dt = 0.001
127
+
128
+ self.odes = dict()
129
+
130
+ self.odes["Euler "] = els.EulerSolver( multi , self.pset , dt )
131
+ self.odes["Runge Kutta"] = rks.RungeKuttaSolver( multi , self.pset , dt )
132
+ self.odes["Leap Frog "] = lps.LeapfrogSolver( multi , self.pset , dt )
133
+ self.odes["MidPoint "] = mps.MidpointSolver( multi , self.pset , dt )
134
+ self.odes["Verlet "] = svs.StormerVerletSolver( multi , self.pset , dt )
135
+
136
+ def data_stream( self ):
137
+
138
+ for i in range( self.steps ) :
139
+
140
+ self.t[i] = self.ode_solver.time
141
+
142
+ #print( self.t[i] )
143
+
144
+ self.x[i,:] = self.analytical_sol( self.t[i] )
145
+
146
+ self.xn[i,:] = self.pset.X[self.ip,:]
147
+
148
+ #print( " t: %f , x: %s , xn: %s " % ( self.t[i] , self.x[i,:] , self.xn[i,:] ) )
149
+ self.ode_solver.step()
150
+
151
+
152
+
153
+ def start(self):
154
+
155
+ print( "Start testing:" )
156
+
157
+ j = 0
158
+
159
+ print("")
160
+ print("Errors:")
161
+
162
+ #plt.ion()
163
+
164
+ for ky in self.odes.keys():
165
+
166
+ self.init_pset()
167
+
168
+ self.ode_solver = self.odes[ky]
169
+ self.data_stream()
170
+
171
+ err = np.sqrt( np.sum( (self.x-self.xn)**2 , 1 ) )
172
+
173
+ merr = np.mean( err )
174
+
175
+ mt = np.array( [ self.t[0] , self.t[self.steps-1] ] )
176
+ me = np.array( [ merr , merr ] )
177
+
178
+ print( " %s - mean err: %f " % ( ky , merr ) )
179
+
180
+ ax = plt.subplot( 230+j+1 )
181
+
182
+ ax.yaxis.set_major_formatter(FuncFormatter(lambda x, pos: ('%.1f')%(x*1e3)))
183
+
184
+ p1, = plt.plot( self.t[:] , err , linewidth=2 )
185
+ p2, = plt.plot( mt , me , linewidth=1 , color="g" )
186
+
187
+ plt.title( "Absolute error: %s " % ky )
188
+ plt.xlabel( "Time" )
189
+ plt.ylabel( "Abs error [1e-3]" )
190
+
191
+ plt.legend([p1, p2], ["Abs Error", "Mean"] , loc=4 )
192
+
193
+ plt.grid(1)
194
+
195
+ plt.draw()
196
+
197
+ j += 1
198
+
199
+ plt.show()
200
+
201
+
202
+
203
+ class TestAnimationHarmonic( TestAnimation ):
204
+ """
205
+ Test the harmonic motion with two particles.
206
+ """
207
+
208
+ def __init__(self):
209
+ self.analytical_sol = harmonic
210
+
211
+ def init_pset(self):
212
+ self.pset.X[0,:] = 0.0
213
+ self.pset.X[1,:] = 1.0 / np.sqrt(3)
214
+ self.pset.M[:] = 1.0
215
+ self.pset.V[:] = 0.0
216
+
217
+ def build_animation(self):
218
+
219
+ self.steps = 6000
220
+ dt = 0.004
221
+
222
+ self.ip = 1
223
+
224
+ self.pset = ps.ParticlesSet( 2 , 3 )
225
+ self.pset.M[:] = 1.0
226
+ self.pset.V[:] = 0.0
227
+
228
+ self.pset.X[0,:] = 0.0
229
+ self.pset.X[1,:] = 1.0 / np.sqrt(3)
230
+
231
+ ci = np.array( [ 0 ] )
232
+ cx = np.array( [ 0.0 , 0.0 , 0.0 ] )
233
+
234
+ costrs = csx.ConstrainedX( self.pset )
235
+ costrs.add_x_constraint( ci , cx )
236
+
237
+ self.t = np.zeros(( self.steps ))
238
+ self.x = np.zeros(( self.steps , self.pset.dim ))
239
+
240
+ self.xn = np.zeros(( self.steps , self.pset.dim ))
241
+
242
+ spring = ls.LinearSpring( self.pset.size , self.pset.dim , Consts=1.0 )
243
+
244
+ spring.set_masses( self.pset.M )
245
+
246
+ self.odes = dict()
247
+
248
+ self.odes["Euler "] = asc.EulerSolverConstrained( spring , self.pset , dt , costrs )
249
+ self.odes["Runge Kutta"] = rkc.RungeKuttaSolverConstrained( spring , self.pset , dt , costrs )
250
+ self.odes["Leap Frog "] = lpc.LeapfrogSolverConstrained( spring , self.pset , dt , costrs )
251
+ self.odes["MidPoint "] = mdc.MidpointSolverConstrained( spring , self.pset , dt , costrs )
252
+ self.odes["Verlet "] = svc.StormerVerletSolverConstrained( spring , self.pset , dt , costrs )
253
+
254
+
255
+ class TestAnimationDampedHarmonic( TestAnimation ):
256
+ """
257
+ Test the damped harmonic motion with two particles.
258
+ """
259
+
260
+ def __init__(self):
261
+ self.analytical_sol = damp_harmonic
262
+
263
+ def init_pset(self):
264
+ self.pset.X[0,:] = 0.0
265
+ self.pset.X[1,:] = 1.0 / np.sqrt(3)
266
+ self.pset.M[:] = 1.0
267
+ self.pset.V[:] = 0.0
268
+
269
+ def build_animation(self):
270
+
271
+ self.steps = 6000
272
+ dt = 0.004
273
+
274
+ self.ip = 1
275
+
276
+ self.pset = ps.ParticlesSet( 2 , 3 )
277
+ self.pset.M[:] = 1.0
278
+ self.pset.V[:] = 0.0
279
+
280
+ self.pset.X[0,:] = 0.0
281
+ self.pset.X[1,:] = 1.0 / np.sqrt(3)
282
+
283
+ ci = np.array( [ 0 ] )
284
+ cx = np.array( [ 0.0 , 0.0 , 0.0 ] )
285
+
286
+ costrs = csx.ConstrainedX( self.pset )
287
+ costrs.add_x_constraint( ci , cx )
288
+
289
+ self.t = np.zeros(( self.steps ))
290
+ self.x = np.zeros(( self.steps , self.pset.dim ))
291
+
292
+ self.xn = np.zeros(( self.steps , self.pset.dim ))
293
+
294
+ spring = ls.LinearSpring( self.pset.size , self.pset.dim , Consts=1.0 )
295
+ damp = da.Damping( self.pset.size , self.pset.dim , Consts=0.5 )
296
+
297
+ multi = mf.MultipleForce( self.pset.size )
298
+
299
+ multi.append_force( spring )
300
+ multi.append_force( damp )
301
+
302
+ multi.set_masses( self.pset.M )
303
+
304
+ self.odes = dict()
305
+
306
+ self.odes["Euler "] = asc.EulerSolverConstrained( multi , self.pset , dt , costrs )
307
+ self.odes["Runge Kutta"] = rkc.RungeKuttaSolverConstrained( multi , self.pset , dt , costrs )
308
+ self.odes["Leap Frog "] = lpc.LeapfrogSolverConstrained( multi , self.pset , dt , costrs )
309
+ self.odes["MidPoint "] = mdc.MidpointSolverConstrained( multi , self.pset , dt , costrs )
310
+ self.odes["Verlet "] = svc.StormerVerletSolverConstrained( multi , self.pset , dt , costrs )
@@ -0,0 +1,33 @@
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 glob
19
+ import os
20
+ import sys
21
+
22
+ import pyparticles.animation as _animation
23
+ from pyparticles.animation import animated_ogl_compat as _animated_ogl_compat
24
+
25
+ # All official demos were written against the legacy animated_ogl module.
26
+ # Route both the module cache and package attribute to the modern FreeGLUT
27
+ # compatibility layer. animated_ogl_compat itself keeps a private reference
28
+ # to the original renderer.
29
+ _animation.animated_ogl = _animated_ogl_compat
30
+ sys.modules["pyparticles.animation.animated_ogl"] = _animated_ogl_compat
31
+
32
+ __all__ = [ os.path.splitext( os.path.basename(f) )[0] for f in glob.glob(os.path.dirname(os.path.abspath(__file__))+"/*.py")]
33
+
@@ -0,0 +1,106 @@
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
+
19
+ import pyparticles.pset.particles_set as ps
20
+ import pyparticles.pset.opencl_context as occ
21
+ import pyparticles.pset.rand_cluster as rc
22
+ import pyparticles.pset.rebound_boundary as rb
23
+
24
+ import pyparticles.forces.pseudo_bubble as pb
25
+ import pyparticles.forces.const_force as cf
26
+ import pyparticles.forces.drag as dr
27
+ import pyparticles.forces.multiple_force as mf
28
+
29
+ import pyparticles.ode.stormer_verlet_solver as svs
30
+
31
+ import pyparticles.animation.animated_ogl as aogl
32
+
33
+ from pyparticles.utils.pypart_global import test_pyopencl
34
+
35
+
36
+ def bubble():
37
+ """Pseudo bubble simulation."""
38
+ ocl_ok = test_pyopencl()
39
+
40
+ if ocl_ok:
41
+ pcnt = 9000
42
+ r_min = 0.5
43
+ else:
44
+ pcnt = 700
45
+ r_min = 1.5
46
+
47
+ steps = 1000000
48
+ dt = 0.01
49
+
50
+ pset = ps.ParticlesSet(pcnt, dtype=np.float32)
51
+ rand_c = rc.RandCluster()
52
+ rand_c.insert3(
53
+ X=pset.X,
54
+ M=pset.M,
55
+ start_indx=0,
56
+ n=pset.size,
57
+ radius=3.0,
58
+ mass_rng=(0.5, 0.8),
59
+ r_min=0.0,
60
+ )
61
+
62
+ if ocl_ok:
63
+ occx = occ.OpenCLcontext(
64
+ pset.size,
65
+ pset.dim,
66
+ occ.OCLC_X | occ.OCLC_V | occ.OCLC_A | occ.OCLC_M,
67
+ )
68
+ bubble_force = pb.PseudoBubbleOCL(
69
+ pset.size,
70
+ pset.dim,
71
+ Consts=(r_min, 10),
72
+ ocl_context=occx,
73
+ )
74
+ drag = dr.DragOCL(
75
+ pset.size,
76
+ pset.dim,
77
+ Consts=0.01,
78
+ ocl_context=occx,
79
+ )
80
+ else:
81
+ bubble_force = pb.PseudoBubble(pset.size, pset.dim, Consts=(r_min, 10))
82
+ drag = dr.Drag(pset.size, pset.dim, Consts=0.01)
83
+
84
+ constf = cf.ConstForce(pset.size, dim=pset.dim, u_force=[0, 0, -10.0])
85
+
86
+ multif = mf.MultipleForce(pset.size, pset.dim)
87
+ multif.append_force(bubble_force)
88
+ multif.append_force(constf)
89
+ multif.append_force(drag)
90
+ multif.set_masses(pset.M)
91
+
92
+ solver = svs.StormerVerletSolver(multif, pset, dt)
93
+
94
+ pset.set_boundary(rb.ReboundBoundary(bound=(-5.0, 5.0)))
95
+
96
+ a = aogl.AnimatedGl()
97
+ a.ode_solver = solver
98
+ a.pset = pset
99
+ a.steps = steps
100
+
101
+ if ocl_ok:
102
+ a.draw_particles.set_draw_model(a.draw_particles.DRAW_MODEL_VECTOR)
103
+
104
+ a.init_rotation(-80, [0.7, 0.05, 0])
105
+ a.build_animation()
106
+ a.start()
@@ -0,0 +1,128 @@
1
+ # PyParticles : Particles simulation in python
2
+ # Copyright (C) 2012 Simone Riva mail: 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
+
18
+ import numpy as np
19
+
20
+ import pyparticles.pset.particles_set as ps
21
+ import pyparticles.pset.default_boundary as db
22
+
23
+ import pyparticles.forces.electromagnetic_field as elmf
24
+
25
+ import pyparticles.ode.euler_solver as els
26
+ import pyparticles.ode.leapfrog_solver as lps
27
+ import pyparticles.ode.runge_kutta_solver as rks
28
+ import pyparticles.ode.stormer_verlet_solver as svs
29
+ import pyparticles.ode.midpoint_solver as mds
30
+
31
+ import pyparticles.animation.animated_ogl as aogl
32
+ import pyparticles.ogl.draw_particles_ogl as drp
33
+
34
+ def electric_field( E , X ):
35
+ E[:] = np.array( [ 10 , 10 , 10 ] )
36
+
37
+
38
+ def magnetic_field( B , X ):
39
+ #B[:] = 1000.0 * np.sin( 500.0 * X )
40
+ B[:] = np.array( [ 0 , 0 , 1000 ] )
41
+
42
+
43
+ def magf_color( RGBA , X ):
44
+ RGBA[:] = np.array([ 0.4 , 0.4 , 1.0 , 0.6 ])
45
+
46
+ def elf_color( RGBA , X ):
47
+ RGBA[:] = np.array([ 0.4 , 1.0 , 0.4 , 0.6 ])
48
+
49
+ def default_pos( pset , indx ):
50
+ pset.X[indx,:] = 0.0
51
+ pset.V[indx,:] = ( ( np.random.rand( len(indx) , 3 ) - 0.5 ) / 3.0 )
52
+
53
+
54
+ def electromag_field():
55
+ """
56
+ Electrimagnetic field demo
57
+ """
58
+
59
+ steps = 1000000
60
+ size = 25000
61
+ dt = 1e-4
62
+
63
+ qe = 1.60217646e-19
64
+
65
+ me = 9.10938188e-31
66
+ mp = 1.67262158e-18
67
+
68
+ pset = ps.ParticlesSet( size , charge=True )
69
+
70
+ pset.X[:] = 10.0e-3 * ( ( 2.0*np.random.rand( size , 3 ) - 1.0 ) )
71
+
72
+ pset.Q[:] = qe * np.sign( np.random.rand( size , 1 ) - 0.5 )
73
+
74
+ pset.V[:] = 0.5 * ( ( np.random.rand( size , 3 ) - 0.5 ) / 2.0 )
75
+
76
+ pset.M[:] = mp
77
+
78
+ elmag = elmf.ElectromagneticField( pset.size , dim=pset.dim , m=pset.M , q=pset.Q )
79
+
80
+ elmag.append_electric_field( electric_field )
81
+ elmag.append_magnetic_field( magnetic_field )
82
+
83
+ #solver = els.EulerSolver( elmag , pset , dt )
84
+ #solver = lps.LeapfrogSolver( elmag , pset , dt )
85
+ #solver = svs.StormerVerletSolver( elmag , pset , dt )
86
+ #solver = rks.RungeKuttaSolver( elmag , pset , dt )
87
+ solver = mds.MidpointSolver( elmag , pset , dt )
88
+
89
+ pset.unit = 2e-3
90
+ pset.mass_unit = 1e-3
91
+
92
+ bound = db.DefaultBoundary( ( -pset.unit*5.0 , pset.unit*5.0 ) , dim=3 , defualt_pos=default_pos )
93
+ pset.set_boundary(bound)
94
+
95
+ pset.enable_log( True , log_max_size=200 )
96
+
97
+ solver.update_force()
98
+
99
+ a = aogl.AnimatedGl()
100
+
101
+ a.ode_solver = solver
102
+
103
+ a.trajectory = False
104
+
105
+ a.xlim = ( -pset.unit*5.0 , pset.unit*5.0 )
106
+ a.ylim = ( -pset.unit*5.0 , pset.unit*5.0 )
107
+ a.zlim = ( -pset.unit*5.0 , pset.unit*5.0 )
108
+
109
+ a.add_vector_field_fun( magnetic_field , 2000.0 , pset.unit , color_fun=magf_color )
110
+ a.add_vector_field_fun( electric_field , 50.0 , pset.unit , color_fun=elf_color )
111
+
112
+ a.draw_vector_field = False
113
+
114
+ a.pset = pset
115
+ a.steps = steps
116
+
117
+ a.draw_particles.color_fun = drp.charged_particles_color
118
+
119
+ a.draw_particles.vect_color_fun = drp.charged_particles_vect_color
120
+
121
+ a.draw_particles.set_draw_model( a.draw_particles.DRAW_MODEL_VECTOR )
122
+
123
+ a.build_animation()
124
+
125
+ a.start()
126
+
127
+ return
128
+
@@ -0,0 +1,126 @@
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
+
19
+ import pyparticles.pset.particles_set as ps
20
+
21
+ import pyparticles.forces.electrostatic as esf
22
+
23
+ import pyparticles.ode.euler_solver as els
24
+ import pyparticles.ode.leapfrog_solver as lps
25
+ import pyparticles.ode.runge_kutta_solver as rks
26
+ import pyparticles.ode.stormer_verlet_solver as svs
27
+ import pyparticles.ode.midpoint_solver as mds
28
+
29
+ import pyparticles.measures.kinetic_energy as ke
30
+ import pyparticles.measures.total_energy as te
31
+
32
+ import pyparticles.pset.rand_cluster as rc
33
+ import pyparticles.pset.rebound_boundary as rb
34
+
35
+ import pyparticles.animation.animated_ogl as aogl
36
+ import pyparticles.ogl.draw_particles_ogl as drp
37
+
38
+ import sys
39
+
40
+ def electro():
41
+ """
42
+ Electrostatic demo
43
+ """
44
+
45
+ steps = 1000000
46
+ dt = 0.01
47
+
48
+ r_min=1.5
49
+
50
+ Ke = 8.9875517873681764e9
51
+ qe = 1.60217646e-19 * 1.0e8
52
+
53
+ me = 9.10938188e-31
54
+ mp = 1.67262158e-18
55
+
56
+ rand_c = rc.RandCluster()
57
+
58
+ pset = ps.ParticlesSet( 10 , charge=True )
59
+
60
+ pset.Q[:5] = qe
61
+ pset.Q[5:10] = -qe
62
+
63
+ pset.M[:] = 1e-3
64
+
65
+ pset.V[:] = 0.0
66
+
67
+ pset.X[:] = 1.0e-3 * np.array( [
68
+ [ 0.0 , 0.0 , 0.0 ] ,
69
+ [ 0.0 , 0.0 , 1.0 ] ,
70
+ [ 0.0 , 0.0 , -1.0 ] ,
71
+ [ 0.0 , 1.0 , 1.0 ] ,
72
+ [ -1.0 , -1.0 , -1.0 ] ,
73
+ [ 2.0 , -2.0 , 4.0 ] ,
74
+ [ 4.0 , 7.0 , 2.0 ] ,
75
+ [ -3.0 , -5.0 , 1.0 ] ,
76
+ [ 4.0 , 4.0 , -7.0 ] ,
77
+ [ 2.0 , 8.0 , -6.0 ]
78
+ ]
79
+ )
80
+
81
+ #rand_c.insert3( X=pset.X ,
82
+ # M=pset.M ,
83
+ # start_indx=0 ,
84
+ # n=pset.size ,
85
+ # radius=5.0 ,
86
+ # mass_rng=(0.5,0.8) ,
87
+ # r_min=0.0 )
88
+
89
+ elecs = esf.Electrostatic( pset.size , dim=3 , Consts=Ke )
90
+
91
+
92
+ elecs.set_masses( pset.M )
93
+ elecs.set_charges( pset.Q )
94
+
95
+ #solver = els.EulerSolver( multif , pset , dt )
96
+ #solver = lps.LeapfrogSolver( lennard_jones , pset , dt )
97
+ #solver = svs.StormerVerletSolver( multif , pset , dt )
98
+ solver = rks.RungeKuttaSolver( elecs , pset , dt )
99
+ #solver = mds.MidpointSolver( lennard_jones , pset , dt )
100
+
101
+ bound = rb.ReboundBoundary( bound=( -10.0e-3 , 10.0e-3 ) )
102
+ pset.set_boundary( bound )
103
+
104
+ pset.unit = 2e-3
105
+ pset.mass_unit = 1e-3
106
+
107
+ pset.enable_log( True , log_max_size=1000 )
108
+
109
+ solver.update_force()
110
+
111
+ a = aogl.AnimatedGl()
112
+
113
+ a.ode_solver = solver
114
+
115
+ a.trajectory = True
116
+
117
+ a.pset = pset
118
+ a.steps = steps
119
+
120
+ a.draw_particles.color_fun = drp.charged_particles_color
121
+
122
+ a.build_animation()
123
+
124
+ a.start()
125
+
126
+ return