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,608 @@
|
|
|
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 matplotlib.animation as animation
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
from mpl_toolkits.mplot3d import Axes3D
|
|
23
|
+
import matplotlib.pyplot as plt
|
|
24
|
+
import matplotlib
|
|
25
|
+
import numpy as np
|
|
26
|
+
|
|
27
|
+
import pyparticles.animation.animated_scatter as anim
|
|
28
|
+
|
|
29
|
+
import pyparticles.pset.particles_set as ps
|
|
30
|
+
|
|
31
|
+
import pyparticles.animation as pan
|
|
32
|
+
|
|
33
|
+
import pyparticles.pset.rand_cluster as clu
|
|
34
|
+
import pyparticles.forces.gravity as gr
|
|
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
|
+
|
|
40
|
+
import pyparticles.ode.midpoint_solver as mds
|
|
41
|
+
|
|
42
|
+
import numpy as np
|
|
43
|
+
import pyparticles.pset.periodic_boundary as pb
|
|
44
|
+
import pyparticles.pset.rebound_boundary as rb
|
|
45
|
+
import pyparticles.forces.const_force as cf
|
|
46
|
+
import pyparticles.forces.vector_field_force as vf
|
|
47
|
+
import pyparticles.forces.linear_spring as ls
|
|
48
|
+
import pyparticles.pset.file_cluster as fc
|
|
49
|
+
|
|
50
|
+
import re
|
|
51
|
+
import sys
|
|
52
|
+
|
|
53
|
+
if sys.version_info[0] == 2:
|
|
54
|
+
import ConfigParser
|
|
55
|
+
else:
|
|
56
|
+
import configparser as ConfigParser
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
import pyparticles.animation.animated_ogl as aogl
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
Config file
|
|
65
|
+
===========
|
|
66
|
+
|
|
67
|
+
Config file description:
|
|
68
|
+
|
|
69
|
+
Section: pset_origin
|
|
70
|
+
--------------------
|
|
71
|
+
|
|
72
|
+
**Define the origin of the particles data set.**
|
|
73
|
+
|
|
74
|
+
**Varibles**
|
|
75
|
+
|
|
76
|
+
========================== ========================
|
|
77
|
+
Variable Description
|
|
78
|
+
========================== ========================
|
|
79
|
+
media_origin = [file|rand] Where data the is stored
|
|
80
|
+
file_name = <file> the dataset file name
|
|
81
|
+
========================== ========================
|
|
82
|
+
|
|
83
|
+
Section: set_config
|
|
84
|
+
-------------------
|
|
85
|
+
**Particles data set configauration**
|
|
86
|
+
|
|
87
|
+
**Varibles:**
|
|
88
|
+
|
|
89
|
+
=========================== ==============================================
|
|
90
|
+
Variable Description
|
|
91
|
+
=========================== ==============================================
|
|
92
|
+
len_unit = <number> How many meters is a unit
|
|
93
|
+
mass_unit = <number> How many Kg is a unit
|
|
94
|
+
boundary = [open|periodic|rebound] The boundary model used in the simulation
|
|
95
|
+
boundary_lim = <#> <#> Define the size of the boundary
|
|
96
|
+
sim_log = <number> The size of the log queue (0 disable the log)
|
|
97
|
+
sim_log_X = [True|False] If sim_log is enabled log the position
|
|
98
|
+
sim_log_V = [True|False] If sim_log is enabled log the velocities
|
|
99
|
+
rand_part_nr = <number> The total number of particles for a rand set
|
|
100
|
+
=========================== ==============================================
|
|
101
|
+
|
|
102
|
+
Note: len_unit & mass_unit are used only for drawing the particles
|
|
103
|
+
|
|
104
|
+
Section: model
|
|
105
|
+
--------------
|
|
106
|
+
**Simulation method and force model**
|
|
107
|
+
|
|
108
|
+
**Varibles:**
|
|
109
|
+
|
|
110
|
+
============================================================== =====================================
|
|
111
|
+
Variable Description
|
|
112
|
+
============================================================== =====================================
|
|
113
|
+
force = [gravity|linear_spring|constant_force] Force type used
|
|
114
|
+
ode_solver_name = [euler|runge_kutta|leap_frog|midpoint] Integration method
|
|
115
|
+
time_step = <number> time step used for the integration
|
|
116
|
+
force_const = <number> Force constant, like G
|
|
117
|
+
force_vector= <number> Force vector, for the constant force
|
|
118
|
+
============================================================== =====================================
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
Section: animation
|
|
122
|
+
------------------
|
|
123
|
+
**Simulation control & graphic wiew**
|
|
124
|
+
|
|
125
|
+
**Variables:**
|
|
126
|
+
|
|
127
|
+
============================================================== =================================================
|
|
128
|
+
Variable Description
|
|
129
|
+
============================================================== =================================================
|
|
130
|
+
animation_type = [opengl|matplotlib] Setup the output interface
|
|
131
|
+
draw_log = [True|False] Draw the simulation log (if enabled)
|
|
132
|
+
xlim = <number> <number> define the limit of the picture (sometime unused)
|
|
133
|
+
ylim = <number> <number>
|
|
134
|
+
zlim = <number> <number>
|
|
135
|
+
============================================================== =================================================
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
Example:
|
|
139
|
+
--------
|
|
140
|
+
::
|
|
141
|
+
|
|
142
|
+
[pset_origin]
|
|
143
|
+
media_origin = from_file
|
|
144
|
+
file_name = solar_sys.csv
|
|
145
|
+
|
|
146
|
+
[set_config]
|
|
147
|
+
len_unit = 149597870700.0
|
|
148
|
+
mass_unit = 5.9736e24
|
|
149
|
+
boundary = open
|
|
150
|
+
|
|
151
|
+
[model]
|
|
152
|
+
force = gravity
|
|
153
|
+
ode_solver_name = euler
|
|
154
|
+
time_step = 3600
|
|
155
|
+
steps = 1000000
|
|
156
|
+
force_const = 6.67384e-11
|
|
157
|
+
force_vector = 0 0 0
|
|
158
|
+
|
|
159
|
+
[animation]
|
|
160
|
+
animation_type = opengl
|
|
161
|
+
xlim = -5.0 5.0
|
|
162
|
+
ylim = -5.0 5.0
|
|
163
|
+
zlim = -5.0 5.0
|
|
164
|
+
|
|
165
|
+
"""
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
#ConfigParser.ConfigParser.add_comment = lambda self, section, option, value: self.set(section, '# '+option, value)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
class ParticlesConfig(object):
|
|
174
|
+
|
|
175
|
+
"""
|
|
176
|
+
Parse the config files used for generating the problems:
|
|
177
|
+
"""
|
|
178
|
+
def __init__(self):
|
|
179
|
+
|
|
180
|
+
self.file_name = ""
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
self.default = {
|
|
184
|
+
# section pset_origin
|
|
185
|
+
'media_origin': 'from_file' ,
|
|
186
|
+
'file_name': 'solar_sys.csv' ,
|
|
187
|
+
|
|
188
|
+
# section set_config
|
|
189
|
+
'len_unit': '149597870700.0' ,
|
|
190
|
+
'mass_unit': '5.9736e24' ,
|
|
191
|
+
'boundary': 'open' ,
|
|
192
|
+
'boundary_lim': '-7 7' ,
|
|
193
|
+
'sim_log': '0' ,
|
|
194
|
+
'sim_log_X': 'True' ,
|
|
195
|
+
'sim_log_V': 'False' ,
|
|
196
|
+
'rand_part_nr': '500' ,
|
|
197
|
+
|
|
198
|
+
# section model
|
|
199
|
+
'force': 'gravity' ,
|
|
200
|
+
'ode_solver_name': 'euler' ,
|
|
201
|
+
'time_step': '3600' ,
|
|
202
|
+
'steps': '1000000' ,
|
|
203
|
+
'force_const': '6.67384e-11' ,
|
|
204
|
+
'force_vector': '0 0 0' ,
|
|
205
|
+
|
|
206
|
+
# section animation
|
|
207
|
+
'animation_type': 'opengl' ,
|
|
208
|
+
'draw_trajectory': 'False' ,
|
|
209
|
+
'trajectory_step': '15' ,
|
|
210
|
+
'xlim': '-5.0 5.0' ,
|
|
211
|
+
'ylim': '-5.0 5.0' ,
|
|
212
|
+
'zlim': '-5.0 5.0' ,
|
|
213
|
+
|
|
214
|
+
# section rand_cluster_*
|
|
215
|
+
'rc_part_nr': '100' ,
|
|
216
|
+
'rc_centre': '0 0 0' ,
|
|
217
|
+
'rc_radius': '1.0' ,
|
|
218
|
+
'rc_mass_rng': '0.5 1.5' ,
|
|
219
|
+
'rc_vel_rng': '0.5 1.0' ,
|
|
220
|
+
'rc_vel_mdl': 'no' ,
|
|
221
|
+
'rc_vel_dir': '0 1 0' ,
|
|
222
|
+
'rc_r_min': '0.0' ,
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
def write_example_config_file( self , file_name='example_pyparticles_config.cfg' ):
|
|
226
|
+
""" Write a generic config file """
|
|
227
|
+
config = ConfigParser.ConfigParser()
|
|
228
|
+
|
|
229
|
+
config.add_section('pset_origin')
|
|
230
|
+
config.set('pset_origin', 'media_origin', 'from_file')
|
|
231
|
+
config.set('pset_origin', 'file_name', 'solar_sys.csv')
|
|
232
|
+
|
|
233
|
+
config.add_section('set_config')
|
|
234
|
+
config.set('set_config', 'len_unit', '149597870700.0')
|
|
235
|
+
config.set('set_config', 'mass_unit', '5.9736e24')
|
|
236
|
+
config.set('set_config', 'boundary', 'open')
|
|
237
|
+
config.set('set_config', 'boundary_lim', '-7 7')
|
|
238
|
+
config.set('set_config', 'sim_log', '0')
|
|
239
|
+
config.set('set_config', 'sim_log_X', 'True')
|
|
240
|
+
config.set('set_config', 'sim_log_V', 'False')
|
|
241
|
+
config.set('set_config', 'rand_part_nr', '500')
|
|
242
|
+
|
|
243
|
+
config.add_section('model')
|
|
244
|
+
config.set('model', 'force', 'gravity')
|
|
245
|
+
config.set('model', 'ode_solver_name', 'euler')
|
|
246
|
+
config.set('model', 'time_step', '3600')
|
|
247
|
+
config.set('model', 'steps', '1000000')
|
|
248
|
+
config.set('model', 'force_const', '6.67384e-11')
|
|
249
|
+
config.set('model' , 'force_vector' , '0 0 0' )
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
config.add_section('animation')
|
|
253
|
+
config.set('animation', 'animation_type', 'opengl')
|
|
254
|
+
config.set('animation', 'draw_trajectory', 'False')
|
|
255
|
+
config.set('animation', 'trajectory_step', '15')
|
|
256
|
+
config.set('animation', 'xlim', '-5.0 5.0')
|
|
257
|
+
config.set('animation', 'ylim', '-5.0 5.0')
|
|
258
|
+
config.set('animation', 'zlim', '-5.0 5.0')
|
|
259
|
+
|
|
260
|
+
config.add_section('rand_cluster_any')
|
|
261
|
+
config.set('rand_cluster_any', 'rc_part_nr', '100')
|
|
262
|
+
config.set('rand_cluster_any', 'rc_centre', '0 0 0')
|
|
263
|
+
config.set('rand_cluster_any', 'rc_radius', '1.0')
|
|
264
|
+
config.set('rand_cluster_any', 'rc_mass_rng', '0.5 1.0')
|
|
265
|
+
config.set('rand_cluster_any', 'rc_vel_rng', '0.5 1.0')
|
|
266
|
+
config.set('rand_cluster_any', 'rc_vel_mdl', 'bomb')
|
|
267
|
+
config.set('rand_cluster_any', 'rc_vel_dir', '0 1 0')
|
|
268
|
+
config.set('rand_cluster_any', 'rc_r_min', '0.0')
|
|
269
|
+
|
|
270
|
+
# Writing our configuration file to 'example.cfg'
|
|
271
|
+
with open( file_name , 'wb' ) as configfile:
|
|
272
|
+
config.write(configfile)
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
###################################################################
|
|
276
|
+
## read and parse config file
|
|
277
|
+
###################################################################
|
|
278
|
+
def read_config( self , file_name ):
|
|
279
|
+
"""
|
|
280
|
+
Read the configuration file
|
|
281
|
+
"""
|
|
282
|
+
|
|
283
|
+
self.file_name = file_name
|
|
284
|
+
|
|
285
|
+
config = ConfigParser.ConfigParser(self.default)
|
|
286
|
+
|
|
287
|
+
fp = None
|
|
288
|
+
|
|
289
|
+
try :
|
|
290
|
+
fp = open( file_name )
|
|
291
|
+
except IOError:
|
|
292
|
+
print(" Error - config file not fount: %s " % file_name )
|
|
293
|
+
exit()
|
|
294
|
+
|
|
295
|
+
config.readfp( fp )
|
|
296
|
+
|
|
297
|
+
#########################################################
|
|
298
|
+
## Section pset_origin
|
|
299
|
+
self.media_origin = config.get( 'pset_origin' , 'media_origin' )
|
|
300
|
+
self.pset_file_name = config.get( 'pset_origin' , 'file_name' )
|
|
301
|
+
|
|
302
|
+
#########################################################
|
|
303
|
+
## Section set_config
|
|
304
|
+
self.len_unit = config.getfloat( 'set_config' , 'len_unit' )
|
|
305
|
+
self.mass_unit = config.getfloat( 'set_config' , 'mass_unit' )
|
|
306
|
+
self.boudary = config.get( 'set_config' , 'boundary' )
|
|
307
|
+
self.boudary_lim = config.get( 'set_config' , 'boundary_lim' )
|
|
308
|
+
self.sim_log = config.getint( 'set_config' , 'sim_log' )
|
|
309
|
+
self.sim_log_X = config.getboolean( 'set_config' , 'sim_log_X' )
|
|
310
|
+
self.sim_log_V = config.getboolean( 'set_config' , 'sim_log_V' )
|
|
311
|
+
self.rand_part_nr= config.getint( 'set_config' , 'rand_part_nr' )
|
|
312
|
+
|
|
313
|
+
#########################################################
|
|
314
|
+
## Section model
|
|
315
|
+
self.force_name = config.get( 'model' , 'force' )
|
|
316
|
+
self.ode_solver_name = config.get( 'model' , 'ode_solver_name' )
|
|
317
|
+
self.time_step = config.getfloat( 'model' , 'time_step' )
|
|
318
|
+
self.steps = config.getint( 'model' , 'steps' )
|
|
319
|
+
self.force_const = config.get( 'model' , 'force_const' )
|
|
320
|
+
|
|
321
|
+
if self.force_name == "constant_force" :
|
|
322
|
+
self.force_vector = config.get( 'model' , 'force_vector' , '-1 0 0' )
|
|
323
|
+
|
|
324
|
+
###################################################################
|
|
325
|
+
## Section animation
|
|
326
|
+
self.animation_type = config.get( 'animation' , 'animation_type' )
|
|
327
|
+
self.draw_trajectory = config.getboolean( 'animation' , 'draw_trajectory' )
|
|
328
|
+
self.trajectory_step = config.getint( 'animation' , 'trajectory_step' )
|
|
329
|
+
|
|
330
|
+
def build_problem( self ):
|
|
331
|
+
"""
|
|
332
|
+
Build the main problem and return the four main objects:
|
|
333
|
+
return ( self.animation , self.pset , self.force , self.ode_solver )
|
|
334
|
+
"""
|
|
335
|
+
self.get_particle_set()
|
|
336
|
+
self.get_force()
|
|
337
|
+
self.get_ode_solver()
|
|
338
|
+
self.get_animation()
|
|
339
|
+
|
|
340
|
+
return ( self.animation , self.pset , self.force , self.ode_solver )
|
|
341
|
+
|
|
342
|
+
################################################################################
|
|
343
|
+
def get_particle_set( self ):
|
|
344
|
+
"""
|
|
345
|
+
Build and return a set of particles (class: particles_set)
|
|
346
|
+
"""
|
|
347
|
+
|
|
348
|
+
print("")
|
|
349
|
+
|
|
350
|
+
self.pset = ps.ParticlesSet()
|
|
351
|
+
|
|
352
|
+
if self.media_origin == "from_file" :
|
|
353
|
+
ff = fc.FileCluster()
|
|
354
|
+
ff.open( self.pset_file_name )
|
|
355
|
+
ff.insert3( self.pset )
|
|
356
|
+
ff.close()
|
|
357
|
+
print( " setup - particles set - file name: %s " % self.pset_file_name )
|
|
358
|
+
|
|
359
|
+
elif self.media_origin == "rand" :
|
|
360
|
+
self.pset.realloc( self.rand_part_nr , dim=3 )
|
|
361
|
+
self.__get_rand_clusters()
|
|
362
|
+
else:
|
|
363
|
+
print(" !! Error - particles set - media origin: %s don't exist " % self.media_origin )
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
print( " setup - particles set - size: %d " % self.pset.size )
|
|
367
|
+
print( " setup - particles set - dim: %d " % self.pset.dim )
|
|
368
|
+
|
|
369
|
+
self.pset.unit = self.len_unit
|
|
370
|
+
self.pset.mass_unit = self.mass_unit
|
|
371
|
+
|
|
372
|
+
print( " setup - particles set - len unit: %e " % self.pset.unit )
|
|
373
|
+
print( " setup - particles set - len mass unit: %e " % self.pset.mass_unit )
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
if self.boudary == "open" :
|
|
378
|
+
self.pset.boundary = None
|
|
379
|
+
print( " setup - particles set - Boundary: open " )
|
|
380
|
+
|
|
381
|
+
elif self.boudary == "periodic" :
|
|
382
|
+
bound = read_str_list( self.boudary_lim )
|
|
383
|
+
self.pset.boundary = pb.PeriodicBoundary( bound=bound , dim=self.pset.dim )
|
|
384
|
+
print( " setup - particles set - Boundary: periodic " )
|
|
385
|
+
print( " setup - particles set - Boundary size : %s " % (bound,) )
|
|
386
|
+
|
|
387
|
+
elif self.boudary == "rebound" :
|
|
388
|
+
bound = read_str_list( self.boudary_lim )
|
|
389
|
+
self.pset.boundary = rb.ReboundBoundary( bound=bound , dim=self.pset.dim )
|
|
390
|
+
print( " setup - particles set - Boundary: rebound " )
|
|
391
|
+
print( " setup - particles set - Boundary size : %s " % (bound,) )
|
|
392
|
+
|
|
393
|
+
if self.sim_log > 0 :
|
|
394
|
+
self.pset.enable_log( log_X=self.sim_log_X , log_V=self.sim_log_V , log_max_size=self.sim_log )
|
|
395
|
+
|
|
396
|
+
print( " setup - particles set - Simulation log size %d " % self.sim_log )
|
|
397
|
+
print( " setup - particles set - Simulation log : X = %r ; V = %r " % ( self.sim_log_X , self.sim_log_V ) )
|
|
398
|
+
|
|
399
|
+
#print( self.pset.X )
|
|
400
|
+
#print( self.pset.M )
|
|
401
|
+
#print( self.pset.V )
|
|
402
|
+
|
|
403
|
+
return self.pset
|
|
404
|
+
|
|
405
|
+
################################################################################
|
|
406
|
+
def get_force(self):
|
|
407
|
+
"""
|
|
408
|
+
Build and return an object for mdeling the force (derived form the abstract class force)
|
|
409
|
+
"""
|
|
410
|
+
print("")
|
|
411
|
+
|
|
412
|
+
self.force = None
|
|
413
|
+
|
|
414
|
+
if self.force_name == "gravity" :
|
|
415
|
+
self.force = gr.Gravity( self.pset.size , self.pset.dim , Consts=float(self.force_const) )
|
|
416
|
+
|
|
417
|
+
print( " setup - force - Type: Gravity " )
|
|
418
|
+
print( " setup - force - G: %e " % float(self.force_const) )
|
|
419
|
+
|
|
420
|
+
elif self.force_name == "linear_spring" :
|
|
421
|
+
self.force = ls.LinearSpring( self.pset.size , self.pset.dim , Consts=self.force_const )
|
|
422
|
+
|
|
423
|
+
print( " setup - force - Type: Linear spring " )
|
|
424
|
+
print( " setup - force - K: %e " % float(self.force_const) )
|
|
425
|
+
|
|
426
|
+
elif self.force_name == "constant_force" :
|
|
427
|
+
fv = read_str_list( self.force_vector )
|
|
428
|
+
|
|
429
|
+
self.force = cf.ConstForce( self.pset.size , dim=self.pset.dim , u_force=fv )
|
|
430
|
+
|
|
431
|
+
print( " setup - force - Type: Constant " )
|
|
432
|
+
print( " setup - force - Vect: %e %e %e " % ( float(fv[0]) , float(fv[1]) , float(fv[2]) ) )
|
|
433
|
+
|
|
434
|
+
self.force.set_masses( self.pset.M )
|
|
435
|
+
|
|
436
|
+
return self.force
|
|
437
|
+
|
|
438
|
+
################################################################################
|
|
439
|
+
def get_ode_solver(self):
|
|
440
|
+
"""
|
|
441
|
+
Build and return an object for solving the Newton Law of motion (derived form the abstract class ode_solver)
|
|
442
|
+
"""
|
|
443
|
+
print("")
|
|
444
|
+
|
|
445
|
+
self.ode_solver = None
|
|
446
|
+
|
|
447
|
+
if self.ode_solver_name == "euler" :
|
|
448
|
+
self.ode_solver = els.EulerSolver( self.force , self.pset , self.time_step )
|
|
449
|
+
|
|
450
|
+
print( " setup - Integration method: EULER " )
|
|
451
|
+
|
|
452
|
+
elif self.ode_solver_name == "runge_kutta" :
|
|
453
|
+
self.ode_solver = rks.RungeKuttaSolver( self.force , self.pset , self.time_step )
|
|
454
|
+
|
|
455
|
+
print( " setup - Integration method: Runge Kutta " )
|
|
456
|
+
|
|
457
|
+
elif self.ode_solver_name == "leap_frog" :
|
|
458
|
+
self.ode_solver = lps.LeapfrogSolver( self.force , self.pset , self.time_step )
|
|
459
|
+
|
|
460
|
+
print( " setup - Integration method: Leap Frog " )
|
|
461
|
+
|
|
462
|
+
elif self.ode_solver_name == "stormer_verlet" :
|
|
463
|
+
self.ode_solver = svs.StormerVerletSolver( self.force , self.pset , self.time_step )
|
|
464
|
+
|
|
465
|
+
print( " setup - Integration method: Stormer Verlet " )
|
|
466
|
+
|
|
467
|
+
elif self.ode_solver_name == "midpoint" :
|
|
468
|
+
self.ode_solver = mds.MidpointSolver( self.force , self.pset , self.time_step )
|
|
469
|
+
|
|
470
|
+
print( " setup - Integration method: Midpoint " )
|
|
471
|
+
|
|
472
|
+
print( " setup - Integration method - time step: %e " % self.time_step )
|
|
473
|
+
return self.ode_solver
|
|
474
|
+
|
|
475
|
+
################################################################################
|
|
476
|
+
def get_animation(self):
|
|
477
|
+
"""
|
|
478
|
+
Build an Animation object and return the reference to the object
|
|
479
|
+
"""
|
|
480
|
+
print("")
|
|
481
|
+
|
|
482
|
+
self.animation = None
|
|
483
|
+
|
|
484
|
+
if self.animation_type == "opengl" :
|
|
485
|
+
self.animation = aogl.AnimatedGl()
|
|
486
|
+
|
|
487
|
+
print(" setup - animation - type: OpenGL")
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
elif self.animation_type == "matplotlib" :
|
|
491
|
+
self.animation = anim.AnimatedScatter()
|
|
492
|
+
|
|
493
|
+
print(" setup - animation - type: MatPlotlib")
|
|
494
|
+
|
|
495
|
+
if self.draw_trajectory == True :
|
|
496
|
+
self.animation.trajectory = self.draw_trajectory
|
|
497
|
+
self.animation.trajectory_step = self.trajectory_step
|
|
498
|
+
|
|
499
|
+
print(" setup - animation - Draw trajectory : %r " % self.draw_trajectory )
|
|
500
|
+
print(" setup - animation - Trajectory step : %d " % self.trajectory_step )
|
|
501
|
+
if self.sim_log == 0 :
|
|
502
|
+
print(" !! Warning - animation - Trajectory will be not drawn: sim_log is disabled " )
|
|
503
|
+
|
|
504
|
+
self.animation.ode_solver = self.ode_solver
|
|
505
|
+
self.animation.pset = self.pset
|
|
506
|
+
self.animation.steps = self.steps
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
return self.animation
|
|
510
|
+
|
|
511
|
+
################################################################################
|
|
512
|
+
def __get_rand_clusters(self):
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
# 'rc_part_nr': '100' ,
|
|
516
|
+
# 'rc_centre': '0 0 0' ,
|
|
517
|
+
# 'rc_radius': '1.0' ,
|
|
518
|
+
# 'rc_mass_rng': '0.5 1.5' ,
|
|
519
|
+
# 'rc_vel_rng': '0.5 1.0' ,
|
|
520
|
+
# 'rc_vel_mdl': 'const' ,
|
|
521
|
+
# 'rc_vel_dir': '0 1 0' ,
|
|
522
|
+
|
|
523
|
+
config = ConfigParser.ConfigParser(self.default)
|
|
524
|
+
config.read( self.file_name )
|
|
525
|
+
|
|
526
|
+
indx = 0
|
|
527
|
+
|
|
528
|
+
l_sec = config.sections()
|
|
529
|
+
|
|
530
|
+
for se in l_sec :
|
|
531
|
+
m = re.search( r"(^rand_cluster_\w+)" , se )
|
|
532
|
+
|
|
533
|
+
if m != None :
|
|
534
|
+
sect = m.group(1)
|
|
535
|
+
print(" setup - rand cluster - name : %s " % sect )
|
|
536
|
+
|
|
537
|
+
rc_part_nr = config.getfloat( sect , 'rc_part_nr' )
|
|
538
|
+
print(" setup - rand cluster - size : %d " % rc_part_nr )
|
|
539
|
+
|
|
540
|
+
rc_centre = config.get ( sect , 'rc_centre' )
|
|
541
|
+
rc_centre = read_str_list ( rc_centre , to=float )
|
|
542
|
+
print(" setup - rand cluster - centre : %s " % (rc_centre,) )
|
|
543
|
+
|
|
544
|
+
rc_radius = config.getfloat( sect , 'rc_radius' )
|
|
545
|
+
print(" setup - rand cluster - radius : %f " % rc_radius )
|
|
546
|
+
|
|
547
|
+
rc_mass_rng = config.get ( sect , 'rc_mass_rng' )
|
|
548
|
+
rc_mass_rng = read_str_list ( rc_mass_rng , to=float )
|
|
549
|
+
print(" setup - rand cluster - mass range : %s " % (rc_mass_rng,) )
|
|
550
|
+
|
|
551
|
+
rc_vel_rng = config.get ( sect , 'rc_vel_rng' )
|
|
552
|
+
rc_vel_rng = read_str_list ( rc_vel_rng , to=float )
|
|
553
|
+
print(" setup - rand cluster - velocity range : %s " % (rc_vel_rng,) )
|
|
554
|
+
|
|
555
|
+
rc_vel_dir = config.get ( sect , 'rc_vel_dir' )
|
|
556
|
+
rc_vel_dir = read_str_list ( rc_vel_dir , to=float )
|
|
557
|
+
print(" setup - rand cluster - velocity direction : %s " % (rc_vel_dir,) )
|
|
558
|
+
|
|
559
|
+
rc_vel_mdl = config.get ( sect , 'rc_vel_mdl' )
|
|
560
|
+
print(" setup - rand cluster - velocity model : %s " % (rc_vel_mdl,) )
|
|
561
|
+
|
|
562
|
+
rc_r_min = config.getfloat( sect , 'rc_r_min' )
|
|
563
|
+
print(" setup - rand cluster - minimal dist : %f " % rc_r_min )
|
|
564
|
+
|
|
565
|
+
cs = clu.RandCluster()
|
|
566
|
+
|
|
567
|
+
if ( indx + rc_part_nr ) > self.pset.size :
|
|
568
|
+
print(" !! Error the total size of the rand clusters is too big")
|
|
569
|
+
exit()
|
|
570
|
+
|
|
571
|
+
cs.insert3( X=self.pset.X ,
|
|
572
|
+
M=self.pset.M ,
|
|
573
|
+
V=self.pset.V ,
|
|
574
|
+
start_indx=indx ,
|
|
575
|
+
n = int(rc_part_nr) ,
|
|
576
|
+
centre=rc_centre ,
|
|
577
|
+
vel_rng=rc_vel_rng ,
|
|
578
|
+
vel_mdl=rc_vel_mdl ,
|
|
579
|
+
vel_dir=rc_vel_dir ,
|
|
580
|
+
r_min=rc_r_min
|
|
581
|
+
)
|
|
582
|
+
|
|
583
|
+
indx += rc_part_nr
|
|
584
|
+
print("")
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
def read_str_list( string , to=float ):
|
|
588
|
+
|
|
589
|
+
a = re.split( "\s+" , string )
|
|
590
|
+
c = a.count( "" )
|
|
591
|
+
|
|
592
|
+
for i in range(c):
|
|
593
|
+
a.remove("")
|
|
594
|
+
|
|
595
|
+
r = []
|
|
596
|
+
for i in a :
|
|
597
|
+
r.append( to(i) )
|
|
598
|
+
|
|
599
|
+
return tuple(r)
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
|
|
607
|
+
|
|
608
|
+
|