is a high-level command language, facilitating the setting up of flow-simulation problems.
For In-Form, the latest extension to the Power of PIL, click here.
Especially useful in this regard are the PIL statements:
A simple example is provided by core-library case 119, which is concerned with the calculation of the distance from the wall within an enclosure.
The parts of the Q1 file which are concerned with the menu will now be presented and explained.
** Declarations ** BOOLEAN(BLOCK) ** Settings ** BLOCK=F
The logical (ie boolean) variable BLOCK is declared, so as to be set
true or false later, in answer to a question; whereafter certain
actions will or will not ensue.
Its default value is FALSE
XULAST=1.0; YVLAST=1.0; ZWLAST=1.0 CARTES=T; RINNER=YVLAST/2
Here some default values of geometrical variables are provided, which can be changed later.
** messages to screen ** LABEL DISPLAY
This is the "label" to which control will be passed if any data changes are made subsequently.
MESG(x, y & z dimensions are.. :xulast:, :yvlast:, :zwlast: IF(CARTES) THEN MESG(grid is cartesian ELSE MESG(grid is cylindrical polar ENDIF IF(BLOCK) THEN MESG(there is a central blockage ELSE S MESG(the box is empty ENDIF
The words following MESG( are what are displayed on the screen; and the IF..THEN..ELSE..ENDIF structures determine whether they will be displayed.
** Questions ** MESG(Are data settings OK? (Y/n)
This is an important first question; for, if the settings are OK, there is no point in asking further questions.
(Y/n) invites the answer Yes or no, the upper case of Y being a conventional indication that Yes is the default, which will be taken if any no other answer is given.
READVDU(ANS,CHAR,Y) IF(:ANS:.EQ.Y) THEN GOTO PROCEED
READVDU puts the user's answer into the variable ANS, which it will treat as being of CHARacter type, with default value Y.
The next statements send control to the PROCEED label, to be seen below, if the answer is Y.
ELSE IF(CARTES) THEN + MESG(change to polar grid? (Y/n) + READVDU(ANS,CHAR,Y)
If the settings are not what the user wants, the next question concerns a possible change to a polar grid. It is asked only if the grid is cartesian, ie not polar already.
The + signs appear so as to indicate that what follows is to be read by SATELLITE, even though it does not start in the first or second column. This enables indentation to be used so as to clarify the nested logical structure.
+ IF(:ANS:.EQ.Y) THEN + CARTES=F + GOTO DISPLAY + ENDIF ENDIF
If the answer is Y, the PIL variable CARTES is set FALSE; then the data settings are displayed again. Otherwise control proceeds to the next question.
IF(.NOT.BLOCK) THEN + MESG(introduce blockage? (Y/n) + READVDU(ANS,CHAR,Y) + IF(:ANS:.EQ.Y) THEN + BLOCK=T + GOTO DISPLAY + ENDIF ENDIF
This concerns, evidently, whether a blockage is to be placed inside the box. If it is, the logical variable BLOCK is set to TRUE.
MESG(change dimensions of box? (Y/n) READVDU(ANS,CHAR,Y) IF(:ANS:.EQ.Y) THEN
The user is now given the opportunity to change the enclosure dimensions.
+ MESG(x-dimension is :xulast: . New value? + MESG(in metres if cartesian, otherwise radians + READVDU(XULAST,REAL,XULAST)
Taking this opportunity enables the user to set new values of XULAST (in metres or radians according to the value of CARTES)
+ MESG(y-dimension is :yvlast: . New value? + READVDU(YVLAST,REAL,YVLAST)
and then YVLAST
+ MESG(z-dimension is :zwlast: . New value? + READVDU(ZWLAST,REAL,ZWLAST) + GOTO DISPLAY
and then ZWLAST
+ IF(.NOT.CARTES) THEN + MESG(Inner radius = :rinner: . New value?) + READVDU(RINNER,REAL,RINNER) + ENDIF
and finally, if CARTES = TRUE, RINNER .
ENDIF ENDIF LABEL PROCEED
Here is the PROCEED label, after which no further questions are posed.
IF(BLOCK) THEN STORE(PRPS) PATCH(BLOCK,INIVAL,NX/4+1,3*NX/4,NY/4+1,3*NY/4,NZ/4+1,3*NZ/4,1,1) COVAL(BLOCK,PRPS,0.0,100.0) ENDIF
However, consequences of the menu-made settings are of course to be found. Here it is seen how, if and only if BLOCK is TRUE, the PRPS value is stored, and then given a "solid" value in a central portion of the enclosure.
It should be remarked that no questions are asked about the size or
location of the blockage, which are therefore fixed by the PATCH arguments:
Of course, the menu options could easily be extended, by declaring integer variables indicating what cells of the grid the solid was to occupy, and providing appropriate question-and-answer sequences.
Whether a user prefers to make this extension, or simply to edit the default values, is a matter of choice, to be made by reference to:-
The setting of individual values may become rather tedious; it is therefore useful to point out that menus can be easily created for making several settings simultaneously, as in the following simple example,
** Declarations ** REAL(XLENGTH,YLENGTH,ZLENGTH) CHAR(SETNAME,BILLS,JANES,JOHNS,MARYS) ** Defaults ** XLENGTH=1.0; YLENGTH=1.0; ZLENGTH=1.0
It is supposed that the user most easily remembers the data sets as Bill's, Jane's, John's and Mary's. The question is therefore asked as follows:
MESG(Whose data set do you wish to use? Default is Bill's. MESG(Insert one of: BILLS, JANES, JOHNS or MARYS. MESG(You can use upper or lower case; but not an apostrophe. READVDU(SETNAME,CHAR,BILLS)
The consequences of the choice are then indicated by such statements as:
IF(:SETNAME:.EQ.BILLS) THEN XLENGTH=1.0; YLENGTH=2.0; ZLENGTH=3.0 ELSE IF(:SETNAME:.EQ.JANES) THEN + XLENGTH=3.5; YLENGTH=2.0; ZLENGTH=0.01 ELSE + IF(:SETNAME:.EQ.JOHNS) THEN + XLENGTH=0.5; YLENGTH=1.5; ZLENGTH=0.1 + ELSE + IF(:SETNAME:.EQ.MARYS) THEN + XLENGTH=3.5; YLENGTH=0.25; ZLENGTH=10.0 + ENDIF + ENDIF ENDIF ENDIF
The consequences of the choice are then indicated by the following:
XLENGTH YLENGTH ZLENGTH
which cause the values of the quantities in question to be printed
on the screen as:
XLENGTH = etc
Of course, as many entries as are desired can be included in the sections of the Q1 file devoted to Bill, Jane, etc. However, it is often convenient to keep large sets of data in individual files, which can be called in by use of the INTRPT statement, as shown here:
IF(:SETNAME:.EQ.BILLS) THEN INTRPT(R,billsfile) ELSE
where billsfile is the full pathname to the file containing the data.
A PIL "macro" is a set of PIL statements which can be invoked by way of the load, # or intrpt commands to permit re-use of previously-assembled sets of statements.
References to them can be found in section 5 of this encyclopaedia entry, in the article on In-Form, and elsewhere (for example the PHENC article on MAXABS).
Evidence is afforded by inspecting the files in the directory /phoenics/d_satell/d_men/ and below, namely:
These files are "PIL fragments" which interact with each other by way of LOAD statements.