文档库 最新最全的文档下载
当前位置:文档库 › 8 FISH Begunner's Guide (fish语言入门指导)

8 FISH Begunner's Guide (fish语言入门指导)

8 FISH Begunner's Guide (fish语言入门指导)
8 FISH Begunner's Guide (fish语言入门指导)

4FISH BEGINNER’S GUIDE

4.1Introduction and Overview

FISH is a programming language embedded within PFC2D that enables the user to de?ne new variables and functions.These functions may be used to extend PFC2D’s usefulness or add user-de?ned features.For example,new variables may be plotted or printed,special particle generators may be implemented,servo-control may be applied to a numerical test,unusual distributions of properties may be speci?ed,and parameter studies may be automated.

FISH was developed in response to requests from users who wanted to do things with Itasca software that were either dif?cult or impossible to do with existing program structures.Rather than incorporate many new and specialized features into the standard code,it was decided that an embedded language would be provided so that users could write their own functions.Some useful FISH functions have already been written;an interrelated set of such functions,known as the Augmented Fishtank,is provided with the PFC2D program(see Section3in the FISH volume). It is possible for someone without experience in programming to write simple FISH functions or to modify some of the simpler existing functions.Section4.2contains an introductory tutorial for non-programmers.However,FISH programs can also become very complicated(which is true of code in any programming language);for more details,refer to Section2in the FISH volume.

As with all programming tasks,FISH functions should be constructed in an incremental fashion,

checking operations at each level before moving on to more complicated code.FISH does less error-checking than most compilers,so all functions should be tested on simple data sets before using them for real applications.

FISH programs are simply embedded in a normal PFC2D data?le—lines following the word processed as a FISH function;the function terminates when the word END is encountered.

may invoke other functions,which may invoke others,and so on.The order in which functions are de?ned does not matter as long as they are all de?ned before they are used(e.g., invoked by a PFC2D command).Since the compiled form of a FISH function is stored in PFC2D’s memory space,the SAVE command saves the function and the current values of associated variables.

A complete de?nition of FISH language rules and intrinsic functions is provided in Section2in the FISH volume.This includes rules for syntax,data types,arithmetic,variables and functions. All FISH language names are described in Section2in the FISH volume,and a summary of the names is provided in the Command and FISH Reference Summary.

4.2Beginner’s Guide and Tutorial

This section is intended for people who have run PFC2D(at least for simple problems)but have not used the FISH language;no programming experience is assumed.To get the maximum bene?t from the examples given here,you should try them out with PFC2D running interactively.The short programs may be typed in directly.After running an example,give the PFC2D command NEW to “wipe the slate clean,”ready for the next example.Alternatively,the more lengthy programs may be created on?le and CALL ed when required.

Type the lines in Example4.1after PFC2D’s command prompt,pressingat the end of each line.(In this and all subsequent examples,the?rst line,which starts with a semicolon,is only a comment line and need not be typed.)

Example4.1De?ning a FISH function

;fname:fishb1.DAT

def abc

abc=22*3+5

end

Note that the command prompt changes to Def>after the?rst line has been typed in;then it changes back to the usual prompt when the command END is entered.This change in prompt lets you know if you are sending lines to PFC2D or to FISH.Normally,all lines following the DEFINE statement are taken as part of the de?nition of a FISH function(until the END statement is entered).However, if you type in a line that contains an error(e.g.,you type the=sign instead of the+sign),then you will get the PFC2D prompt back again.In this case,you should give the NEW command and try again from the beginning.Since it is very easy to make mistakes,FISH programs are normally typed into a?le using an editor.These are then CALL ed into PFC2D just like a regular PFC2D data ?le.We will describe this process later;for now,we’ll continue to work interactively.Assuming that you typed in the above lines without error and that you now see the PFC2D prompt Pfc2D>, you can“execute”the function abc,*de?ned earlier in Example4.1,by typing the line print abc

The message

abc=71

should appear on the screen.By de?ning the symbol abc(using the DEFINE...END construction, as in Example4.1),we can now refer to it in many ways using PFC2D commands.

For example,the PRINT command causes the value of a FISH symbol to be displayed;the value is computed by the series of arithmetic operations in the line

