Thank you very much, Theophile,
I used a longer version for my code where it is very important to find the bad blocks.
;
fish define b_sa_min(index_)
local use_deformable = true
local use_rigid = false
if block.rigid(index_) = 1
bf = block.facelist(index_, use_rigid)
else
bf = block.facelist(index_, use_deformable )
end_if
; Now, to loop through the block faces:
loop foreach local bfpnt bf
; Do stuff considering that bfpnt is a block face pointer
end_loop
end
;
fish define sa_bad
;
;------- FISH range to find blocks with small face surface area -------
;INPUT: sa_min: minimum face area. Block is selected if any face area is below this value
argument ;(position)
argument ;(object)
b = range.isin(r,a)
if b_sa_min(object) < sa_min then
sa_bad = 1
else
sa_bad = 0
endif
end
fish define findBadBlock()
loop foreach local bPnt block.list()
loop foreach local fPnt block.facelist(bPnt,~block.rigid(bPnt))
if block.face.area(fPnt)<b_sa_min
block.group(bPnt,'bad') ="yes"
exit loop
endif
endloop
endloop
end
;
;
fish define b_edge_min(index_)
;
; ----- Function to determine minimum edge length for a given block
;
; INPUT: index_ - index of block to be tested
;
if block.rigid(index_) = 1 then ; rigid
bf = block.facelist(index_)
else ; deformable
bf = block.facelist(index_)
endif
local ret = 1.0e24
loop while bf # 0
local block.gp.num = block.face.ngp(bf)
local next = 2
loop n (1,block.gp.num)
if n = block.gp.num then
next = 1
endif
local v1 = block.gp.pos(block.face.gp(bf, n)) ;vector of gridpoint 1
local v2 = block.gp.pos(block.face.gp(bf, next)) ;vector of gridpoint 2
local edge = math.mag(v1-v2) ;magnitude of vector difference
ret = math.min(ret,edge)
next = next + 1
endloop
bf = block.face.next(bf)
endloop
b_edge_min = ret
end
;
fish define edge_bad
;
; -------- FISH range to find blocks with small edge lengths -------------
;
; INPUT: e_min - minimum edge length. Block is selected if any edge length is below this value
;
argument position
argument object
if b_edge_min(object) < e_min then
edge_bad = 1
else
edge_bad = 0
endif
end
;
fish define b_aspect_max(index_)
;
; ----- Function to calculate maximum aspect ratio for input block
;
; INPUT: index_ - index of block to be tested
;
if block.rigid(index_) = 1 then ; rigid
bf = block.facelist(index_)
else ; deformable
bf = block.facelist(index_)
endif
local ret = 0.0
loop while bf # 0
local block.gp.num = block.face.ngp(bf)
local next = 2
loop n (1,block.gp.num)
if n = block.gp.num then
next = 1
endif
local v1 = block.gp.pos(block.face.gp(bf, n)) ;vector of gridpoint 1
local v2 = block.gp.pos(block.face.gp(bf, next)) ;vector of gridpoint 2
local edgel = math.mag(v1-v2) ;magnitude of vector difference
local aspect = edgel/(block.vol(index_)^(1.0/3.0)) ;aspect ratio
ret = math.max(ret,aspect)
next = next + 1
endloop
bf = block.face.next(bf)
endloop
b_aspect_max = ret
end
;
fish define aspect_bad
;
; ----- FISH range to find blocks with large aspect ratios ----------
;
; INPUT: a_max - maximum aspect ratio. Block is selected if aspect ratio is greater than this value
;
argument position
argument object
if b_aspect_max(object) > a_max then
aspect_bad = 1
else
aspect_bad = 0
endif
end
;
fish define b_max_fa(index_)
;
; Function to get maximum angle between faces on a given block
;
; NOTE 1: This assume block is convex. Will not return angles > 180 degrees
; NOTE 2: If maximum angle is less than 90 degrees, this function will return 0
;
; INPUT: index_ - index of block to be tested
;
if block.rigid(index_) = 1 then ; rigid
bf = block.facelist(index_)
else ; deformable
bf = block.facelist(index_)
endif
local ret = 0.0
loop while bf # 0
local n1 = block.face.normal(bf)
local bf2 = block.face.next(bf)
loop while bf2 # 0
local n2 = block.face.normal(bf2)
local dot_product = math.dot(n1,n2)
if dot_product > 0 ; ensure pointing in the same direction
if dot_product > 0.99999 ; coincident - 180 degrees
ret = math.pi
else
ret = math.max(ret,math.pi-math.acos(dot_product))
end_if
end_if
bf2 = block.face.next(bf2)
end_loop
bf = block.face.next(bf)
endloop
b_max_fa = ret/math.degrad
end
;
fish define fa_bad
;
; ----- FISH range to find blocks with large face angles
;
; INPUT: fa_max - maximum face angle in degrees. Block is slected if 2 faces have an angle greater than this
;
argument position
argument object
if b_max_fa(object) > fa_max then
fa_bad = 1
else
fa_bad = 0
endif
end
;
fish define get_worst_blocks
;
; Function to loop through all blocks and get worst ones
;
local min_vol_allblocks = 1.0e12
local min_vol_bi = 0
local min_edge_allblocks = 1.0e12
local min_edge_bi = 0
local min_area_allblocks = 1.0e12
local min_area_bi = 0
local max_aratio_allblocks = 0.0
local max_aratio_bi = 0
local max_angle_allblocks = 0.0
local max_angle_bi = 0
local bi = block.head
loop while bi # 0
if block.vol(bi) < min_vol_allblocks
min_vol_allblocks = block.vol(bi)
min_vol_bi = bi
end_if
if b_edge_min(bi) < min_edge_allblocks
min_edge_allblocks = b_edge_min(bi)
min_edge_bi = bi
end_if
if b_sa_min(bi) < min_area_allblocks
min_area_allblocks = b_sa_min(bi)
min_area_bi = bi
end_if
if b_aspect_max(bi) > max_aratio_allblocks
max_aratio_allblocks = b_aspect_max(bi)
max_aratio_bi = bi
end_if
if b_max_fa(bi) > max_angle_allblocks
max_angle_allblocks = b_max_fa(bi)
max_angle_bi = bi
end_if
bi = block.next(bi)
end_loop
end
;
; β find and group bad blocks β
;
fish set @b_sa_min 0.00003
block group βbad_faceβ range fish βsa_badβ
fish set @edge_min = 0.00020