5.4. Controlling Program Flow in APDL

When executing an input file, Mechanical APDL is normally restricted to linear program flow; that is, each statement is executed in the order that it is encountered in the listing. However, APDL provides a rich set of commands that you can use to control program flow. These commands are listed in Chapter 2 of the Command Reference.

  • Call subroutines (nested macros).

  • Branch unconditionally to a specified location with a macro.

  • Branch based upon a condition to a specified location within a macro.

  • Repeat the execution of a single command, incrementing one or more command parameters.

  • Loop through a section of a macro a specified number of times.

5.4.1. Nested Macros: Calling Subroutines Within a Macro

APDL allows you to nest macros up to 20 levels deep, providing functionally similar capability to a FORTRAN CALL statement or to a function call. You can pass up to 19 arguments to the macro and, at the conclusion of each nested macro, execution returns to the level that called the macro. For example, the following simply macro library file shows the MYSTART macro, which calls the MYSPHERE macro to create the sphere.

mystart
/prep7
/view,,-1,-2,-3
*use,mysphere,1.2
finish
/eof
mysphere
sphere,arg1
/eof

5.4.2. Unconditional Branching: Goto

The simplest branching command, *GO, instructs the program to go to a specified label without executing any commands in between. Program flow continues from the specified label. For example

*GO,:BRANCH1
---    ! This block of commands is skipped (not executed)
---
:BRANCH1
---
---

The label specified by the *GO command must start with a colon (:) and must not contain more than eight characters, including the colon. The label can reside anywhere within the same file.


Note:  The use of *GO is now considered obsolete and is discouraged. See the other branching commands for better methods of controlling program flow.


5.4.3. Conditional Branching: The *IF Command

APDL allows you to execute one of a set of alternative blocks based on the evaluation of a condition. The conditions are evaluated by comparing two numerical values (or parameters that evaluate to numerical values).

The *IF command has the following syntax

*IF, VAL1, Oper, VAL2, Base

Where

  • VAL1 is the first numerical value (or numerical parameter) in the comparison.

  • Oper is the comparison operator.

  • VAL2 is the second numerical value (or numerical parameter) in the comparison.

  • Base is the action that occurs if the comparison evaluates as true.

APDL offers eight comparison operators, which are discussed in detail in the *IF command reference. Briefly these are:

EQ

Equal (for VAL1 = VAL2).

NE

Not equal (for VAL1 ≠ VAL2).

LT

Less than (for VAL1 < VAL2).

GT

Greater than (for VAL1 > VAL2).

LE

Less than or equal (for VAL1 VAL2).

GE

Greater than or equal (for VAL1 VAL2).

ABLT

Absolute values of VAL1 and VAL2 before < operation.

ABGT

Absolute values of VAL1 and VAL2 before > operation.

By giving the Base argument a value of THEN, the *IF command becomes the beginning of an if-then-else construct (similar to the FORTRAN equivalent). The construct consists of

  • An *IF command, followed by

  • One or more optional *ELSEIF commands

  • An optional *ELSE command

  • A required *ENDIF command, marking the end of the construct.

In its simplest form, the *IF command evaluates the comparison and, if true, branches to a label specified in the Base argument. This is similar to the "computed goto" in FORTRAN. (In combination, a set of such *IF commands could function similarly to the CASE statements in other programming languages.) Take care not to branch to a label within an if-then-else construct or do-loop. If a batch input stream hits an end-of-file during a false *IF condition, the Mechanical APDL run will not terminate normally. You will need to terminate it externally (use either the Linux "kill" function or the Windows task manager).

By setting the Base argument to a value of STOP, you can exit from Mechanical APDL based on a particular condition.

An if-then-else construct simply evaluates a condition and executes the following block or jumps to the next statement following the *ENDIF command (shown with the "Continue" comment).

*IF,A,EQ,1,THEN
    !  Block1
    .
    .
*ENDIF
! Continue

The following example shows a more complex structure. Note that only one block can be executed. If no comparison evaluates to true, the block following the *ELSE command is executed.