*We will use courier boldface to identify user-de?ned FISH functions and declared variables in the text.

abc=22*3+5

This is an“assignment statement.”If an equal sign is present,the expression on the right-hand side of the equal sign is evaluated and given to the variable on the left-hand side.Note that arithmetic operations follow the usual conventions;addition,subtraction,multiplication and division are done with the signs+,-,*and/,respectively.The sign?denotes“raised to the power of.”

We now type in a slightly different program(using the command NEW to erase the old one): Example4.2Using a variable

;fname:fishb2.DAT

new

def abc

hh=22

abc=hh*3+5

end

Here we introduce a“variable,”hh,which is given the value of22and then used in the next line. If we give the command PRINT abc,then exactly the same output as in the previous case appears. However,we now have two FISH symbols;they both have values,but one(abc)is known as a “function”and the other(hh)as a“variable.”The distinction is as follows.

When a FISH symbol name is mentioned(e.g.,in a PRINT statement),

the associated function is executed if the symbol corresponds to a

function.However,if the symbol is not a function name,then the

current value of the symbol is simply used.

The following experiment may help to clarify the distinction between variables and functions. Before doing the experiment,note that PFC2D’s SET command can be used to set the value of any user-de?ned FISH symbol,independent of the FISH program in which the symbol was introduced. Now type in the following lines without giving the command NEW,since we want to keep our previously entered program in memory.

Example4.3SET ting variables

;fname:fishb3.DAT

set abc=0hh=0

print hh

print abc

print hh

The SET command sets the values of both abc and hh to zero.Since hh is a variable,the?rst PRINT command simply displays the current value of hh,which is zero.The second PRINT command causes abc to be executed(since abc is the name of a function);the values of both hh and abc

are thereby recalculated.Accordingly,the third PRINT statement shows that hh has indeed been reset to its original value.As a test of your understanding,you should type in the slightly modi?ed sequence shown in Example4.4and?gure out why the displayed answers are different.

Example4.4Test your understanding of function and variable names

;fname:fishb4.DAT

new

def abc

abc=hh*3+5

end

set hh=22

print abc

set abc=0hh=0

print hh

print abc

print hh

At this stage,it may be useful to list the most important PFC2D commands that directly refer to simple FISH variables or functions.(In Table4.1,below,var stands for the name of the variable or function.)

Table4.1Commands that directly

refer to FISH names

PRINT var

SET var=value

HISTORY var

We have already seen examples of the?rst two(refer to Examples4.3and4.4);the third case is useful when histories are required of things that are not provided in the standard PFC2D list of history variables.Example4.5shows how this can be done.

Example4.5shows how the unbalanced force on a particle can be stored in a FISH variable and used by the HISTORY command.

Example4.5Capturing the history of a FISH variable

;fname:fishb5.DAT

new

wall id5kn1e8nodes-5,05,0

ball id1x0y 1.1rad1

prop dens1000kn1e8

set grav0-10

set dt max=2e-3

def down_force

down_force=b_yfob(ball_head)

end

hist down_force

cyc500

plot his1

In this example,a ball is dropped onto a plane,it bounces and then comes to equilibrium.The name b yfob in the function is an example of a pre-de?ned variable name—in this case,corresponding to the unbalanced force in the y-direction.ball head is another pre-de?ned name and corresponds to the“address”of the ball.All of PFC2D’s pre-de?ned names are de?ned in Table2.1in the FISH volume.At the end of the run,we simply plot out the history of yforce(history1)just like any other history.In a similar way,we may use FISH functions to plot out a history of any quantity we wish,no matter how complicated the formula might be to describe it.

In addition to the above-mentioned pre-de?ned variable names,there are many other pre-de?ned objects available to a FISH program.These fall into several classes;one such class consists of scalar variables,which are single numbers—for example,

clock clock time in hundredths of a second

piπ

step current step number

unbal maximum unbalanced force

urand random number drawn from uniform distribution between

0.0and1.0.

Another useful class of built-in objects is the set of intrinsic functions,which enables things like sines and cosines to be calculated from within a FISH program.A complete list is provided in Section2.5.2in the FISH volume;a few are given below:

abs(a)absolute value of a

cos(a)cosine of a(a is in radians)

