11import numpy as np
22import numba
33import time
4+ from time import sleep
5+ import pyvista as pv
6+
47
58def PCA (number : int , mass : np .ndarray , r : np .ndarray , Df : float , kf : float , tolerance : float ) -> tuple [bool , np .ndarray ]:
69 PCA_ok = True
710 n1 ,m1 ,rg1 ,x_cm ,y_cm ,z_cm , X ,Y ,Z = First_two_monomers (r , mass , number , Df , kf )
811
912 if number > 2 :
1013 k = 3
11- while k < number + 1 :
14+ while k <= number :
1215 n2 = 1
1316 m2 = mass [k - 1 ]
1417
1518 rg2 = np .sqrt (0.6 )* r [k - 1 ]
1619
1720 n3 = n1 + n2
1821 m3 = m1 + m2
19-
2022 rg3 = (np .exp (np .sum (np .log (r ))/ r .size ))* np .power (n3 / kf ,1 / Df )
23+
2124 gamma_ok , gamma_pc = gamma_calc (rg1 ,rg2 ,rg3 ,n1 ,n2 ,n3 )
2225 monomer_candidates = np .zeros ((number - k + 1 )) # 0 = not considered
2326 monomer_candidates [0 ] = 1 # first one has been considered
27+
2428 candidates , rmax = random_list_selection (gamma_ok , gamma_pc , X ,Y ,Z ,r ,n1 ,x_cm ,y_cm ,z_cm )
25- list_sum = 0
2629
30+ list_sum = 0
31+ # print("here")
2732 while list_sum == 0 :
28- while np .sum (candidates ) == 0 and np .sum (monomer_candidates ) < number - k :
33+ # print(f"{np.sum(candidates) == 0 = }")
34+ # print(f"{np.sum(monomer_candidates) <= number-k = }")
35+ # if not np.sum(monomer_candidates) <= number-k-1:
36+ # print(f"{number = }")
37+ # print(f"{k = }")
38+ # print(f"{number-k = }")
39+ # print(f"{list_sum = }")
40+ # print(f"{np.sum(candidates) = }")
41+ # print(f"{monomer_candidates = }")
42+ while np .sum (candidates ) == 0 and np .sum (monomer_candidates ) <= number - k :
2943 candidates , rmax = search_monomer_candidates (r ,mass ,monomer_candidates ,number ,k ,n3 ,Df ,kf ,rg1 ,n1 ,X ,Y ,Z ,x_cm ,y_cm ,z_cm )
3044
31- previous_candidate = 0
45+ previous_candidate = - 1
3246
3347 if np .sum (candidates ) > 0 :
3448 candidates , selected_real = random_list_selection_one (candidates , previous_candidate )
3549 previous_candidate = selected_real
3650 elif np .sum (candidates ) == number - k + 1 :
3751 PCA_ok = False
52+ exit (- 1 )
3853
3954 curr_try = 1
4055 X_sel = X [selected_real ]
@@ -43,13 +58,28 @@ def PCA(number: int, mass: np.ndarray, r: np.ndarray, Df: float, kf: float, tole
4358 R_sel = r [selected_real ]
4459 r_k = r [k - 1 ]
4560
61+ # print(f"modified {k-1 = }")
4662 x_k , y_k , z_k , r0 ,x0 ,y0 ,z0 ,i_vec ,j_vec = sticking_process (X_sel ,Y_sel ,Z_sel ,R_sel ,r_k ,x_cm ,y_cm ,z_cm ,gamma_pc )
4763 X [k - 1 ] = x_k
4864 Y [k - 1 ] = y_k
4965 Z [k - 1 ] = z_k
5066
5167 cov_max = overlap_check (X [0 :k ], Y [0 :k ], Z [0 :k ], r [0 :k ],k )
5268
69+ positions = [[X [i ], Y [i ], Z [i ]] for i in range (X .shape [0 ])]
70+ # print(f"{len(positions) = }")
71+ # print(f"{positions}")
72+ # point_cloud = pv.PolyData(positions)
73+ # point_cloud["radius"] = [2 for i in range(X.shape[0])]
74+
75+ # geom = pv.Sphere(theta_resolution=8, phi_resolution=8)
76+ # glyphed = point_cloud.glyph(scale="radius", geom=geom,)
77+ # # p = pv.Plotter(notebook=False, off_screen=True, window_size=(2000,2000))
78+ # p = pv.Plotter(notebook=False)
79+ # p.add_mesh(glyphed, color='white',smooth_shading=True)
80+ # p.show()
81+ # if cov_max > tolerance:
82+ # print("Need to readjust")
5383 while cov_max > tolerance and curr_try < 360 :
5484 x_k , y_k , z_k ,_ = sticking_process2 (x0 ,y0 ,z0 ,r0 ,i_vec ,j_vec )
5585
@@ -61,6 +91,8 @@ def PCA(number: int, mass: np.ndarray, r: np.ndarray, Df: float, kf: float, tole
6191
6292 if np .mod (curr_try ,359 ) == 0 and np .sum (candidates ) > 1 :
6393 candidates , selected_real = random_list_selection_one (candidates , previous_candidate )
94+ # if np.sum(candidates) == 0:
95+ # print("FOURTH, candidates all ZERO")
6496 X_sel = X [selected_real ]
6597 Y_sel = Y [selected_real ]
6698 Z_sel = Z [selected_real ]
@@ -73,15 +105,27 @@ def PCA(number: int, mass: np.ndarray, r: np.ndarray, Df: float, kf: float, tole
73105 previous_candidate = selected_real
74106 curr_try += 1
75107
108+ # print("huh1")
76109 cov_max = overlap_check (X [0 :k ], Y [0 :k ], Z [0 :k ], r [0 :k ],k )
110+ # print("huh2")
77111
112+ # FIXME: candidates may be full of zeros at some point which causes the program to get stuck
78113 list_sum = np .sum (candidates )
114+ if np .sum (candidates ) == 0 :
115+ print ("FIFTH, candidates all ZERO" )
116+ sleep (2 )
117+
79118
80119 if cov_max > tolerance :
81120 list_sum = 0
82121 candidates *= 0
122+ # print("SIXTH, set all candidates to ZERO")
123+ if number == k :
124+ print ("Failure -- restarting PCA routine" )
125+ return False , np .zeros ((number ,4 ))
83126
84127
128+ # print("bruh")
85129 x_cm = (x_cm * m1 + X [k - 1 ]* m2 )/ (m1 + m2 )
86130 y_cm = (y_cm * m1 + Y [k - 1 ]* m2 )/ (m1 + m2 )
87131 z_cm = (z_cm * m1 + Z [k - 1 ]* m2 )/ (m1 + m2 )
@@ -91,10 +135,21 @@ def PCA(number: int, mass: np.ndarray, r: np.ndarray, Df: float, kf: float, tole
91135 rg1 = (np .exp (np .sum (np .log (r ))/ np .log (r ).size ))* (np .power (n1 / kf , 1 / Df ))
92136 k = k + 1
93137 # FIXME: this gets stuck for some reason (no apparent connection to the arcos issue)
138+ # print("hi")
94139
95140 data_new = np .zeros ((number ,4 ))
96141 for i in range (number ):
97142 data_new [i ,:] = np .array ([X [i ], Y [i ], Z [i ], r [i ]])
143+
144+ # point_cloud = pv.PolyData(data_new[:,:-1])
145+ # point_cloud["radius"] = [2 for i in range(X.shape[0])]
146+
147+ # geom = pv.Sphere(theta_resolution=8, phi_resolution=8)
148+ # glyphed = point_cloud.glyph(scale="radius", geom=geom,)
149+ # # p = pv.Plotter(notebook=False, off_screen=True, window_size=(2000,2000))
150+ # p = pv.Plotter(notebook=False)
151+ # p.add_mesh(glyphed, color='white',smooth_shading=True)
152+ # p.show()
98153 return PCA_ok , data_new
99154
100155def PCA_subcluster (N : int , N_subcluster : int , R : np .ndarray , DF : float , kf : float , tolerance : float ) -> tuple [bool , np .ndarray , int , np .ndarray ]:
@@ -120,7 +175,11 @@ def PCA_subcluster(N: int, N_subcluster: int, R: np.ndarray, DF: float, kf: floa
120175 for j in range (radius .size ):
121176 mass [j ] = 4 / 3 * np .pi * np .power (R [j ],3 )
122177
123- PCA_OK , data_new = PCA (number ,mass ,radius ,DF ,kf ,tolerance )
178+ PCA_OK = False
179+ while not PCA_OK :
180+ PCA_OK , data_new = PCA (number ,mass ,radius ,DF ,kf ,tolerance )
181+ print (f"PCA LOOP { i } DONE!" )
182+ # time.sleep(1)
124183
125184 if i == 0 :
126185 acum = number
@@ -145,10 +204,16 @@ def First_two_monomers(R: np.ndarray,M: np.ndarray,N: int,DF: float,kf:float) ->
145204
146205 u = np .random .rand ()
147206 v = np .random .rand ()
207+ # print("first two monomers")
208+ # print(f"{u = }, {v = }")
209+
210+
211+ # u = 0.007316022089059793
212+ # v = 0.43406326698233766
148213 theta = 2 * np .pi * u
149214 phi = np .arccos (2 * v - 1 )
150- theta = 1
151- phi = 1
215+ # theta = 0.5
216+ # phi = 0. 1
152217
153218 X [1 ] = X [0 ] + (R [0 ]+ R [1 ])* np .cos (theta )* np .sin (phi )
154219 Y [1 ] = Y [0 ] + (R [0 ]+ R [1 ])* np .sin (theta )* np .sin (phi )
@@ -158,11 +223,17 @@ def First_two_monomers(R: np.ndarray,M: np.ndarray,N: int,DF: float,kf:float) ->
158223 n1 = 2
159224
160225 rg1 = (np .exp (np .sum (np .log (R [:2 ]))/ 2 ))* np .power (n1 / kf ,1 / DF )
226+ # print(f"{rg1 = }")
161227
162228 x_cm = (X [0 ]* M [0 ]+ X [1 ]* M [1 ])/ (M [0 ] + M [1 ])
163229 y_cm = (Y [0 ]* M [0 ]+ Y [1 ]* M [1 ])/ (M [0 ] + M [1 ])
164230 z_cm = (Z [0 ]* M [0 ]+ Z [1 ]* M [1 ])/ (M [0 ] + M [1 ])
165231
232+
233+ # print(f"{X[0] = }, {Y[0] = }, {Z[0] = }")
234+ # print(f"{x_cm = }, {y_cm = }, {z_cm = }")
235+ # print(f"{M = }")
236+
166237 return n1 ,m1 ,rg1 ,x_cm ,y_cm ,z_cm , X ,Y ,Z
167238
168239def gamma_calc (rg1 : float ,rg2 : float ,rg3 : float ,n1 : int ,n2 : int ,n3 : int ) -> tuple [bool ,float ]:
@@ -178,7 +249,7 @@ def gamma_calc(rg1: float,rg2: float,rg3: float,n1: int,n2: int,n3: int) -> tupl
178249 gamma_pc = np .sqrt ((np .power (n3 ,2 )* np .power (rg3_aux ,2 )- n3 * (n1 * np .power (rg1 ,2 )+ n2 * np .power (rg2 ,2 )))/ (n1 * n2 ))
179250 else :
180251 gamma_ok = False
181-
252+
182253 return gamma_ok , gamma_pc
183254
184255@numba .njit ()
@@ -202,7 +273,8 @@ def search_monomer_candidates(R: np.ndarray, M: np.ndarray, monomer_candidates:
202273 M_sl = M
203274 vector_search = np .zeros ((N - k + 1 ))
204275 for i in range (vector_search .size ):
205- vector_search [i ] = i + k
276+ vector_search [i ] = i + k - 2
277+ # print(f"{i+k-2 = }")
206278
207279 for i in range (monomer_candidates .size ):
208280 if monomer_candidates [i ] == 1 :
@@ -211,6 +283,8 @@ def search_monomer_candidates(R: np.ndarray, M: np.ndarray, monomer_candidates:
211283
212284 if vector_search2 .size > 1 :
213285 u = np .random .rand ()
286+ # print("search monomer candidates")
287+ # print(f"{u = }")
214288 RS_1 = int (vector_search2 [int (u * (vector_search .size - 1 ))])
215289 else :
216290 RS_1 = int (vector_search2 [0 ])
@@ -229,15 +303,16 @@ def search_monomer_candidates(R: np.ndarray, M: np.ndarray, monomer_candidates:
229303
230304 candidates , rmax = random_list_selection (gamma_ok , gamma_pc , X ,Y ,Z ,R ,n1 ,x_cm ,y_cm ,z_cm )
231305
232- # FIXME: this fails once kf > 1.5 LMFAO
233- candidates [RS_1 - k - 1 ] = 1
234306 return candidates , rmax
235307
236308def random_list_selection_one (candidates : np .ndarray , previous_candidate : int ):
237- if previous_candidate > 0 :
309+ if previous_candidate > - 1 :
238310 candidates [previous_candidate ] = 0
239311 candidates2 = candidates [candidates > 0 ]
240312 n = np .random .rand ()
313+ # print("random list selection one")
314+ # print(f"{n = }")
315+ # n = 0.5
241316 selected = 1 + int (n * (candidates2 .size - 1 ))
242317
243318 selected_real = 0
@@ -260,6 +335,9 @@ def sticking_process(x: float,y: float,z: float,r: float,r_k: float, x_cm: float
260335 z2 = z_cm
261336 r2 = gamma_pc
262337
338+ # print(f"{x1 = }, {y1 = }, {z1 = }, {r1 = }")
339+ # print(f"{x2 = }, {y2 = }, {z2 = }, {r2 = }")
340+
263341 a = 2 * (x2 - x1 )
264342 b = 2 * (y2 - y1 )
265343 c = 2 * (z2 - z1 )
@@ -273,9 +351,24 @@ def sticking_process(x: float,y: float,z: float,r: float,r_k: float, x_cm: float
273351
274352 distance = np .sqrt (np .power (x2 - x1 ,2 ) + np .power (y2 - y1 ,2 ) + np .power (z2 - z1 ,2 ))
275353
354+
355+ # print(f"{distance = }")
356+
276357 alpha = np .arccos ((np .power (r1 ,2 ) + np .power (distance ,2 ) - np .power (r2 ,2 ))/ (2 * r1 * distance ))
358+ # print(f"{alpha = }")
277359 if abs ((np .power (r1 ,2 ) + np .power (distance ,2 ) - np .power (r2 ,2 ))/ (2 * r1 * distance )) > 1 :
278360 # FIXME: this should never happen!
361+
362+ pos = [[x1 ,y1 ,z1 ], [x2 ,y2 ,z2 ]]
363+ point_cloud = pv .PolyData (pos )
364+ point_cloud ["radius" ] = [2 ,2 ]
365+
366+ geom = pv .Sphere (theta_resolution = 8 , phi_resolution = 8 )
367+ glyphed = point_cloud .glyph (scale = "radius" , geom = geom ,)
368+ # p = pv.Plotter(notebook=False, off_screen=True, window_size=(2000,2000))
369+ p = pv .Plotter (notebook = False )
370+ p .add_mesh (glyphed , color = 'white' ,smooth_shading = True )
371+ p .show ()
279372 print (f"{ (np .power (r1 ,2 ) + np .power (distance ,2 ) - np .power (r2 ,2 ))/ (2 * r1 * distance ) = } " )
280373 exit (- 1 )
281374 r0 = r1 * np .sin (alpha )
@@ -289,6 +382,9 @@ def sticking_process(x: float,y: float,z: float,r: float,r_k: float, x_cm: float
289382
290383 u = np .random .rand ()
291384 v = np .random .rand ()
385+ # print("sticking process")
386+ # print(f"{u = }, {v = }")
387+
292388 theta = 2. * np .pi * u
293389 phi = np .arccos (2. * v - 1. )
294390
@@ -300,6 +396,8 @@ def sticking_process(x: float,y: float,z: float,r: float,r_k: float, x_cm: float
300396
301397def sticking_process2 (x0 , y0 , z0 , r0 ,i_vec ,j_vec ):
302398 u = np .random .rand ()
399+ # print("sticking process2")
400+ # print(f"{u = }")
303401 theta = 2 * np .pi * u
304402
305403 x_k = x0 + r0 * np .cos (theta )* i_vec [0 ]+ r0 * np .sin (theta )* j_vec [0 ]
0 commit comments