@@ -866,11 +866,12 @@ def process_as_index(varname):
866866 v = mesh .attrs ['face_edge_connectivity' ]
867867 if v in nc :
868868 # Some files advertise variable they don't have. Trust no one.
869- ug .cells ['edges' ] = nc [mesh . attrs [ 'face_edge_connectivity' ] ].values
869+ ug .cells ['edges' ] = nc [v ].values
870870 if 'edge_face_connectivity' in mesh .attrs :
871871 v = mesh .attrs ['edge_face_connectivity' ]
872872 if v in nc :
873- ug .edges ['cells' ] = nc [mesh .attrs ['edge_face_connectivity' ]].values
873+ cells = nc [v ].values
874+ ug .edges ['cells' ] = np .where ( np .isfinite (cells ), cells , - 1 )
874875
875876 if dialect == 'fishptm' :
876877 ug .cells_center ()
@@ -7750,6 +7751,7 @@ def circumcenter_errors(self,radius_normalized=False,cells=None,
77507751 errs /= np .mean (dists ,axis = 1 )
77517752 errors [sel ]= errs
77527753 return errors
7754+
77537755 def angle_errors (self ):
77547756 centers = self .cells_center ()
77557757 e2c = self .edge_to_cells (recalc = True )
@@ -7764,7 +7766,54 @@ def angle_errors(self):
77647766 / mag (edge_vecs ) )
77657767 angle_err = (np .arccos (dots ) - np .pi / 2 )
77667768 return angle_err
7769+
7770+ def dfm_cosphiunet (self ):
7771+ """
7772+ Compute per-edge cosphiunet as in DFM. 0.0 on edges without two adjacent cells.
7773+ This is the cosine of the angle between the center-center vector and the edge vector.
7774+ 0.0 is ideal. 0.5 is typical DFM threshold. Reports signed values, but only the absolute
7775+ value really matters. cosphi=nan for edges with coincident cell centers
7776+ """
7777+ cc = self .cells_center ()
7778+ e2c = self .edge_to_cells ()
7779+ cosphi = np .zeros (self .Nedges (), np .float64 )
7780+
7781+ is_link = e2c .min (axis = 1 )>= 0
7782+ cosphi [~ is_link ]= 0.0
7783+
7784+ cell_vecs = cc [e2c [is_link ,0 ]] - cc [e2c [is_link ,1 ]]
7785+ edge_vecs = self .nodes ['x' ][self .edges ['nodes' ][is_link ,1 ]] - self .nodes ['x' ][self .edges ['nodes' ][is_link ,0 ]]
7786+
7787+ cell_mags = (cell_vecs ** 2 ).sum (axis = 1 )
7788+ edge_mags = (edge_vecs ** 2 ).sum (axis = 1 )
7789+
7790+ mags = cell_mags * edge_mags
7791+ bad_link = mags < 1e-6
7792+ mags [bad_link ] = 1
7793+ cosphi [is_link ] = np .where (bad_link , np .nan , (cell_vecs * edge_vecs ).sum (axis = 1 ) / np .sqrt (mags ))
7794+ return cosphi
77677795
7796+ def dfm_linklength (self ):
7797+ """
7798+ Compute nondimensional link length
7799+ DFM (tag 141798) compares center:center distance
7800+ dist(center1-center2) < 0.9*removesmalllinkstrsh*0.5*(sqrt(area1)+sqrt(area2))
7801+
7802+ Where the default threshold is 0.1.
7803+ This method returns
7804+ dist(center1-center2) / 0.9*0.5*(sqrt(area1)+sqrt(area2))
7805+ """
7806+ lengths = np .zeros (self .Nedges (),np .float64 )
7807+ e2c = self .edge_to_cells ()
7808+ cc = self .cells_center ()
7809+ internal = e2c .min (axis = 1 )>= 0
7810+ lengths [~ internal ] = np .nan
7811+ sqrt_area = np .sqrt (self .cells_area ())
7812+ cA = e2c [internal ,0 ]
7813+ cB = e2c [internal ,1 ]
7814+ lengths [internal ] = mag (cc [cA ]- cc [cB ]) / (0.9 * 0.5 * (sqrt_area [cA ]+ sqrt_area [cB ]))
7815+ return lengths
7816+
77687817 def edge_clearance (self ,edges = None ,mode = 'min' ,cc = None ,Ac = None ,
77697818 eps_Ac = 1e-5 ,recalc_e2c = False ):
77707819 """
0 commit comments