log(a)base-ten logarithm of a

max(a,b)returns maximum of a,b

sqrt(a)square root of a

An example in the use of intrinsic functions will be presented later,but now we must discuss one further way in which a PFC2D data?le can make use of user-de?ned FISH names.

Wherever a number is expected in a PFC2D input line,you may

substitute the name of a FISH variable or function.

This simple statement is the key to a very powerful feature of FISH that allows such things as ranges,applied forces and properties to be computed in a FISH function and used by PFC2D input in symbolic form.Hence,parameter changes can be made very easily,without the need to change many numbers in an input?le.

Example4.6allows the wall geometry and stiffness to be set in one place at the start of the?le, rather than in many places.This reduces the risk of errors and data?le corruption,as well as making it possible to reuse a single piece of work on many models.

Example4.6Using symbolic constants in a FISH function

;fname:fishb6.DAT

new

def box_geometry

n_stiff=2e8

s_stiff=1e8

xx= 5.0

yy= 3.0

end

box_geometry

macro wall1nodes’nodes(0,0)(xx,0)’

macro wall2nodes’nodes(xx,0)(xx,yy)’

macro wall3nodes’nodes xx yy0yy’

macro wall4nodes’nodes0yy00’

wall id=1ks=s_stiff kn=n_stiff wall1nodes

wall id=2ks=s_stiff kn=n_stiff wall2nodes

wall id=3ks=s_stiff kn=n_stiff wall3nodes

wall id=4ks=s_stiff kn=n_stiff wall4nodes

plot wall red id on

print wall prop

print macro

In passing,note that there is great?exibility in choosing names for FISH variables and functions; the underline character()may be included in a https://www.wendangku.net/doc/1519220534.html,s must begin with a non-number and must not contain any of the arithmetic operators(+,–,/,*or?).A chosen name should not be the same as one of the built-in(or reserved)names;Table2.1in Section2.2.2in the FISH volume contains a complete list of names to be avoided,as well as some rules that should be followed.

In the above examples,we checked the computed values of FISH variables by giving their names explicitly as arguments to a PRINT command.Alternatively,we can list all current variables and functions by giving the command

print fish

We now examine ways in which decisions can be made and repeated operations can be done in FISH programs.The following FISH statements allow speci?ed sections of a program to be repeated many times:

LOOP var(expr1,expr2)

ENDLOOP

The words LOOP and ENDLOOP are FISH statements,the symbol var stands for the loop variable, and expr1and expr2stand for expressions(or single variables).Example4.7shows the use of a loop(or repeated sequence)to produce the sum and product of the?rst10integers.

Example4.7Controlled loop in FISH

;fname:fishb7.DAT

new

def xxx

sum=0

prod=1

loop n(1,10)

sum=sum+n

prod=prod*n

endloop

end

xxx

print sum,prod

In this case,the loop variable n is given successive values from1to10,and the statements inside the loop(between the LOOP and ENDLOOP statements)are executed for each value.As mentioned, variable names or an arithmetic expression could be substituted for the numbers1or10.

A practical use of the loop in PFC2D would be to select each ball in a model in turn and access and/or change some property.Example4.8contains the FISH function makecolors,which shows how we can(randomly,in this case)change the color index of each ball in the model.Here, integer values in the range0to2are assigned as color indices.

Example4.8Manipulating variables in a loop construct

;fname:fishb8.DAT

new

generate x=0,1y=0,1rad=0.05,0.07id=1,20

def makecolors

bp=ball_head

loop while bp#null

xx=int(urand*3)

b_color(bp)=xx

bp=b_next(bp)

end_loop

end

makecolors

plot ball red green blue

Having seen several examples of FISH programs,let’s brie?y examine the question of program syntax and style.A complete FISH statement must occupy one line;there are no continuation lines. If a formula is too long to?t on one line,then a temporary variable must be used to split the formula. Example4.9shows how this can be done.

Example4.9Splitting lines

;fname:fishb9.DAT

new

def long_sum;example of a sum of many things

temp1=v1+v2+v3+v4+v5+v6+v7+v8+v9+v10

long_sum=temp1+v11+v12+v13+v14+v15

end

