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,131 @@
1
+ # PyParticles : Particles simulation in python
2
+ # Copyright (C) 2012 Simone Riva
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+
18
+ import numpy as np
19
+
20
+ class TrackBall( object ):
21
+ """
22
+ Class used for controlling the rotation of the scene via mouse or joystick, by generating the virtual trackball effect
23
+
24
+ Constructor
25
+
26
+ ========== =========================
27
+ Arguments
28
+ ========== =========================
29
+ w_size size of the window
30
+ ========== =========================
31
+
32
+ Example:
33
+ Event On click: ::
34
+
35
+ ( x , y ) = get_click_coords_on_window()
36
+ trk.track_ball_mapping( [ x , y ] )
37
+
38
+ Event On Move: ::
39
+
40
+ ( x , y ) = get_current_coords_on_window()
41
+ ( rot_axis , rot_angle ) = trk.on_move( [ x , y ] )
42
+ glRotatef( rot_angle , rot_axis[0] , rot_axis[1] , rot_axis[2] )
43
+ """
44
+ def __init__( self , w_size ):
45
+
46
+ self.__v = np.array( [ 0.0 , 0.0 , 0.0 ] )
47
+ self.__v_old = np.array( [ 0.0 , 0.0 , 0.0 ] )
48
+
49
+ self.__win_size = ( 800 , 600 )
50
+
51
+ self.__win_width = 800
52
+ self.__win_height = 600
53
+
54
+ self.win_size = w_size
55
+
56
+ def get_V( self ):
57
+ return self.__v
58
+
59
+ def set_V( self , v ):
60
+ self.__v = v
61
+
62
+ V = property( get_V , set_V )
63
+
64
+
65
+ def get_win_size( self ):
66
+ return ( self.__win_width , self.__win_height )
67
+
68
+ def set_win_size( self , w_size ):
69
+ self.__win_width = w_size[0]
70
+ self.__win_height = w_size[1]
71
+
72
+ win_size = property( get_win_size , set_win_size )
73
+
74
+
75
+ def track_ball_mapping( self , point ):
76
+ """
77
+ Function to be called after a click on the mouse or at beginnig of the rotation, it takes the current coordinates of the pointer.
78
+ """
79
+ self.__v_old[:] = self.__v[:]
80
+
81
+ self.__v[0] = ( 2.0 * point[0] - self.win_size[0] ) / self.win_size[0]
82
+ self.__v[1] = ( self.win_size[1] - 2.0 * point[1] ) / self.win_size[1]
83
+
84
+ self.__v[2] = 0.0
85
+
86
+ d = np.linalg.norm( self.__v )
87
+
88
+ if d > 1.0 :
89
+ self.__v[:] = self.__v[:] / d
90
+
91
+ tb_radius = 4.0
92
+
93
+ self.__v[:] = self.__v[:] * tb_radius * 0.999
94
+
95
+ self.__v[2] = np.sqrt( tb_radius**2 - self.__v[0]**2 - self.__v[1]**2 )
96
+
97
+ self.__v[:] = self.__v / np.linalg.norm( self.__v )
98
+
99
+
100
+ def on_move( self , point ):
101
+ """
102
+ function to be called when the mouse is moved. argument requires the coordinates of the mouse pointer and it returns the axis of rotation and angle.
103
+ """
104
+
105
+ self.track_ball_mapping( point )
106
+
107
+ direction = self.__v - self.__v_old
108
+
109
+ velocity = np.linalg.norm( direction )
110
+
111
+ rot_axis = np.cross( self.__v_old , self.__v )
112
+ rot_angle = velocity * 400.0
113
+
114
+ rot_axis = rot_axis / np.linalg.norm( rot_axis )
115
+
116
+ return ( rot_axis , rot_angle )
117
+
118
+
119
+ def on_joystick( self , jaxes ):
120
+ """
121
+ Given the axes ( x and y ) of the joystick; it returns the axis and the angle of rotation.
122
+ Example: ::
123
+
124
+ ( rot_axis , rot_angle ) = trk.on_joystick( [ x , y ] )
125
+ """
126
+ ws = self.win_size
127
+
128
+ jd = 400
129
+
130
+ self.track_ball_mapping( ( ws[0]/2 , ws[1]/2 ) )
131
+ return self.on_move( ( ws[0]/2 + jaxes[0]/jd , ws[1]/2 + jaxes[1]/jd ) )
@@ -0,0 +1,87 @@
1
+ # PyParticles : Particles simulation in python
2
+ # Copyright (C) 2012 Simone Riva
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+
18
+ import numpy as np
19
+
20
+ class TranslateScene(object):
21
+ def __init__( self , w_size ):
22
+
23
+ self.__v = np.array( [ 0.0 , 0.0 , 0.0 ] )
24
+ self.__v_old = np.array( [ 0.0 , 0.0 , 0.0 ] )
25
+
26
+ self.__win_size = ( 800 , 600 )
27
+
28
+ self.__win_width = 800
29
+ self.__win_height = 600
30
+
31
+ self.win_size = w_size
32
+
33
+ self.factor = 100
34
+ self.__fovy = 2.0
35
+
36
+ def get_V( self ):
37
+ return self.__v
38
+
39
+ def set_V( self , v ):
40
+ self.__v = v
41
+
42
+ V = property( get_V , set_V )
43
+
44
+
45
+ def get_fovy( self ):
46
+ return self.__fovy
47
+
48
+ def set_fovy( self , fv ):
49
+ if fv > 2.0 :
50
+ fv = 2.0
51
+ self.__fovy = fv
52
+
53
+ fovy = property( get_fovy , set_fovy )
54
+
55
+
56
+ def get_win_size( self ):
57
+ return ( self.__win_width , self.__win_height )
58
+
59
+ def set_win_size( self , w_size ):
60
+ self.__win_width = w_size[0]
61
+ self.__win_height = w_size[1]
62
+
63
+ win_size = property( get_win_size , set_win_size )
64
+
65
+
66
+ def translate_mapping( self , point ):
67
+ self.__v_old[:] = self.__v[:]
68
+
69
+ self.__v[0] = ( 2.0 * point[0] - self.win_size[0] ) / self.win_size[0]
70
+ self.__v[1] = ( self.win_size[1] - 2.0 * point[1] ) / self.win_size[1]
71
+ self.__v[2] = 1.0
72
+
73
+
74
+ def on_move( self , point ):
75
+ self.translate_mapping( point )
76
+
77
+ direction = self.__v - self.__v_old
78
+
79
+ velocity = np.linalg.norm( direction )
80
+
81
+ delta = direction * velocity * self.factor * self.fovy
82
+
83
+ return ( delta[0] , delta[1] )
84
+
85
+
86
+
87
+
@@ -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,69 @@
1
+ # PyParticles : Particles simulation in python
2
+ # PyParticles : Particles simulation in python
3
+ # Copyright (C) 2012 Simone Riva
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ import numpy as np
19
+ import sys
20
+
21
+
22
+ class Boundary(object):
23
+ def __init__(self):
24
+ pass
25
+
26
+ def set_boundary( self , bound=(-1,1) , dim=3 ):
27
+ if len(bound) not in ( 2 , 4 , 6 ):
28
+ raise ValueError
29
+
30
+ self.__dim = dim
31
+ self.__bound = np.zeros((dim,2))
32
+
33
+ if len(bound) >= 2 :
34
+ self.__bound[0,0] = bound[0]
35
+ self.__bound[0,1] = bound[1]
36
+
37
+ if dim >= 2 :
38
+ self.__bound[1,0] = bound[0]
39
+ self.__bound[1,1] = bound[1]
40
+
41
+ if dim == 3 :
42
+ self.__bound[2,0] = bound[0]
43
+ self.__bound[2,1] = bound[1]
44
+
45
+ if len(bound) == 6:
46
+ self.__bound[1,0] = bound[2]
47
+ self.__bound[1,1] = bound[3]
48
+
49
+ self.__bound[2,0] = bound[4]
50
+ self.__bound[2,1] = bound[5]
51
+
52
+ if len(bound) == 4:
53
+ self.__bound[1,0] = bound[2]
54
+ self.__bound[1,1] = bound[3]
55
+
56
+ def get_dim(self):
57
+ return self.__dim
58
+
59
+ dim = property( get_dim )
60
+
61
+ def get_bound(self):
62
+ return self.__bound
63
+
64
+ bound = property( get_bound )
65
+
66
+ def boundary( self , p_set ):
67
+ NotImplementedError(" %s : is virtual and must be overridden." % sys._getframe().f_code.co_name )
68
+
69
+
@@ -0,0 +1,28 @@
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
+ class Cluster(object):
20
+ def __init__(self):
21
+ pass
22
+
23
+ def insert3( self , X , M=None ,V=None ):
24
+ pass
25
+
26
+ def write_out( self , X , M=None ,V=None ):
27
+ pass
28
+
@@ -0,0 +1,63 @@
1
+ # PyParticles : Particles simulation in python
2
+ # Copyright (C) 2012 Simone Riva
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ import numpy as np
18
+ from scipy.sparse import dok_matrix
19
+
20
+ import pyparticles.pset.constraint as ct
21
+
22
+
23
+ class ConstrainedForceInteractions(ct.Constraint):
24
+ def __init__(self, pset=None):
25
+ self.__S = dok_matrix((1, 1), dtype=np.byte)
26
+ super(ConstrainedForceInteractions, self).__init__(pset=None)
27
+ if pset is not None:
28
+ self.pset = pset
29
+
30
+ def get_pset(self):
31
+ return super(ConstrainedForceInteractions, self).get_pset()
32
+
33
+ def set_pset(self, pset):
34
+ self.__S.resize((pset.size, pset.size))
35
+ super(ConstrainedForceInteractions, self).set_pset(pset)
36
+
37
+ pset = property(get_pset, set_pset)
38
+
39
+ def add_connections(self, fc):
40
+ for c in fc:
41
+ i, j = int(c[0]), int(c[1])
42
+ self.__S[i, j] = True
43
+
44
+ def remove_connections(self, fc):
45
+ for c in fc:
46
+ i, j = int(c[0]), int(c[1])
47
+ if (i, j) in self.__S:
48
+ del self.__S[i, j]
49
+
50
+ def get_dense(self):
51
+ return np.asarray(self.__S.todense(), dtype=np.bool_)
52
+
53
+ dense = property(get_dense)
54
+
55
+ def get_sparse(self):
56
+ return self.__S
57
+
58
+ sparse = property(get_sparse)
59
+
60
+ def get_items(self):
61
+ return self.__S.items()
62
+
63
+ items = property(get_items)
@@ -0,0 +1,158 @@
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.constraint as ct
20
+
21
+
22
+ class ConstrainedX(ct.Constraint):
23
+ def __init__(self, pset=None):
24
+ self.__X_cr = None
25
+ self.__X_cr_i = None
26
+ self.__X_free = None
27
+
28
+ self.__use_slice_const = False
29
+ self.__use_slice_free = False
30
+
31
+ super(ConstrainedX, self).__init__(pset=pset)
32
+
33
+ def add_x_constraint(self, indx, constr):
34
+ """Add positional constraints and update the referenced particle set."""
35
+ if isinstance(indx, slice):
36
+ self.__X_cr = np.array(constr)
37
+ self.__X_cr_i = indx
38
+ self.__use_slice_const = True
39
+ self.pset.X[indx, :] = constr
40
+ self._optimize()
41
+ return
42
+
43
+ indx = np.asarray(indx, dtype=np.int64)
44
+ constr = np.asarray(constr)
45
+
46
+ if self.__X_cr is None:
47
+ self.__X_cr = constr.copy()
48
+ self.__X_cr_i = indx.copy()
49
+ else:
50
+ self.__X_cr_i = np.concatenate((self.__X_cr_i, indx))
51
+ self.__X_cr = np.concatenate((self.__X_cr, constr))
52
+
53
+ self._optimize()
54
+ self.pset.X[indx, :] = constr
55
+
56
+ def _optimize(self):
57
+ """Use a slice for free indices when they form one contiguous range."""
58
+ free = list(range(self.pset.size))
59
+
60
+ if self.__X_cr_i is None:
61
+ constrained = []
62
+ elif isinstance(self.__X_cr_i, slice):
63
+ constrained = range(*self.__X_cr_i.indices(self.pset.size))
64
+ else:
65
+ constrained = self.__X_cr_i
66
+
67
+ for i in constrained:
68
+ i = int(i)
69
+ if i in free:
70
+ free.remove(i)
71
+
72
+ if not free:
73
+ self.__X_free = np.array([], dtype=np.int64)
74
+ self.__use_slice_free = False
75
+ return
76
+
77
+ sequential = all((free[i + 1] - free[i]) == 1 for i in range(len(free) - 1))
78
+ if sequential:
79
+ self.__X_free = slice(free[0], free[-1] + 1)
80
+ self.__use_slice_free = True
81
+ else:
82
+ self.__X_free = np.asarray(free, dtype=np.int64)
83
+ self.__use_slice_free = False
84
+
85
+ def get_pset(self):
86
+ return super(ConstrainedX, self).get_pset()
87
+
88
+ def set_pset(self, pset):
89
+ super(ConstrainedX, self).set_pset(pset)
90
+ if self.__X_cr_i is not None and self.__X_cr is not None:
91
+ pset.X[self.__X_cr_i, :] = self.__X_cr
92
+ self._optimize()
93
+
94
+ pset = property(get_pset, set_pset, doc="get and set the particles set (pset)")
95
+
96
+ def remove_x_constraint(self, indxs):
97
+ """Remove constraints whose particle indices are listed in *indxs*."""
98
+ if self.__use_slice_const or self.__X_cr_i is None:
99
+ return
100
+
101
+ remove_positions = []
102
+ for i in indxs:
103
+ matches = np.flatnonzero(self.__X_cr_i == i)
104
+ remove_positions.extend(matches.tolist())
105
+
106
+ if not remove_positions:
107
+ return
108
+
109
+ remove_positions = np.asarray(sorted(set(remove_positions)), dtype=np.int64)
110
+ self.__X_cr = np.delete(self.__X_cr, remove_positions, axis=0)
111
+ self.__X_cr_i = np.delete(self.__X_cr_i, remove_positions, axis=0)
112
+
113
+ if self.__X_cr_i.size == 0:
114
+ self.__X_cr = None
115
+ self.__X_cr_i = None
116
+
117
+ self._optimize()
118
+
119
+ def get_cx_indicies(self):
120
+ """Return a copy of the constrained indices (legacy spelling kept)."""
121
+ if isinstance(self.__X_cr_i, slice):
122
+ return self.__X_cr_i
123
+ if self.__X_cr_i is None:
124
+ return None
125
+ return np.copy(self.__X_cr_i)
126
+
127
+ def set_free_indicies(self, indx):
128
+ if isinstance(indx, slice):
129
+ self.__X_free = indx
130
+ self.__use_slice_free = True
131
+ return
132
+
133
+ indx = np.asarray(indx, dtype=np.int64)
134
+ if self.__X_free is None:
135
+ self.__X_free = indx
136
+ elif isinstance(self.__X_free, slice):
137
+ current = np.arange(self.pset.size, dtype=np.int64)[self.__X_free]
138
+ self.__X_free = np.concatenate((current, indx))
139
+ else:
140
+ self.__X_free = np.concatenate((self.__X_free, indx))
141
+ self.__use_slice_free = False
142
+
143
+ def get_cx_free_indicies(self):
144
+ return self.__X_free
145
+
146
+ def clear_all_x_constraint(self):
147
+ self.__X_cr = None
148
+ self.__X_cr_i = None
149
+ self.__X_free = slice(0, self.pset.size) if self.pset is not None else None
150
+ self.__use_slice_const = False
151
+ self.__use_slice_free = self.pset is not None
152
+
153
+ def get_cX(self):
154
+ if self.__X_cr_i is None:
155
+ return None
156
+ return self.pset.X[self.__X_cr_i, :]
157
+
158
+ cX = property(get_cX, doc="return the constrained X elements")
@@ -0,0 +1,42 @@
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
+ from collections import deque
20
+
21
+ import pyparticles.pset.particles_set as ps
22
+
23
+ class Constraint( object ):
24
+ def __init__( self , pset=None ):
25
+ self.__pset = pset
26
+
27
+
28
+ def get_pset(self):
29
+ return self.__pset
30
+
31
+ def set_pset( self , pset ):
32
+ self.__pset = pset
33
+
34
+ pset = property( get_pset , set_pset )
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+
@@ -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
+ import numpy as np
10
+ import pyparticles.pset.boundary as bd
11
+
12
+
13
+ class DefaultBoundary(bd.Boundary):
14
+ r"""Move particles outside the domain through a user callback."""
15
+
16
+ def __init__(self, bound=(-1, 1), dim=3, defualt_pos=None):
17
+ self.set_boundary(bound, dim)
18
+ self.__defualt_pos = defualt_pos
19
+
20
+ def needs_update(self, p_set):
21
+ """Return True when at least one position lies outside the domain."""
22
+ for i in range(self.dim):
23
+ if np.any(p_set.X[:, i] < self.bound[i, 0]):
24
+ return True
25
+ if np.any(p_set.X[:, i] > self.bound[i, 1]):
26
+ return True
27
+ return False
28
+
29
+ def boundary(self, p_set):
30
+ changed = False
31
+ for i in range(self.dim):
32
+ b_mi, = np.where(p_set.X[:, i] < self.bound[i, 0])
33
+ b_mx, = np.where(p_set.X[:, i] > self.bound[i, 1])
34
+
35
+ if len(b_mi) > 0:
36
+ self.__defualt_pos(p_set, b_mi)
37
+ changed = True
38
+
39
+ if len(b_mx) > 0:
40
+ self.__defualt_pos(p_set, b_mx)
41
+ changed = True
42
+
43
+ return changed