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,222 @@
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.gravity as gr
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.animation.animated_ogl as aogl
33
+
34
+
35
+ def solar_system():
36
+ """
37
+ Solar system demo
38
+ """
39
+ dt = 3.0*3600.0
40
+ steps = 1000000
41
+
42
+ G = 6.67384e-11
43
+
44
+ FLOOR = -10
45
+ CEILING = 10
46
+
47
+ pset = ps.ParticlesSet( 12 , 3 , label=True )
48
+
49
+ pset.label[0] = "Sun"
50
+ pset.label[1] = "Earth"
51
+ pset.label[2] = "Jupiter"
52
+ pset.label[3] = "Mars"
53
+ pset.label[4] = "Mercury"
54
+ pset.label[5] = "Neptune"
55
+ pset.label[6] = "Pluto"
56
+ pset.label[7] = "Saturn"
57
+ pset.label[8] = "Uranus"
58
+ pset.label[9] = "Venus"
59
+ pset.label[10] = "Ceres"
60
+ pset.label[11] = "Moon"
61
+
62
+
63
+ # Coordinates
64
+ pset.X[:] = np.array( [
65
+ [ 0.00000000e+00 , 0.00000000e+00 , 0.00000000e+00], # Sun
66
+ [ 1.49597871e+11 , 0.00000000e+00 , 0.00000000e+00], # Earth
67
+ [ 7.78357721e+11 , 0.00000000e+00 , 0.00000000e+00], # Jupiter
68
+ [ 2.27987155e+11 , 0.00000000e+00 , 0.00000000e+00], # Mars
69
+ [ 5.83431696e+10 , 0.00000000e+00 , 0.00000000e+00], # Mercury
70
+ [ 4.49691199e+12 , 0.00000000e+00 , 0.00000000e+00], # Neptune
71
+ [ 5.91360383e+12 , 0.00000000e+00 , 0.00000000e+00], # Pluto
72
+ [ 1.42701409e+12 , 0.00000000e+00 , 0.00000000e+00], # Saturn
73
+ [ 2.86928716e+12 , 0.00000000e+00 , 0.00000000e+00], # Uranus
74
+ [ 1.04718509e+11 , 0.00000000e+00 , 0.00000000e+00], # Venus
75
+ [ 4.138325875e+11, 0.00000000e+00 , 0.00000000e+00], # Ceres
76
+ [ 1.499604410e+11, 0.00000000e+00 , 0.00000000e+00] # Moon
77
+ ])
78
+
79
+
80
+ # Mass
81
+ pset.M[:] = np.array( [
82
+ [ 1.98910000e+30] ,
83
+ [ 5.98000000e+24] ,
84
+ [ 1.90000000e+27] ,
85
+ [ 6.42000000e+23] ,
86
+ [ 3.30000000e+23] ,
87
+ [ 1.02000000e+26] ,
88
+ [ 1.29000000e+22] ,
89
+ [ 5.69000000e+26] ,
90
+ [ 8.68000000e+25] ,
91
+ [ 4.87000000e+24] ,
92
+ [ 9.43000000e+20] ,
93
+ [ 7.34770000e+22]
94
+ ] )
95
+
96
+ # Speed
97
+ pset.V[:] = np.array( [ [ 0. , 0. , 0.] ,
98
+ [ 0. , 29800. , 0.] ,
99
+ [ 0. , 13100. , 0.] ,
100
+ [ 0. , 24100. , 0.] ,
101
+ [ 0. , 47900. , 0.] ,
102
+ [ 0. , 5400. , 0.] ,
103
+ [ 0. , 4700. , 0.] ,
104
+ [ 0. , 9600. , 0.] ,
105
+ [ 0. , 6800. , 0.] ,
106
+ [ 0. , 35000. , 0.] ,
107
+ [ 0 , 17882. , 0.] ,
108
+ [ 0 , 30822. , 0.]
109
+ ] )
110
+
111
+ # Inclination
112
+ incl = np.array([ 0.0 ,
113
+ 0.0 ,
114
+ 1.305 ,
115
+ 1.850 ,
116
+ 7.005 ,
117
+ 1.767975,
118
+ 17.151 ,
119
+ 2.485 ,
120
+ 0.772 ,
121
+ 3.394 ,
122
+ 10.587 ,
123
+ 0.0 ,
124
+ ])
125
+
126
+ # Longitude of the ascending node
127
+ lan = np.array([ 0.0 ,
128
+ 348.73936 ,
129
+ 100.492 ,
130
+ 49.562 ,
131
+ 48.331 ,
132
+ 131.794310 ,
133
+ 110.286 ,
134
+ 113.642 ,
135
+ 73.989 ,
136
+ 76.678 ,
137
+ 80.3932 ,
138
+ 348.73936
139
+ ])
140
+
141
+
142
+
143
+ incl[:] = incl * 2.0*np.pi / 360.0
144
+
145
+ lan[:] = lan * 2.0*np.pi / 360.0
146
+
147
+ pset.V[:,2] = np.sin( incl ) * pset.V[:,1]
148
+ pset.V[:,1] = np.cos( incl ) * pset.V[:,1]
149
+
150
+ for i in range ( pset.V.shape[0] ) :
151
+ x = pset.V[i,0]
152
+ y = pset.V[i,1]
153
+
154
+ pset.V[i,0] = x * np.cos( lan[i] ) - y * np.sin( lan[i] )
155
+ pset.V[i,1] = x * np.sin( lan[i] ) + y * np.cos( lan[i] )
156
+
157
+
158
+ for i in range ( pset.X.shape[0] ) :
159
+ x = pset.X[i,0]
160
+ y = pset.X[i,1]
161
+
162
+ pset.X[i,0] = x * np.cos( lan[i] ) - y * np.sin( lan[i] )
163
+ pset.X[i,1] = x * np.sin( lan[i] ) + y * np.cos( lan[i] )
164
+
165
+
166
+ #outf = fc.FileCluster()
167
+ #outf.open( "solar_system.csv" , "wb" )
168
+ #outf.write_out( pset )
169
+
170
+
171
+ pset.unit = 149597870700.0
172
+ pset.mass_unit = 5.9736e24
173
+
174
+ grav = gr.Gravity( pset.size , Consts=G )
175
+
176
+ grav.set_masses( pset.M )
177
+
178
+
179
+ bound = None
180
+
181
+ pset.set_boundary( bound )
182
+
183
+ pset.enable_log( True , log_max_size=1000 )
184
+
185
+ grav.update_force( pset )
186
+
187
+ #solver = els.EulerSolver( grav , pset , dt )
188
+ #solver = lps.LeapfrogSolver( grav , pset , dt )
189
+ #solver = svs.StormerVerletSolver( grav , pset , dt )
190
+ #solver = rks.RungeKuttaSolver( grav , pset , dt )
191
+ solver = mds.MidpointSolver( grav , pset , dt )
192
+
193
+
194
+ ken = ke.KineticEnergy( pset , grav )
195
+ ken.set_str_format( "%e" )
196
+
197
+ #
198
+ ken.update_measure()
199
+
200
+ a = aogl.AnimatedGl()
201
+ # a = anim.AnimatedScatter()
202
+
203
+ a.trajectory = True
204
+ a.trajectory_step = 1
205
+
206
+
207
+ a.xlim = ( FLOOR , CEILING )
208
+ a.ylim = ( FLOOR , CEILING )
209
+ a.zlim = ( FLOOR , CEILING )
210
+
211
+ a.ode_solver = solver
212
+ a.pset = pset
213
+ a.steps = steps
214
+
215
+ a.add_measure( ken )
216
+
217
+
218
+ a.build_animation()
219
+
220
+ a.start()
221
+
222
+ return
@@ -0,0 +1,141 @@
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.linear_spring as ls
22
+ import pyparticles.forces.const_force as cf
23
+ import pyparticles.forces.multiple_force as mf
24
+ import pyparticles.forces.drag as dr
25
+
26
+ import pyparticles.pset.rebound_boundary as rb
27
+
28
+ import pyparticles.measures.elastic_potential_energy as epe
29
+ import pyparticles.measures.kinetic_energy as ke
30
+ import pyparticles.measures.momentum as mm
31
+ import pyparticles.measures.total_energy as te
32
+
33
+
34
+
35
+ import pyparticles.ode.euler_solver as els
36
+ import pyparticles.ode.leapfrog_solver as lps
37
+ import pyparticles.ode.runge_kutta_solver as rks
38
+ import pyparticles.ode.stormer_verlet_solver as svs
39
+ import pyparticles.ode.midpoint_solver as mds
40
+
41
+ import sys
42
+
43
+ import pyparticles.animation.animated_ogl as aogl
44
+
45
+
46
+ def springs() :
47
+ """
48
+ Springs demo
49
+ """
50
+
51
+ dt = 0.02
52
+ steps = 1000000
53
+
54
+ G = 0.5
55
+
56
+ pset = ps.ParticlesSet( 3 , 3 , label=True )
57
+
58
+ pset.label[0] = "1"
59
+ pset.label[1] = "2"
60
+ pset.label[2] = "3"
61
+
62
+ pset.X[:] = np.array( [
63
+ [ 2.0 , 4.0 , 1.0 ], # 1
64
+ [ -2.0 , -2.0 , 1.0 ], # 2
65
+ [ 3.0 , -3.0 , 2.0 ] # 3
66
+ ] )
67
+
68
+ pset.M[:] = np.array( [
69
+ [ 1.0 ] ,
70
+ [ 1.0 ] ,
71
+ [ 1.5 ]
72
+ ] )
73
+
74
+ pset.V[:] = np.array( [ [ 0. , 0. , 0.] ,
75
+ [ 0. , 0 , 0.] ,
76
+ [ 0. , 0 , 0.]
77
+ ] )
78
+
79
+
80
+ springs = ls.LinearSpring( pset.size , Consts=G )
81
+ constf = cf.ConstForce( pset.size , u_force=[ 0,0,-1.5 ] )
82
+ drag = dr.Drag( pset.size , Consts=0.2 )
83
+
84
+ mlf = mf.MultipleForce( pset.size , 3 )
85
+
86
+ mlf.append_force( springs )
87
+ #mlf.append_force( constf )
88
+ #mlf.append_force( drag )
89
+
90
+ pot = epe.ElasticPotentialEnergy( pset , springs )
91
+ ken = ke.KineticEnergy( pset , springs )
92
+ tot = te.TotalEnergy( ken , pot )
93
+
94
+ #
95
+ pot.update_measure()
96
+ ken.update_measure()
97
+ tot.update_measure()
98
+
99
+ #
100
+ #print( "Potential = %f " % pot.value() )
101
+ #print( "Kinetic = %f " % ken.value() )
102
+
103
+ #P = mm.MomentumParticles( pset , subset=np.array([1,2]) , model="part_by_part")
104
+ #
105
+ #P.update_measure()
106
+ #
107
+ #print( P.value() )
108
+
109
+ bound = rb.ReboundBoundary( bound=(-10,10) )
110
+ pset.set_boundary( bound )
111
+
112
+ mlf.set_masses( pset.M )
113
+ springs.set_masses( pset.M )
114
+
115
+ springs.update_force( pset )
116
+ mlf.update_force( pset )
117
+
118
+ #solver = rks.RungeKuttaSolver( springs , pset , dt )
119
+ solver = rks.RungeKuttaSolver( mlf , pset , dt )
120
+
121
+ pset.enable_log( True , log_max_size=1000 )
122
+
123
+
124
+ a = aogl.AnimatedGl()
125
+
126
+ a.trajectory = True
127
+ a.trajectory_step = 1
128
+
129
+ a.ode_solver = solver
130
+ a.pset = pset
131
+ a.steps = steps
132
+
133
+ a.add_measure( ken )
134
+ a.add_measure( pot )
135
+ a.add_measure( tot )
136
+
137
+ a.build_animation()
138
+
139
+ a.start()
140
+
141
+ return
@@ -0,0 +1,135 @@
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
+
19
+ import numpy as np
20
+
21
+ import pyparticles.pset.particles_set as ps
22
+
23
+ import pyparticles.forces.linear_spring_constrained as lsc
24
+
25
+ import pyparticles.forces.const_force as cf
26
+ import pyparticles.forces.multiple_force as mf
27
+ import pyparticles.forces.drag as dr
28
+ import pyparticles.forces.damping as da
29
+
30
+ import pyparticles.pset.constrained_x as csx
31
+ import pyparticles.pset.constrained_force_interactions as cfi
32
+
33
+
34
+ import pyparticles.measures.elastic_potential_energy as epe
35
+ import pyparticles.measures.kinetic_energy as ke
36
+ import pyparticles.measures.momentum as mm
37
+ import pyparticles.measures.total_energy as te
38
+
39
+ import pyparticles.animation.animated_ogl as aogl
40
+
41
+ import pyparticles.ode.euler_solver_constrained as asc
42
+ import pyparticles.ode.leapfrog_solver_constrained as lpc
43
+ import pyparticles.ode.stormer_verlet_solver_constrained as svc
44
+ import pyparticles.ode.runge_kutta_solver_constrained as rkc
45
+ import pyparticles.ode.midpoint_solver_constrained as mdc
46
+
47
+
48
+ def spring_constr():
49
+ """
50
+ Constrained catenary springs demo
51
+ """
52
+
53
+ dt = 0.01
54
+ steps = 1000000
55
+
56
+ K = 30
57
+
58
+ x = list([])
59
+ m = list([])
60
+ #v = list([])
61
+
62
+ d = 0.1
63
+
64
+ ar = np.arange( -4.0 , 4.0+d , d )
65
+
66
+ for i in ar :
67
+ x.append( list( [i,i,3.0] ) )
68
+ m.append( list([ 1.0 / float( len(ar) ) ] ) )
69
+ #v.append( list([0.0]) )
70
+
71
+ pset = ps.ParticlesSet( len(ar) , 3 )
72
+
73
+ pset.X[:] = np.array( x , np.float64 )
74
+ pset.M[:] = np.array( m , np.float64 )
75
+ pset.V[:] = 0.0
76
+
77
+
78
+ pset.X[10:12,2] = 4
79
+ #pset.X[10:15,1] = 6
80
+
81
+ ci = np.array( [ 0 , len(ar)-1 ] )
82
+ cx = np.array( [
83
+ [ -4.0 , -4.0 , 3.0] ,
84
+ [ 4.0 , 4.0 , 3.0]
85
+ ] )
86
+
87
+ f_conn = list([])
88
+ for i in range( len(ar) - 1 ):
89
+ f_conn.append( list( [ i , i+1 ] ) )
90
+
91
+ f_conn = np.array( f_conn , np.float64 )
92
+
93
+ costrs = csx.ConstrainedX( pset )
94
+ costrs.add_x_constraint( ci , cx )
95
+
96
+ fi = cfi.ConstrainedForceInteractions( pset )
97
+
98
+ fi.add_connections( f_conn )
99
+
100
+ spring = lsc.LinearSpringConstrained( pset.size , pset.dim , pset.M , Consts=K , f_inter=fi )
101
+ constf = cf.ConstForce( pset.size , dim=pset.dim , u_force=[ 0 , 0 , -10 ] )
102
+ drag = dr.Drag( pset.size , pset.dim , Consts=0.003 )
103
+ #damp = da.Damping( pset.size , pset.dim , Consts=0.003 )
104
+
105
+ multif = mf.MultipleForce( pset.size , pset.dim )
106
+ multif.append_force( spring )
107
+ multif.append_force( constf )
108
+ multif.append_force( drag )
109
+
110
+ multif.set_masses( pset.M )
111
+
112
+ #solver = asc.EulerSolverConstrained( multif , pset , dt , costrs )
113
+ #solver = lpc.LeapfrogSolverConstrained( multif , pset , dt , costrs )
114
+ #solver = svc.StormerVerletSolverConstrained( multif , pset , dt , costrs )
115
+ #solver = rkc.RungeKuttaSolverConstrained( multif , pset , dt , costrs )
116
+ solver = mdc.MidpointSolverConstrained( multif , pset , dt , costrs )
117
+
118
+ a = aogl.AnimatedGl()
119
+
120
+ pset.enable_log( True , log_max_size=1000 )
121
+
122
+ a.trajectory = False
123
+ a.trajectory_step = 1
124
+
125
+ a.ode_solver = solver
126
+ a.pset = pset
127
+ a.steps = steps
128
+
129
+ a.init_rotation( -80 , [ 0.7 , 0.05 , 0 ] )
130
+
131
+ a.build_animation()
132
+
133
+ a.start()
134
+
135
+ return
@@ -0,0 +1,34 @@
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 pyparticles.animation.test_animation as tt
19
+
20
+ def test( ty ):
21
+ """
22
+ testing procedures
23
+
24
+ ty: test name
25
+ """
26
+ if ty == "fall":
27
+ tst = tt.TestAnimation()
28
+ elif ty == "harmonic" :
29
+ tst = tt.TestAnimationHarmonic()
30
+ elif ty == "dharmonic" :
31
+ tst = tt.TestAnimationDampedHarmonic()
32
+
33
+ tst.build_animation()
34
+ tst.start()
@@ -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,140 @@
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
+
11
+ import pyparticles.forces.force as fr
12
+ import pyparticles.pset.opencl_context as occ
13
+
14
+ try:
15
+ import pyopencl as cl
16
+ except ImportError:
17
+ cl = None
18
+
19
+
20
+ class ConstForce(fr.Force):
21
+ """Constant acceleration field."""
22
+
23
+ def __init__(self, size, dim=3, m=None, u_force=(0, 0, 0), Consts=1.0):
24
+ self.__dim = int(dim)
25
+ self.__size = int(size)
26
+ self.__G = Consts
27
+ self.__UF = np.asarray(u_force, dtype=float)
28
+ self.__A = np.zeros((size, dim))
29
+ self.__M = np.zeros((size, 1))
30
+ self.__A[:] = self.__UF
31
+
32
+ if m is not None:
33
+ self.set_masses(m)
34
+
35
+ def set_masses(self, m):
36
+ self.__M[:] = m
37
+
38
+ def update_force(self, p_set):
39
+ return self.__A
40
+
41
+ def getA(self):
42
+ return self.__A
43
+
44
+ A = property(getA)
45
+
46
+ def getF(self):
47
+ return self.__A * self.__M
48
+
49
+ F = property(getF)
50
+
51
+
52
+ class ConstForceOCL(fr.Force):
53
+ """Constant acceleration field accumulated directly in an OpenCL A buffer."""
54
+
55
+ def __init__(self, size, dim=3, m=None, u_force=(0, 0, 0), Consts=1.0, ocl_context=None):
56
+ if cl is None:
57
+ raise RuntimeError("PyOpenCL is required for ConstForceOCL")
58
+ if int(dim) != 3:
59
+ raise ValueError("ConstForceOCL currently supports only 3 dimensions")
60
+
61
+ self.__size = int(size)
62
+ self.__dim = int(dim)
63
+ self.__occ = ocl_context or occ.OpenCLcontext(size, dim, occ.OCLC_A | occ.OCLC_M)
64
+ self.__dtype = self.__occ.dtype
65
+ self.__UF = np.asarray(u_force, dtype=self.__dtype).reshape(3)
66
+ self.__A = np.zeros((size, dim), dtype=self.__dtype)
67
+ self.__M = np.zeros((size, 1), dtype=self.__dtype)
68
+
69
+ source = r"""
70
+ __kernel void const_force(
71
+ float ax,
72
+ float ay,
73
+ float az,
74
+ int accumulate,
75
+ __global float *A)
76
+ {
77
+ int i = get_global_id(0);
78
+ int i0 = 3*i;
79
+ int i1 = i0 + 1;
80
+ int i2 = i0 + 2;
81
+
82
+ if (accumulate)
83
+ {
84
+ A[i0] += ax;
85
+ A[i1] += ay;
86
+ A[i2] += az;
87
+ }
88
+ else
89
+ {
90
+ A[i0] = ax;
91
+ A[i1] = ay;
92
+ A[i2] = az;
93
+ }
94
+ }
95
+ """
96
+ self.__program = cl.Program(self.__occ.CL_context, source).build()
97
+ self.__kernel = cl.Kernel(self.__program, "const_force")
98
+
99
+ if m is not None:
100
+ self.set_masses(m)
101
+
102
+ def set_masses(self, m):
103
+ self.__M[:] = np.asarray(m, dtype=self.__dtype)
104
+ if self.__occ.M_cla is not None:
105
+ self.__occ.set_from_host("M", self.__M)
106
+
107
+ def update_force_device(self, p_set=None, accumulate=False, host_authoritative=False):
108
+ self.__kernel(
109
+ self.__occ.CL_queue,
110
+ (self.__size,),
111
+ None,
112
+ self.__dtype(self.__UF[0]),
113
+ self.__dtype(self.__UF[1]),
114
+ self.__dtype(self.__UF[2]),
115
+ np.int32(bool(accumulate)),
116
+ self.__occ.A_cla.data,
117
+ )
118
+ self.__occ.mark_device_modified("A")
119
+ return self.__occ.A_cla
120
+
121
+ def update_force(self, p_set):
122
+ self.update_force_device(p_set, accumulate=False)
123
+ self.__occ.sync_to_host("A", self.__A)
124
+ return self.__A
125
+
126
+ def getA(self):
127
+ return self.__A
128
+
129
+ A = property(getA)
130
+
131
+ def getF(self):
132
+ self.__occ.sync_to_host("A", self.__A)
133
+ return self.__A * self.__M
134
+
135
+ F = property(getF)
136
+
137
+ def get_ocl_context(self):
138
+ return self.__occ
139
+
140
+ ocl_context = property(get_ocl_context)