In this case,the sum of15variables is split into two parts.Note also the use of the semicolon after the function name to indicate a comment.Any characters that follow a semicolon are ignored by the FISH compiler,but they are echoed to the log?le.It is good programming practice to annotate programs with informative comments.Some of the programs have been shown with indentation—that is,space inserted at the beginning of some lines to denote a related group of statements.Any number of space characters may be inserted(optionally)between variable names and arithmetic operations to make the program more readable.Again,it is good programming practice to include indentation to indicate things like loops,conditional clauses and so on.Spaces in FISH are“signi?cant”in the sense that space characters may not be inserted into a variable or function name.

One other topic that should be addressed now is that of variable type.You may have noticed,when printing out variables from the various program examples,that numbers are either printed without decimal points or in“E-format”—that is,as a number with an exponent denoted by“E.”At any

instant in time,a FISH variable or function name is classi?ed as one of four types:integer,?oating-point,string or pointer.These types may change dynamically,depending on context,but the casual user should not normally have to worry about the type of a variable,since it is set automatically. Consider Example4.10.

Example4.10Variable types

;fname:fishb10.DAT

new

def haveone

aa=2

bb= 3.4

cc=’Have a nice day’

dd=aa*bb

ee=cc+’,old chap’

end

haveone

print fish

print aa bb cc dd ee

The variables aa,bb and cc are converted to integer,?oat and string,respectively,corresponding to the numbers(or strings)that were assigned to them.Integers are exact numbers(without decimal

points)but are of limited range;?oating-point numbers have limited precision(about15decimal places)but are of much greater range;string variables are arbitrary sequences of characters;pointers are used to address internal variables in PFC2D.There are various rules for conversion between the four For example,dd becomes a?oating-point number because it is set to the product of a?oating-point number and an integer;the variable ee becomes a string because it is the sum (concatenation)of two strings.The topic can get quite complicated,but it is fully explained in Section2.2.5in the FISH volume.

There is a further language element in FISH that is commonly used—the IF statement.The following three statements allow decisions to be made within a FISH program.

IF expr1test expr2THEN

ELSE

ENDIF

These statements allow conditional execution of FISH program segments;ELSE and THEN are optional.The item test consists of one of the following symbols or symbol-pairs:

=#><>=<=

The meanings are standard except for#,which means“not equal.”The items expr1and expr2 are any valid expressions or single variables.If the test is true,then the statements immediately following IF are executed until ELSE or ENDIF is encountered.If the test is false,the statements between ELSE and ENDIF are executed if the ELSE statement exists;otherwise,the program jumps to the?rst line after ENDIF.The action of these statements is illustrated in Example4.11.

Example4.11Action of the IF ELSE ENDIF construct

;fname:fishb11.DAT

new

def abc

if xx>0then

abc=33

else

abc=11

end_if

end

set xx=1

print abc

set xx=-1

print abc

The displayed value of abc in Example4.11depends on the set value of xx.You should experiment with different test symbols(e.g.,replace>with<).

Until now,our FISH programs have been invoked from PFC2D either by using the PRINT command, or by giving the name of the function on a separate line of PFC2D input.It is also possible to do the reverse—that is,to give PFC2D commands from within a FISH function.Most valid PFC2D commands can be embedded between the following two FISH statements:

COMMAND

ENDCOMMAND

There are two main reasons for sending out PFC2D commands from a FISH program.First,it is possible to use a FISH function to perform operations that are not possible using the pre-de?ned variables that we already discussed.Second,we can control a complete PFC2D run with FISH.

Example4.12Use of the COMMAND ENDCOMMAND construct

;fname:fishb12.DAT

new

def make_walls

command

wall id=1nodes=(0,0)(5,0)

wall id=2nodes=(5,0)(5,3)

wall id=3nodes=(5,3)(0,3)

wall id=4nodes=(0,3)(0,0)

endcommand

end

make_walls

plot wall id=on red

In Example4.12,we create four walls from within the function make walls.The four PFC2D wall commands must be enclosed within a COMMAND ENDCOMMAND construct in order to be executed from within a FISH function.

We have now covered some of the aspects of the FISH language and how it interacts with PFC2D.

A complete guide to the language is contained in Section2in the FISH volume.

相关文档