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,49 @@
|
|
|
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
|
+
import pyparticles.ode.ode_solver_constrained as osc
|
|
20
|
+
|
|
21
|
+
class EulerSolverConstrained( osc.OdeSolverConstrained ) :
|
|
22
|
+
def __init__( self , force , p_set , dt , x_constraint=None , v_constraint=None ):
|
|
23
|
+
super(EulerSolverConstrained,self).__init__( force , p_set , dt , x_constraint=None , v_constraint=None )
|
|
24
|
+
|
|
25
|
+
if x_constraint != None :
|
|
26
|
+
self.x_constraint = x_constraint
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def get_x_constraint(self):
|
|
30
|
+
return super(EulerSolverConstrained,self).get_x_constraint()
|
|
31
|
+
|
|
32
|
+
def set_x_constraint(self , xc ):
|
|
33
|
+
super(EulerSolverConstrained,self).set_x_constraint( xc )
|
|
34
|
+
self.__free_inx = self.x_constraint.get_cx_free_indicies()
|
|
35
|
+
self.__csrt_inx = self.x_constraint.get_cx_indicies()
|
|
36
|
+
|
|
37
|
+
x_constraint = property( get_x_constraint , set_x_constraint , doc="get and set the current positionals constraints" )
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def __step__( self , dt ):
|
|
41
|
+
|
|
42
|
+
self.force.update_force( self.pset )
|
|
43
|
+
|
|
44
|
+
self.pset.V[self.__free_inx,:] = self.pset.V[self.__free_inx,:] + self.force.A[self.__free_inx,:] * dt
|
|
45
|
+
self.pset.X[self.__free_inx,:] = self.pset.X[self.__free_inx,:] + self.pset.V[self.__free_inx,:] * dt
|
|
46
|
+
|
|
47
|
+
self.pset.V[self.__csrt_inx,:] = 0.0
|
|
48
|
+
|
|
49
|
+
self.pset.update_boundary()
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
+
import pyparticles.ode.ode_solver as os
|
|
20
|
+
|
|
21
|
+
class LeapfrogSolver( os.OdeSolver ) :
|
|
22
|
+
def __init__( self , force , p_set , dt ):
|
|
23
|
+
super(LeapfrogSolver,self).__init__( force , p_set , dt )
|
|
24
|
+
self.__Ai = np.zeros( self.force.A.shape )
|
|
25
|
+
|
|
26
|
+
def __step__( self , dt ):
|
|
27
|
+
|
|
28
|
+
self.pset.X[:] = self.pset.X + self.pset.V * dt + 0.5*self.force.A * dt**2.0
|
|
29
|
+
self.__Ai[:] = self.force.A
|
|
30
|
+
|
|
31
|
+
self.force.update_force( self.pset )
|
|
32
|
+
|
|
33
|
+
self.pset.V[:] = self.pset.V + 0.5 * ( self.__Ai + self.force.A ) * dt
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
self.pset.update_boundary()
|
|
37
|
+
|
|
@@ -0,0 +1,53 @@
|
|
|
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
|
+
import pyparticles.ode.ode_solver_constrained as osc
|
|
20
|
+
|
|
21
|
+
class LeapfrogSolverConstrained( osc.OdeSolverConstrained ) :
|
|
22
|
+
def __init__( self , force , p_set , dt , x_constraint=None , v_constraint=None ):
|
|
23
|
+
super(LeapfrogSolverConstrained,self).__init__( force , p_set , dt , x_constraint=None , v_constraint=None )
|
|
24
|
+
self.__Ai = np.zeros( self.force.A.shape )
|
|
25
|
+
|
|
26
|
+
if x_constraint != None :
|
|
27
|
+
self.x_constraint = x_constraint
|
|
28
|
+
|
|
29
|
+
def get_x_constraint(self):
|
|
30
|
+
return super(LeapfrogSolverConstrained,self).get_x_constraint()
|
|
31
|
+
|
|
32
|
+
def set_x_constraint(self , xc ):
|
|
33
|
+
super(LeapfrogSolverConstrained,self).set_x_constraint( xc )
|
|
34
|
+
self.__free_inx = self.x_constraint.get_cx_free_indicies()
|
|
35
|
+
self.__csrt_inx = self.x_constraint.get_cx_indicies()
|
|
36
|
+
|
|
37
|
+
x_constraint = property( get_x_constraint , set_x_constraint , doc="get and set the current positionals constraints" )
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def __step__( self , dt ):
|
|
41
|
+
|
|
42
|
+
self.pset.X[self.__free_inx,:] = self.pset.X[self.__free_inx,:] + self.pset.V[self.__free_inx,:] * dt + 0.5*self.force.A[self.__free_inx,:] * dt**2.0
|
|
43
|
+
self.__Ai[self.__free_inx,:] = self.force.A[self.__free_inx,:]
|
|
44
|
+
|
|
45
|
+
self.force.update_force( self.pset )
|
|
46
|
+
|
|
47
|
+
self.pset.V[self.__free_inx,:] = self.pset.V[self.__free_inx,:] + 0.5 * ( self.__Ai[self.__free_inx,:] + self.force.A[self.__free_inx,:] ) * dt
|
|
48
|
+
|
|
49
|
+
self.pset.V[self.__csrt_inx,:] = 0.0
|
|
50
|
+
|
|
51
|
+
#print( self.pset.V )
|
|
52
|
+
|
|
53
|
+
self.pset.update_boundary()
|
|
@@ -0,0 +1,43 @@
|
|
|
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
|
+
import pyparticles.ode.ode_solver as os
|
|
20
|
+
import pyparticles.pset.particles_set as ps
|
|
21
|
+
|
|
22
|
+
class MidpointSolver( os.OdeSolver ) :
|
|
23
|
+
def __init__( self , force , p_set , dt ):
|
|
24
|
+
|
|
25
|
+
super(MidpointSolver,self).__init__( force , p_set , dt )
|
|
26
|
+
|
|
27
|
+
self.__mid_pset = ps.ParticlesSet( p_set.size , p_set.dim )
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def __step__( self , dt ):
|
|
31
|
+
|
|
32
|
+
self.__mid_pset.X[:] = self.pset.X[:] + dt/2.0 * self.pset.V
|
|
33
|
+
|
|
34
|
+
self.force.update_force( self.__mid_pset )
|
|
35
|
+
|
|
36
|
+
self.__mid_pset.V[:] = self.pset.V[:] + dt/2.0 * self.force.A
|
|
37
|
+
|
|
38
|
+
self.pset.V[:] = self.pset.V[:] + dt * self.force.A
|
|
39
|
+
self.pset.X[:] = self.pset.X[:] + dt * self.__mid_pset.V[:]
|
|
40
|
+
|
|
41
|
+
self.pset.update_boundary()
|
|
42
|
+
self.force.update_force( self.pset )
|
|
43
|
+
|
|
@@ -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
|
+
|
|
18
|
+
import numpy as np
|
|
19
|
+
import pyparticles.ode.ode_solver_constrained as osc
|
|
20
|
+
import pyparticles.pset.particles_set as ps
|
|
21
|
+
|
|
22
|
+
class MidpointSolverConstrained( osc.OdeSolverConstrained ) :
|
|
23
|
+
|
|
24
|
+
def __init__( self , force , p_set , dt , x_constraint=None , v_constraint=None ):
|
|
25
|
+
super(MidpointSolverConstrained,self).__init__( force , p_set , dt , x_constraint=None , v_constraint=None )
|
|
26
|
+
|
|
27
|
+
self.__mid_pset = ps.ParticlesSet( p_set.size , p_set.dim )
|
|
28
|
+
|
|
29
|
+
if x_constraint != None :
|
|
30
|
+
self.x_constraint = x_constraint
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def get_x_constraint(self):
|
|
34
|
+
return super(MidpointSolverConstrained,self).get_x_constraint()
|
|
35
|
+
|
|
36
|
+
def set_x_constraint(self , xc ):
|
|
37
|
+
super(MidpointSolverConstrained,self).set_x_constraint( xc )
|
|
38
|
+
self.__free_inx = self.x_constraint.get_cx_free_indicies()
|
|
39
|
+
self.__csrt_inx = self.x_constraint.get_cx_indicies()
|
|
40
|
+
|
|
41
|
+
x_constraint = property( get_x_constraint , set_x_constraint , doc="get and set the current positionals constraints" )
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def __step__( self , dt ):
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
self.__mid_pset.X[self.__free_inx,:] = self.pset.X[self.__free_inx,:] + dt/2.0 * self.pset.V[self.__free_inx,:]
|
|
49
|
+
self.__mid_pset.X[self.__csrt_inx,:] = self.pset.X[self.__csrt_inx,:]
|
|
50
|
+
|
|
51
|
+
self.force.update_force( self.__mid_pset )
|
|
52
|
+
|
|
53
|
+
self.__mid_pset.V[self.__free_inx,:] = self.pset.V[self.__free_inx,:] + dt/2.0 * self.force.A[self.__free_inx,:]
|
|
54
|
+
|
|
55
|
+
self.pset.V[self.__free_inx,:] = self.pset.V[self.__free_inx,:] + dt * self.force.A[self.__free_inx,:]
|
|
56
|
+
self.pset.X[self.__free_inx,:] = self.pset.X[self.__free_inx,:] + dt * self.__mid_pset.V[self.__free_inx,:]
|
|
57
|
+
|
|
58
|
+
self.pset.update_boundary()
|
|
59
|
+
self.force.update_force( self.pset )
|
|
60
|
+
|
|
@@ -0,0 +1,134 @@
|
|
|
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
|
+
import sys
|
|
20
|
+
|
|
21
|
+
import pyparticles.ode.sim_time as st
|
|
22
|
+
|
|
23
|
+
class OdeSolver(object) :
|
|
24
|
+
"""
|
|
25
|
+
Base abstract class for defining the integration method of the ordinary differential equation like Runge Kutta or Euler method,
|
|
26
|
+
the user must overide the method **__step__**
|
|
27
|
+
|
|
28
|
+
Example (Euler method):
|
|
29
|
+
::
|
|
30
|
+
|
|
31
|
+
import numpy as np
|
|
32
|
+
import pyparticles.ode.ode_solver as os
|
|
33
|
+
|
|
34
|
+
class EulerSolver( os.OdeSolver ) :
|
|
35
|
+
def __init__( self , force , p_set , dt ):
|
|
36
|
+
super(EulerSolver,self).__init__( force , p_set , dt )
|
|
37
|
+
|
|
38
|
+
def __step__( self , dt ):
|
|
39
|
+
|
|
40
|
+
self.force.update_force( self.pset )
|
|
41
|
+
|
|
42
|
+
self.pset.V[:] = self.pset.V + self.force.A * dt
|
|
43
|
+
self.pset.X[:] = self.pset.X + self.pset.V * dt
|
|
44
|
+
|
|
45
|
+
self.pset.update_boundary()
|
|
46
|
+
|
|
47
|
+
Constructor:
|
|
48
|
+
|
|
49
|
+
:param force: the force model
|
|
50
|
+
:param p_set: the particle set
|
|
51
|
+
:param dt: delta time
|
|
52
|
+
"""
|
|
53
|
+
def __init__( self , force , p_set , dt ):
|
|
54
|
+
self.__force = force
|
|
55
|
+
self.__p_set = p_set
|
|
56
|
+
self.__dt = dt
|
|
57
|
+
|
|
58
|
+
self.__sim_time = st.SimTime( self )
|
|
59
|
+
|
|
60
|
+
self.__steps_cnt = 0
|
|
61
|
+
|
|
62
|
+
def get_dt( self ):
|
|
63
|
+
return self.__dt
|
|
64
|
+
|
|
65
|
+
def set_dt( self , dt ):
|
|
66
|
+
self.__dt = dt
|
|
67
|
+
|
|
68
|
+
dt = property( get_dt , set_dt , doc="get and set the delta time of the step")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def get_steps(self):
|
|
72
|
+
return self.__steps_cnt
|
|
73
|
+
|
|
74
|
+
def del_steps(self):
|
|
75
|
+
self.__steps_cnt = 0
|
|
76
|
+
|
|
77
|
+
steps_cnt = property( get_steps , fdel=del_steps , doc="return the count of the performed steps")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def get_time(self):
|
|
81
|
+
return self.__sim_time.time
|
|
82
|
+
|
|
83
|
+
def set_time( self , t0 ):
|
|
84
|
+
self.__sim_time.time = t0
|
|
85
|
+
|
|
86
|
+
time = property( get_time , set_time , doc="get and set the current simulation time" )
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def get_sim_time( self ):
|
|
90
|
+
return self.__sim_time
|
|
91
|
+
|
|
92
|
+
sim_time = property( get_sim_time , doc="get the reference to the SimTime object, used for storing and sharing the current simulation time" )
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def get_force( self ):
|
|
96
|
+
return self.__force
|
|
97
|
+
|
|
98
|
+
def set_force( self , force ):
|
|
99
|
+
self.__force = force
|
|
100
|
+
|
|
101
|
+
force = property( get_force , set_force , doc="get and set the used force model")
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def update_force( self ):
|
|
105
|
+
self.__force.update_force( self.pset )
|
|
106
|
+
|
|
107
|
+
def get_pset( self ):
|
|
108
|
+
return self.__p_set
|
|
109
|
+
|
|
110
|
+
def set_pset( self , p_set ):
|
|
111
|
+
self.__p_set = p_set
|
|
112
|
+
|
|
113
|
+
pset = property( get_pset , set_pset , "get and set the used particles set")
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def step( self , dt=None ):
|
|
117
|
+
"""
|
|
118
|
+
Perform an integration step. If the dt is not given (reccomended) it uses the stored *dt*.
|
|
119
|
+
You must alway use this method for executing a step.
|
|
120
|
+
"""
|
|
121
|
+
if dt == None:
|
|
122
|
+
dt = self.dt
|
|
123
|
+
|
|
124
|
+
self.__sim_time.time += dt
|
|
125
|
+
|
|
126
|
+
self.__steps_cnt += 1
|
|
127
|
+
|
|
128
|
+
self.__step__( dt )
|
|
129
|
+
|
|
130
|
+
def __step__( self , dt ):
|
|
131
|
+
"""
|
|
132
|
+
Abstract methos that contain the code for computing the new status of the particles system. This methos must be overidden by the user.
|
|
133
|
+
"""
|
|
134
|
+
NotImplementedError(" %s : is virtual and must be overridden." % sys._getframe().f_code.co_name )
|
|
@@ -0,0 +1,43 @@
|
|
|
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
|
+
import pyparticles.ode.ode_solver as os
|
|
20
|
+
|
|
21
|
+
class OdeSolverConstrained( os.OdeSolver ) :
|
|
22
|
+
def __init__(self , force , p_set , dt , x_constraint=None , v_constraint=None ):
|
|
23
|
+
|
|
24
|
+
self.__x_constr = x_constraint
|
|
25
|
+
self.__v_constr = v_constraint
|
|
26
|
+
|
|
27
|
+
super(OdeSolverConstrained,self).__init__( force , p_set , dt )
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def get_x_constraint(self):
|
|
31
|
+
"""
|
|
32
|
+
returns a reference to the current positionals constraints
|
|
33
|
+
"""
|
|
34
|
+
return self.__x_constr
|
|
35
|
+
|
|
36
|
+
def set_x_constraint(self , xc ):
|
|
37
|
+
"""
|
|
38
|
+
set the new positionals contraints
|
|
39
|
+
"""
|
|
40
|
+
self.__x_constr = xc
|
|
41
|
+
self.__x_constr.pset = self.pset
|
|
42
|
+
|
|
43
|
+
x_constraint = property( get_x_constraint , set_x_constraint , doc="get and set the current positionals constraints" )
|
|
@@ -0,0 +1,79 @@
|
|
|
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
|
+
import pyparticles.ode.ode_solver as os
|
|
20
|
+
import pyparticles.pset.particles_set as ps
|
|
21
|
+
|
|
22
|
+
class RungeKuttaSolver( os.OdeSolver ) :
|
|
23
|
+
def __init__( self , force , p_set , dt ):
|
|
24
|
+
|
|
25
|
+
super(RungeKuttaSolver,self).__init__( force , p_set , dt )
|
|
26
|
+
|
|
27
|
+
self.__Kv1 = np.zeros( self.force.A.shape )
|
|
28
|
+
self.__Kv2 = np.zeros( self.force.A.shape )
|
|
29
|
+
self.__Kv3 = np.zeros( self.force.A.shape )
|
|
30
|
+
self.__Kv4 = np.zeros( self.force.A.shape )
|
|
31
|
+
|
|
32
|
+
self.__Kx1 = np.zeros( self.force.A.shape )
|
|
33
|
+
self.__Kx2 = np.zeros( self.force.A.shape )
|
|
34
|
+
self.__Kx3 = np.zeros( self.force.A.shape )
|
|
35
|
+
self.__Kx4 = np.zeros( self.force.A.shape )
|
|
36
|
+
|
|
37
|
+
self.__tmp_pset = ps.ParticlesSet( p_set.size , p_set.dim )
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def __step__( self , dt ):
|
|
41
|
+
|
|
42
|
+
self.__tmp_pset.V[:] = self.pset.V[:]
|
|
43
|
+
|
|
44
|
+
# K1
|
|
45
|
+
self.__Kv1[:] = self.force.A
|
|
46
|
+
self.__Kx1[:] = self.pset.V
|
|
47
|
+
|
|
48
|
+
# K2
|
|
49
|
+
self.__tmp_pset.X[:] = self.pset.X + dt/2.0*self.__Kx1[:]
|
|
50
|
+
self.force.update_force( self.__tmp_pset )
|
|
51
|
+
|
|
52
|
+
self.__Kv2[:] = self.force.A
|
|
53
|
+
self.__Kx2[:] = self.pset.V + dt/2.0*self.__Kv1[:]
|
|
54
|
+
|
|
55
|
+
#K3
|
|
56
|
+
self.__tmp_pset.X[:] = self.pset.X + dt/2.0*self.__Kx2[:]
|
|
57
|
+
self.force.update_force( self.__tmp_pset )
|
|
58
|
+
|
|
59
|
+
self.__Kv3[:] = self.force.A
|
|
60
|
+
self.__Kx3[:] = self.pset.V + dt/2.0*self.__Kv2[:]
|
|
61
|
+
|
|
62
|
+
#K4
|
|
63
|
+
self.__tmp_pset.X[:] = self.pset.X + dt*self.__Kx3[:]
|
|
64
|
+
self.force.update_force( self.__tmp_pset )
|
|
65
|
+
|
|
66
|
+
self.__Kv4[:] = self.force.A
|
|
67
|
+
self.__Kx4[:] = self.pset.V + dt*self.__Kv3[:]
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
self.pset.V[:] = self.pset.V[:] + dt/6.0 * ( self.__Kv1 + 2.0*self.__Kv2 + 2.0*self.__Kv3 + self.__Kv4 )
|
|
72
|
+
self.pset.X[:] = self.pset.X[:] + dt/6.0 * ( self.__Kx1 + 2.0*self.__Kx2 + 2.0*self.__Kx3 + self.__Kx4 )
|
|
73
|
+
|
|
74
|
+
#self.pset.X[:] = self.pset.X[:] + dt*self.pset.V[:]
|
|
75
|
+
|
|
76
|
+
self.pset.update_boundary()
|
|
77
|
+
self.force.update_force( self.pset )
|
|
78
|
+
|
|
79
|
+
|
|
@@ -0,0 +1,98 @@
|
|
|
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
|
+
import pyparticles.ode.ode_solver_constrained as osc
|
|
20
|
+
import pyparticles.pset.particles_set as ps
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class RungeKuttaSolverConstrained( osc.OdeSolverConstrained ) :
|
|
25
|
+
def __init__( self , force , p_set , dt , x_constraint=None , v_constraint=None ):
|
|
26
|
+
super(RungeKuttaSolverConstrained,self).__init__( force , p_set , dt , x_constraint=None , v_constraint=None )
|
|
27
|
+
|
|
28
|
+
if x_constraint != None :
|
|
29
|
+
self.x_constraint = x_constraint
|
|
30
|
+
|
|
31
|
+
self.__Kv1 = np.zeros( self.force.A.shape )
|
|
32
|
+
self.__Kv2 = np.zeros( self.force.A.shape )
|
|
33
|
+
self.__Kv3 = np.zeros( self.force.A.shape )
|
|
34
|
+
self.__Kv4 = np.zeros( self.force.A.shape )
|
|
35
|
+
|
|
36
|
+
self.__Kx1 = np.zeros( self.force.A.shape )
|
|
37
|
+
self.__Kx2 = np.zeros( self.force.A.shape )
|
|
38
|
+
self.__Kx3 = np.zeros( self.force.A.shape )
|
|
39
|
+
self.__Kx4 = np.zeros( self.force.A.shape )
|
|
40
|
+
|
|
41
|
+
self.__tmp_pset = ps.ParticlesSet( p_set.size , p_set.dim )
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def get_x_constraint(self):
|
|
45
|
+
return super(RungeKuttaSolverConstrained,self).get_x_constraint()
|
|
46
|
+
|
|
47
|
+
def set_x_constraint(self , xc ):
|
|
48
|
+
super(RungeKuttaSolverConstrained,self).set_x_constraint( xc )
|
|
49
|
+
self.__fi = self.x_constraint.get_cx_free_indicies()
|
|
50
|
+
self.__ci = self.x_constraint.get_cx_indicies()
|
|
51
|
+
|
|
52
|
+
x_constraint = property( get_x_constraint , set_x_constraint , doc="get and set the current positionals constraints" )
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def __step__( self , dt ):
|
|
56
|
+
|
|
57
|
+
self.__tmp_pset.V[:] = self.pset.V[:]
|
|
58
|
+
|
|
59
|
+
# K1
|
|
60
|
+
self.__Kv1[self.__fi,:] = self.force.A[self.__fi,:]
|
|
61
|
+
self.__Kx1[self.__fi,:] = self.pset.V[self.__fi,:]
|
|
62
|
+
|
|
63
|
+
# K2
|
|
64
|
+
self.__tmp_pset.X[self.__fi,:] = self.pset.X[self.__fi,:] + dt/2.0*self.__Kx1[self.__fi,:]
|
|
65
|
+
self.__tmp_pset.X[self.__ci,:] = self.pset.X[self.__ci,:]
|
|
66
|
+
self.force.update_force( self.__tmp_pset )
|
|
67
|
+
|
|
68
|
+
self.__Kv2[self.__fi,:] = self.force.A[self.__fi,:]
|
|
69
|
+
self.__Kx2[self.__fi,:] = self.pset.V[self.__fi,:] + dt/2.0*self.__Kv1[self.__fi,:]
|
|
70
|
+
|
|
71
|
+
#K3
|
|
72
|
+
self.__tmp_pset.X[self.__fi,:] = self.pset.X[self.__fi,:] + dt/2.0*self.__Kx2[self.__fi,:]
|
|
73
|
+
self.__tmp_pset.X[self.__ci,:] = self.pset.X[self.__ci,:]
|
|
74
|
+
self.force.update_force( self.__tmp_pset )
|
|
75
|
+
|
|
76
|
+
self.__Kv3[self.__fi,:] = self.force.A[self.__fi,:]
|
|
77
|
+
self.__Kx3[self.__fi,:] = self.pset.V[self.__fi,:] + dt/2.0*self.__Kv2[self.__fi,:]
|
|
78
|
+
|
|
79
|
+
#K4
|
|
80
|
+
self.__tmp_pset.X[self.__fi,:] = self.pset.X[self.__fi,:] + dt*self.__Kx3[self.__fi,:]
|
|
81
|
+
self.__tmp_pset.X[self.__ci,:] = self.pset.X[self.__ci,:]
|
|
82
|
+
self.force.update_force( self.__tmp_pset )
|
|
83
|
+
|
|
84
|
+
self.__Kv4[self.__fi,:] = self.force.A[self.__fi,:]
|
|
85
|
+
self.__Kx4[self.__fi,:] = self.pset.V[self.__fi,:] + dt*self.__Kv3[self.__fi,:]
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
self.pset.V[self.__fi,:] = self.pset.V[self.__fi,:] + dt/6.0 * ( self.__Kv1[self.__fi,:] + 2.0*self.__Kv2[self.__fi,:] + 2.0*self.__Kv3[self.__fi,:] + self.__Kv4[self.__fi,:] )
|
|
90
|
+
self.pset.X[self.__fi,:] = self.pset.X[self.__fi,:] + dt/6.0 * ( self.__Kx1[self.__fi,:] + 2.0*self.__Kx2[self.__fi,:] + 2.0*self.__Kx3[self.__fi,:] + self.__Kx4[self.__fi,:] )
|
|
91
|
+
|
|
92
|
+
self.pset.V[self.__ci,:] = 0.0
|
|
93
|
+
|
|
94
|
+
self.pset.update_boundary()
|
|
95
|
+
self.force.update_force( self.pset )
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
@@ -0,0 +1,56 @@
|
|
|
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
|
+
class SimTime( object ):
|
|
19
|
+
"""
|
|
20
|
+
Class used for storing the current simulation time:
|
|
21
|
+
|
|
22
|
+
Constructor
|
|
23
|
+
|
|
24
|
+
:param controller: a reference to the object that control the simulation time
|
|
25
|
+
|
|
26
|
+
"""
|
|
27
|
+
def __init__( self , controller ):
|
|
28
|
+
self.__time = 0.0
|
|
29
|
+
self.__controller = controller
|
|
30
|
+
|
|
31
|
+
def get_time( self ):
|
|
32
|
+
"""
|
|
33
|
+
get the current time
|
|
34
|
+
"""
|
|
35
|
+
return self.__time
|
|
36
|
+
|
|
37
|
+
def set_time( self , t ):
|
|
38
|
+
"""
|
|
39
|
+
set the current time
|
|
40
|
+
"""
|
|
41
|
+
self.__time = t
|
|
42
|
+
|
|
43
|
+
time = property( get_time , set_time , doc="get and set the current simulation time" )
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def get_controller( self ):
|
|
47
|
+
r"""
|
|
48
|
+
Get a reference to the simulation time controller, normally an ODE solver
|
|
49
|
+
|
|
50
|
+
:returns the reference to the ODE solver object
|
|
51
|
+
"""
|
|
52
|
+
return self.__controller
|
|
53
|
+
|
|
54
|
+
controller = property( get_controller , doc="get the reference to the time controller" )
|
|
55
|
+
|
|
56
|
+
|