# Compare the signs - 3dec fish

Hi,
I would like to see the sign (in terms of velocity) of some blocks (after applying the input) and compare it with the sign (in terms of acceleration) of the input.

My idea is as follows:
sgn (vbk) = sgn (a)
And depending on the situation create two scenarios
If sgn (vbk) is equal to sgn (a) β scenario 1
If sgn (vbk) is not equal to sgn (a) β scenario 2

Can you tell me how to do it?

1 Like

You can use the math.sgn function. See here: math.sgn β 3DEC 7.0 documentation (itascacg.com)

1 Like

instead, for obtain the sum in terms of mass of all the blocks in the model?

I am trying to convert this function from 3DEC 5.0 to 3DEC 7 and I get the following error, any idea how to modify this?

def b_sa_min(index_)
if b_type(index_) = 1 then ; rigid
bf = b_face(index_)
else ; deformable
bf = b_face2(index_)
endif

The converted version suggests the following

fish define b_sa_min(index_)
if %%block.rigid%%(index_) = 1 then ; rigid
;%%- Not an exact analology to b_type
bf = %%block.facelist%%(index_)
;%%- Use foreach to loop through faces
else ; deformable
bf = %%block.facelist%%(index_)
;%%- Use foreach to loop through faces. Set second parameter to true for original block faces
endif

Hi.

The suggestion is right.
However, notice that in 3DEC5.20, bf would be a block face index.
In 3DEC7.00, bf is the list of all the block faces, as mentioned in official documentation

So, if you wish to loop through your blocks, the complete function would be:

``````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
``````

Cheers

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 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
else
endif
``````

end

``````loop foreach local bPnt block.list()

loop foreach local fPnt block.facelist(bPnt,~block.rigid(bPnt))

if block.face.area(fPnt)<b_sa_min

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 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
else
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 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
else
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

``````

end
;
;
; ----- 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
else
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

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