Figure 5.4: A Sample If-Then-Else Construct

A Sample If-Then-Else Construct



Note:  You can issue a /CLEAR command within an if-then-else construct. The /CLEAR command does not clear the *IF stack and the number of *IF levels is retained. An *ENDIF is necessary to close any branching logic. Also, keep in mind that the /CLEAR command deletes all parameters, including any that are used in your branching commands. You can avoid any problems that might arise from the deletion of parameters by issuing a PARSAV command before the /CLEAR command, and then following the /CLEAR command with a PARRES command.


5.4.4. Repeating a Command

The simplest looping capability, the *REPEAT command, allows you to execute the directly preceding command a specified number of times, incrementing any field in that command by a constant value. In the example

E,1,2
*REPEAT,5,0,1

the E command generates one element between nodes 1 and 2 and the following *REPEAT command specifies that E executes a total of five times (including the original E command), incrementing the second node number by one for each additional execution. The result is five total elements with node connectivities 1-2, 1-3, 1-4, 1-5, and 1-6.


Note:  Most commands that begin with a slash (/) or an asterisk (*), as well as macros executed as "unknown commands," cannot be repeated. However, graphics commands that begin with a slash can be repeated. Also, avoid using the *REPEAT command with interactive commands, such as those that require picking or those that require a user response.


5.4.5. Looping: Do-Loops

A do-loop allows you to loop through a series of commands a specified number of times. The *DO and *ENDDO commands mark the beginning and ending points for the loop. *DO command has the following syntax:

The following example do-loop edits five load step files (numbered 1 through 5) and makes the same changes in each file.

*DO,I,1,5       ! For I = 1 to 5:
LSREAD,I        ! Read load step file I
OUTPR,ALL,NONE  ! Change output controls
ERESX,NO
LSWRITE,I       ! Rewrite load step file I
*ENDDO

You can add your own loop controls by using the *IF, *EXIT, or *CYCLE commands.

Keep the following guidelines in mind when constructing do-loops.

  • Do not branch out of a do-loop with a :Label on the *IF or *GO commands.

  • Avoid using a :Label to branch to a different line within a do-loop. Use if-then-else-endif instead.

  • Output from commands within a do-loop is automatically suppressed after the first loop. Use /GOPR or /GO (no response line) within the do-loop if you need to see output for all loops.

  • Take care if you include a /CLEAR command within a do-loop. The /CLEAR command does not clear the do-loop stack, but it does clear all parameters including the loop parameter in the *DO statement itself. You can avoid the problem of having an undefined looping value by issuing a PARSAV command before the /CLEAR command, and then following the /CLEAR command with a PARRES command.

5.4.6. Implied (colon) Do Loops

You can also use the implied (colon) convention for do loops. Using this convention is typically faster because the looping is done in memory. The correct syntax is:

(x:y:z)

with z defaulting to 1 if not specified. For example:

n,(1:6),(2:12:2)

will perform the same steps as:

n,1,2
n,2,4
n,3,6
.
.
.
n,6,12

When using the implied (colon) do loops, be aware that the shortest expression controls execution. For example,

n,(1:7),(2:12:2)

would behave identically to the example above.

Additional numeric fields that do not have the colon (:) will be taken as a constant value.

Also, non-integer numbers will function normally. However, if non-integer numbers are applied to a command that requires integers, then the non-integer will be rounded off following normal mathematical conventions.

This looping convention can be used only for fields requiring a numeric entry. Looping may also be used with GET function arguments, for example a(1:5)=nx(1:5). A text entry field will process (x:y:z) as a literal value.

The implied convention for do loops can be used to access the values of an APDL array parameter. However, it cannot be used to access the values of an APDL Math vector.

5.4.7. Additional Looping: Do-While

You can also perform looping functions that will repeat indefinitely until an external parameter changes. The *DOWHILE command has the following syntax:

*DOWHILE,Parm

The loop repeats as long as the parameter Parm is TRUE. If Parm becomes false (less than or equal to 0.0), the loop terminates. The *CYCLE and *EXIT commands can be used within a *DOWHILE loop.