@@ -359,7 +359,7 @@ def boundary_cycles(self, info=True):
359359 print (indent_level + ' Found {0} boundary cycles' .format (k ))
360360 return cycle_lists
361361
362- def merge_cells (self ,eflag ):
362+ def merge_cells (self ,eflag , pflag ):
363363 ''' Merge all possible cells while retaining marked edge features
364364 '''
365365 def flag_cells (face ,cell_group ):
@@ -390,7 +390,7 @@ def flag_cells(face,cell_group):
390390 cell_group = np .array (cell_group )
391391 # return cell_group, np.where(cell_group[self.lef[:,0]]!=cell_group[self.lef[:,1]])[0]
392392 keep_edges = np .where (cell_group [self .lef [:,0 ]]!= cell_group [self .lef [:,1 ]])[0 ]
393- pt_flag = np .zeros ((self .np ,), dtype = np .int32 )
393+ pt_flag = np .zeros ((self .np ,), dtype = np .int32 ) + pflag
394394 for i in keep_edges :
395395 pt_flag [self .le [i ,0 ]] += 1
396396 pt_flag [self .le [i ,1 ]] += 1
@@ -423,9 +423,9 @@ def update_svd_with_row(U, S, V_T, new_row):
423423
424424 # Compute SVD of the small core matrix
425425 # u_k, s_k, vt_k = np.linalg.svd(K_mat, full_matrices=False)
426- u_k , s_k , vt_k , info = scipy .linalg .lapack .sgesdd (K_mat , full_matrices = 0 )
426+ u_k , s_k , vt_k , info = scipy .linalg .lapack .dgesdd (K_mat , full_matrices = 0 )
427427 if info != 0 :
428- u_k , s_k , vt_k , info = scipy .linalg .lapack .sgesvd (K_mat , full_matrices = 0 )
428+ u_k , s_k , vt_k , info = scipy .linalg .lapack .dgesvd (K_mat , full_matrices = 0 )
429429 if info != 0 :
430430 raise np .linalg .LinAlgError ("SVD did not converge" )
431431
@@ -757,55 +757,69 @@ def compute_homology(in_file, out_file=None, plot_final=False, plot_steps=False,
757757 minima_counts = []
758758 he = []
759759 he_mark = np .zeros ((mesh_covered .ne ,))
760+ p_mark = np .zeros ((mesh_covered .np ,), dtype = np .int32 )
760761 for i in range (len (minima_sets )):
761762 evec , distance = mesh_covered .get_loop_edge_vec (minima_sets [i ])
762763 he .append (evec )
763764 minima_counts .append (distance )
764765 he_mark [abs (evec )> 0 ] = 1
766+ p_mark [minima_sets [i ][0 ]] = 1 # Mark base point for each cycle
765767
766768 # Shrink graph by grouping cells that don't cross cycles
767- cell_flags , keep_edges = mesh_covered .merge_cells (he_mark )
769+ cell_flags , keep_edges = mesh_covered .merge_cells (he_mark , p_mark )
768770 ncoarse = np .max (cell_flags )+ 1
769771 print (indent_level + "[{2}/{3}] Reducing mesh to {0} macro cells with {1} macro edges" .format (ncoarse ,keep_edges .shape [0 ],j + 1 ,len (hb )))
770772 bmat_tmp = bmat_dense_base [:,keep_edges ]
771- bmat_dense = np .zeros ((ncoarse ,keep_edges .shape [0 ]), np .float32 )
773+ bmat_dense = np .zeros ((ncoarse ,keep_edges .shape [0 ]), dtype = np .float64 )
772774 for i in range (ncoarse ):
773775 bmat_dense [i ,:] = np .sum (bmat_tmp [cell_flags == i ,:],axis = 0 )
774776
775777 # Build list of cycles from smallest to largest
776- # intial_rank = np.linalg.matrix_rank(bmat_dense)
778+ # initial_rank = np.linalg.matrix_rank(bmat_dense)
777779 # U, S, V_T = np.linalg.svd(bmat_dense, full_matrices=False)
778- U , S , V_T , _ = scipy .linalg .lapack .sgesdd (bmat_dense , full_matrices = 0 )
779- intial_rank = np .sum (S > 1e-10 )
780+ U , S , V_T , _ = scipy .linalg .lapack .dgesdd (bmat_dense , full_matrices = 0 )
781+ initial_rank = np .sum (S > 1e-10 )
780782 hb_out = []
781- do_check = False
783+ do_check = True
782784 for i in np .argsort (minima_counts ):
783785 bmat_tmp = np .vstack ((bmat_dense ,he [i ][keep_edges ]))
784786 if (not do_check ) and (i >= len (hb )): # Only start checking once we are looking at new cycles
785787 do_check = True
786788 # Update SVD with final set of previously accepted cycles
787- U , S , V_T , _ = scipy .linalg .lapack .sgesdd (bmat_dense , full_matrices = 0 )
789+ # U, S, V_T = np.linalg.svd(bmat_tmp, full_matrices=False)
790+ U , S , V_T , _ = scipy .linalg .lapack .dgesdd (bmat_dense , full_matrices = 0 )
791+ initial_rank = np .sum (S > 1e-10 )
788792 if do_check :
789793 # aug_rank = np.linalg.matrix_rank(bmat_tmp)
794+ # Un, Sn, Vn_T, _ = scipy.linalg.lapack.dgesdd(bmat_tmp, full_matrices=0)
790795 try :
791- U , S , V_T = update_svd_with_row (U , S , V_T , he [i ][keep_edges ])
796+ Un , Sn , Vn_T = update_svd_with_row (U , S , V_T , he [i ][keep_edges ])
792797 except np .linalg .LinAlgError : # Fall back to full factorization
793- # U, S, V_T = np.linalg.svd(bmat_tmp, full_matrices=False)
794- U , S , V_T , _ = scipy .linalg .lapack .sgesdd (bmat_tmp , full_matrices = 0 )
795- aug_rank = np .sum (S > 1.e-10 )
798+ Un , Sn , Vn_T , _ = scipy .linalg .lapack .dgesdd (bmat_tmp , full_matrices = 0 )
799+ aug_rank = np .sum (Sn > 1.e-10 )
796800 else :
797- aug_rank = intial_rank + 1
798- if aug_rank != intial_rank :
801+ aug_rank = initial_rank + 1
802+ if aug_rank != initial_rank :
799803 if debug :
800804 print ("Adding cycle {0}" .format (i ))
801805 bmat_dense = bmat_tmp
806+ U = Un
807+ S = Sn
808+ V_T = Vn_T
802809 hb_out .append (minima_sets [i ])
803- intial_rank = aug_rank
810+ initial_rank = aug_rank
804811 if len (hb_out ) == len (hb ):
805812 break
806813 else :
807814 if debug :
808815 print ("Skipping cycle {0}" .format (i ))
816+
817+ # Verify that final rank matches expected rank for final hole group
818+ if j == len (hb )- 1 :
819+ U , S , V_T , _ = scipy .linalg .lapack .dgesdd (bmat_dense , full_matrices = 0 )
820+ final_rank = np .sum (S > 1e-10 )
821+ if final_rank != initial_rank :
822+ raise ValueError ("Error in hole optimization: Final rank {0} does not match expected rank {1}" .format (final_rank , initial_rank ))
809823 indent_level = indent_level [:- 2 ]
810824
811825 # Save computed internal cycles to hole list
0 commit comments