Execution of FISH Functions

In general, PFC and FISH operate as separate entities; FISH statements cannot be given as PFC commands, and PFC commands do not work directly as statements in a FISH program. However, there are many ways in which the two systems may interact; some of the more common ways are listed below. References to FISH symbols on the command line must be preceded by an @ character or enclosed by brackets [].

  1. Direct use of function – A FISH function is executed at the user’s request by giving its name on an input line. Some typical uses are to generate geometry, set up a particular profile of material properties, or initialize stresses in some fashion.
  2. Use as a history variable – When used as the parameter to a i history command, a FISH function is executed at regular intervals throughout a simulation, whenever histories are stored.
  3. Automatic execution during stepping – If a FISH function makes use of the generalized callback capability, then it is executed automatically at every step in PFC’s calculation cycle, or whenever a particular event occurs. (See fish callback for a discussion on callback events.)
  4. Use of function to control a run – Since a FISH function may issue PFC commands (via the command statement), the function can be used to “drive” PFC, similar to the way a data file is controlled. However, the use of a FISH function to control operation is much more powerful, since parameters to commands may be changed by the function.

The primary method of executing a FISH function from PFC is to give its name as PFC input. In this way, FISH function names act just like regular commands in PFC.

Another important link between FISH and PFC is that in a PFC command, a FISH symbol (variable or function name) may be substituted anywhere that a number, string, or vector is expected. This is a very powerful feature, because data files can be set up with symbols rather than with actual numbers.


;fname: fishr10.dat
;
; Create a string of 5 balls
;
model new
model domain extent -10 10
ball create id=1 pos-x=0.0 pos-y=0.0 pos-z=0.0 rad=0.5
ball create id=2 pos-x=1.0 pos-y=0.0 pos-z=0.0 rad=0.5
ball create id=3 pos-x=2.0 pos-y=0.0 pos-z=0.0 rad=0.5
ball create id=4 pos-x=3.0 pos-y=0.0 pos-z=0.0 rad=0.5
ball create id=5 pos-x=4.0 pos-y=0.0 pos-z=0.0 rad=0.5
;
fish define mark_ball(bid)
;
; ----- Set extra index 1 of the ball with id of [bid] equal to 1.
;
; INPUT: bid - ball id number of ball to be marked
;
  loop foreach local bp ball.list
    if ball.id(bp) = bid then
      ball.extra(bp,1) = 1
    else
      ball.extra(bp,1) = 0
    end_if
  end_loop
end
@mark_ball(2)  ;{input: bid}
;
plot item create ball color-by numeric-attribute "extra" 1

The example illustrates several of the points alluded to above: the function mark_ball is invoked by giving its name on a line; and the parameter controlling the function is passed as a function argument. After executing this example, one can mark another ball by setting bid equal to 4, and then calling mark_ball again.

String variables may be used in a similar way, but their use is much more restricted than the use of numerical variables. A FISH string variable may be substituted: (a) wherever a file name is required; or (b) as a parameter to the model title command. In these cases, single quotes are not placed around the string so that PFC can distinguish between a literal name and a variable standing for a name. The next example illustrates the syntax:


;fname: fishr11.dat
model new
fish define xxx
   name1 = 'abc.log'
   name2 = 'This is run number ' + string(n_run)
   name3 = 'abc' + string(n_run) + '.sav'
end
[n_run = 3]
@xxx
log-file = @name1
log on
model title @name2
log off
model save @name3
sys "del *.sav"

Another important method of using a FISH function is to control a PFC run or a series of PFC operations. PFC commands are placed within a c command - endcommand section in the function. The whole section may be within a loop, and parameters may be passed to PFC commands. This approach is illustrated in the next example, in which three complete runs are done, each with a different value of tip-ball density. As the density is increased, the tip deflection increases, as can be seen in the plot view that shows the 5-ball beam, the ball velocities and displacements, and a history of the y-position of the tip ball. For each run (i.e., execution of the loop), tip-ball density is set and the model title is redefined, so that the current value of tip-ball density is displayed in the title bar of the plot view. Also, note the use of the program pause command to halt processing until the user enters the program continue command.


;fname: fishr12.dat
model new
model domain extent -10 10
contact cmat default model linearpbond
ball create id=1 pos-x=0.0 pos-y=0.0 pos-z=0.0 rad=0.5   ; create 5 balls in a line
ball create id=2 pos-x=1.0 pos-y=0.0 pos-z=0.0 rad=0.5
ball create id=3 pos-x=2.0 pos-y=0.0 pos-z=0.0 rad=0.5
ball create id=4 pos-x=3.0 pos-y=0.0 pos-z=0.0 rad=0.5
ball create id=5 pos-x=4.0 pos-y=0.0 pos-z=0.0 rad=0.5
ball attribute density 2000 damp 0.7
ball property 'kn'=1e8 'ks'=1e8  
; create contacts
model clean
; bond them into a beam using pbonds
contact method bond gap 0.1
contact property pb_kn=1e10 pb_ks=1e10 pb_ten=1e20 pb_coh=1e20
ball fix velocity spin range id=1     ; fix ball at left end
model gravity 0 0 -9.8                ; specify gravity loading
ball history name 10 position-z id=5    ; monitor y-position of tip ball
;
fish define run_series
  bdens = 2000.0
  loop nn (1,3)
    t_var = ' Density of tip ball = ' + string(bdens)
    command
      ball attribute dens @bdens range id=5  ; modify density of tip ball
      model title @t_var
model cycle 1000
    end_command
    bdens = bdens + 3000
  end_loop
end
@run_series