Language Reference Manual

Transcription

Language Reference Manual
acslX
Language Reference Guide
Version 3.0
March 2010
The AEgis Technologies Group, Inc.
410 Jan Davis Drive
Huntsville, AL 35806
U.S.A.
Phone: (256) 922-0802
[email protected]
www.acslx.com
acslX Language Reference Guide
Copyright © 2003 – 2010 The AEgis Technologies Group, Inc.
All Rights Reserved.
Printed in the United States of America.
ACSL, acslX, and PowerBlock are registered trademarks of The AEgis
Technologies Group, Inc.
acslX and acslXpress are trademarks of The AEgis Technologies Group, Inc.
Microsoft, Windows, Microsoft .NET, and Microsoft Internet Explorer are either
registered trademarks or trademarks of Microsoft Corporation in the United
States and/or other countries.
FLEXlm is a registered trademark of Globetrotter Software, Inc., A Macrovision
Company
All other brand and product names mentioned herein are the trademarks and
registered trademarks of their respective owners.
Information in this document is subject to change without notice. The software
described in this document is furnished under a license agreement. The software
and this documentation may be used only in accordance with the terms of those
agreements.
The AEgis Technologies Group, Inc.
410 Jan Davis Drive
Huntsville, AL 35806
U.S.A.
Phone: (256) 922-0802
[email protected]
www.acslx.com
March 2010
Table of Contents
Chapter 1 Introduction ........................................................................................................... 6
1.1 Simulation Language ....................................................................................................................... 6
1.2 The Model Editor Windows .............................................................................................................. 6
1.3 Building Process .............................................................................................................................. 8
1.4 Language features ........................................................................................................................... 8
1.4.1 Operators and functions ............................................................................................................ 9
1.4.2 Integration.................................................................................................................................. 9
1.4.3 INTEG operator ......................................................................................................................... 9
1.4.4 Redundant state variables....................................................................................................... 10
1.4.5 Limit cycle example ................................................................................................................. 10
1.4.6 Runtime commands................................................................................................................. 11
1.5 Coding procedure........................................................................................................................... 11
1.5.1 Separator ................................................................................................................................. 11
1.5.2 Continuation............................................................................................................................. 12
1.5.3 Comments ............................................................................................................................... 12
1.5.4 Blank lines ............................................................................................................................... 12
1.6 Reserved names ............................................................................................................................ 12
1.6.1 System variable defaults ......................................................................................................... 12
1.6.2 Precedence of names.............................................................................................................. 13
Chapter 2 Language Elements .............................................................................................14
2.1 Introduction .................................................................................................................................... 14
2.2 Constants ....................................................................................................................................... 14
2.2.1 Integer...................................................................................................................................... 14
2.2.2 Promotion of integers .............................................................................................................. 15
2.2.3 Floating point ........................................................................................................................... 15
2.2.4 Logical ..................................................................................................................................... 15
2.2.5 Character ................................................................................................................................. 16
2.3 Variables ........................................................................................................................................ 16
2.3.1 Types ....................................................................................................................................... 16
2.3.2 Subscripts ................................................................................................................................ 16
2.3.3 Array order............................................................................................................................... 16
2.4 Labels............................................................................................................................................. 17
2.4.1 Syntax...................................................................................................................................... 17
2.4.2 Statement labels and macro expansion .................................................................................. 17
2.4.3 CONTINUE statements ........................................................................................................... 18
2.5 Expressions.................................................................................................................................... 18
2.5.1 Arithmetic operators ................................................................................................................ 18
2.5.2 Parentheses............................................................................................................................. 18
2.5.3 Warning - dividing by integer ................................................................................................... 19
2.5.4 Relational operators ................................................................................................................ 19
2.5.5 Logical operators ..................................................................................................................... 19
2.5.6 Operands ................................................................................................................................. 19
Chapter 3 Program Structure................................................................................................22
3.1 Implicit and explicit structure .......................................................................................................... 22
3.2 Program flow .................................................................................................................................. 22
3.2.1 INITIAL..................................................................................................................................... 23
3.2.2 DERIVATIVE DISCRETE ........................................................................................................ 24
3.2.3 DYNAMIC ................................................................................................................................ 24
3.2.4 STOP flag ................................................................................................................................ 24
3.2.5 Integration................................................................................................................................ 24
3.2.6 Transfer control ....................................................................................................................... 25
3.2.7 TERMINAL............................................................................................................................... 25
Language Reference Manual
i
3.3 Program sorting.............................................................................................................................. 25
3.3.1 States....................................................................................................................................... 26
3.3.2 CONSTANT ............................................................................................................................. 26
3.4 Program Structure Preset of User Variables.................................................................................. 26
3.4.1 Algebraic loops ........................................................................................................................ 26
3.4.2 Diagnosing loops ..................................................................................................................... 26
3.4.3 Multiple INITIAL, DYNAMIC, and TERMINAL sections........................................................... 26
3.4.4 Section nesting ........................................................................................................................ 27
3.5 Preset of user variables ................................................................................................................. 27
3.6 Preset of derivatives....................................................................................................................... 27
Chapter 4 acslX Statements .................................................................................................28
4.1 Introduction .................................................................................................................................... 28
4.1.1 Documentation convention ...................................................................................................... 28
4.1.2 ! & ; : ........................................................................................................................................ 28
4.1.3 CONSTANT recompilation ...................................................................................................... 28
4.1.4 Debugging ............................................................................................................................... 29
4.1.5 Equal sign (=) .......................................................................................................................... 29
4.1.6 Equal sign in PROCEDURAL .................................................................................................. 29
4.1.7 Operators for simulation models.............................................................................................. 29
4.1.8 State operators ........................................................................................................................ 30
4.1.9 Array name conflicts ................................................................................................................ 30
4.1.10 Standalone form of operators .................................................................................................. 30
4.1.11 Precision of acslX operators.................................................................................................... 31
4.1.12 Forcing precision ..................................................................................................................... 31
4.2 ABS 32
4.3 ACOS ............................................................................................................................................. 32
4.4 AINT ............................................................................................................................................... 32
4.5 ALGORITHM.................................................................................................................................. 33
4.5.1 Array with multiple sections ..................................................................................................... 33
4.5.2 Recommended integration control .......................................................................................... 34
4.5.3 Fixed step algorithms .............................................................................................................. 35
4.5.4 Runge-Kutta procedure ........................................................................................................... 35
4.5.5 Variable step algorithms .......................................................................................................... 37
4.5.6 Adams-Moulton ....................................................................................................................... 37
4.5.7 Gear's stiff................................................................................................................................ 38
4.5.8 Runge-Kutta-Fehlberg ............................................................................................................. 38
4.5.9 MINT with variable step algorithms ......................................................................................... 39
4.5.10 NSTP with variable step algorithms ........................................................................................ 39
4.5.11 Error summary......................................................................................................................... 39
4.5.12 Determining appropriate step size........................................................................................... 40
4.5.13 Efficiency and accuracy........................................................................................................... 40
4.6 ANINT............................................................................................................................................. 41
4.7 ASIN ............................................................................................................................................... 41
4.8 Assignment statements.................................................................................................................. 41
4.8.1 Arithmetic................................................................................................................................. 41
4.8.2 Logical ..................................................................................................................................... 42
4.8.3 Character ................................................................................................................................. 42
4.9 ATAN.............................................................................................................................................. 43
4.10 ATAN2............................................................................................................................................ 43
4.11 BCKLSH ......................................................................................................................................... 43
4.12 BOUND .......................................................................................................................................... 44
4.13 CALL .............................................................................................................................................. 45
4.14 CHARACTER................................................................................................................................. 45
4.15 CINTERVAL ................................................................................................................................... 45
4.15.1 Adjusting step size to CINT ..................................................................................................... 46
Language Reference Manual
ii
4.15.2 Calculating CINT ..................................................................................................................... 46
4.15.3 Changing default name ........................................................................................................... 47
4.15.4 Bound on integration step........................................................................................................ 48
4.16 CMPXPL ........................................................................................................................................ 48
4.17 Comment (!) ................................................................................................................................... 49
4.18 CONSTANT ................................................................................................................................... 50
4.19 Continuation (&) ............................................................................................................................. 51
4.20 CONTINUE .................................................................................................................................... 52
4.21 COS 53
4.22 DBLE .............................................................................................................................................. 53
4.23 DBLINT........................................................................................................................................... 53
4.24 DEAD ............................................................................................................................................. 56
4.25 DELAY............................................................................................................................................ 56
4.26 DELSC ........................................................................................................................................... 58
4.27 DELVC ........................................................................................................................................... 59
4.28 DERIVATIVE.................................................................................................................................. 60
4.29 DERIVT .......................................................................................................................................... 61
4.30 DIM 62
4.31 DIMENSION ................................................................................................................................... 62
4.32 DISCRETE ..................................................................................................................................... 64
4.33 DO 65
4.34 DOUBLE PRECISION.................................................................................................................... 65
4.35 DYNAMIC....................................................................................................................................... 66
4.36 END 66
4.37 ERRTAG ........................................................................................................................................ 67
4.38 EXP 67
4.39 FCNSW .......................................................................................................................................... 67
4.40 GAUSI, UNIFI................................................................................................................................. 68
4.41 GAUSS........................................................................................................................................... 69
4.42 GO TO............................................................................................................................................ 69
4.43 HARM............................................................................................................................................. 70
4.44 HISTORY ....................................................................................................................................... 71
4.45 IF, IF-THEN-ELSE ......................................................................................................................... 71
4.46 IMPLC ............................................................................................................................................ 74
4.47 IMPVC ............................................................................................................................................ 76
4.48 INCLUDE ....................................................................................................................................... 77
4.49 INITIAL ........................................................................................................................................... 78
4.50 INT 79
4.51 INTEG ............................................................................................................................................ 79
4.52 INTEGER ....................................................................................................................................... 81
4.53 INTERVAL...................................................................................................................................... 81
4.54 INTVC............................................................................................................................................. 82
4.55 LEDLAG ......................................................................................................................................... 84
4.56 LIMINT............................................................................................................................................ 85
4.57 LOG 86
4.58 LOG10............................................................................................................................................ 86
4.59 LOGICAL........................................................................................................................................ 87
4.60 LSW, RSW ..................................................................................................................................... 87
4.61 MACRO .......................................................................................................................................... 88
4.62 MAX 88
4.63 MAXTERVAL, MINTERVAL........................................................................................................... 88
4.64 MERROR, XERROR...................................................................................................................... 90
4.65 MIN 91
4.66 MINTERVAL................................................................................................................................... 91
4.67 MOD ............................................................................................................................................... 92
4.68 NINT ............................................................................................................................................... 92
4.69 NSTEPS ......................................................................................................................................... 92
Language Reference Manual
iii
4.70 OU 94
4.71 PARAMETER................................................................................................................................. 96
4.72 PROCEDURAL .............................................................................................................................. 97
4.73 PROGRAM..................................................................................................................................... 99
4.74 PTR 99
4.75 PULSE.......................................................................................................................................... 100
4.76 QNTZR......................................................................................................................................... 101
4.77 RAMP ........................................................................................................................................... 101
4.78 REAL ............................................................................................................................................ 102
4.79 REALPL ....................................................................................................................................... 102
4.80 RESET ......................................................................................................................................... 103
4.81 RSW ............................................................................................................................................. 104
4.82 RTP 104
4.83 SAVE............................................................................................................................................ 104
4.84 SCALE.......................................................................................................................................... 105
4.85 SCHEDULE.................................................................................................................................. 105
4.86 SCHEDULE Time Event Specification......................................................................................... 109
4.87 SCHEDULE State Event Specification ........................................................................................ 111
4.88 SCHEDULE State Event Mechanization...................................................................................... 111
4.89 Separator (;) ................................................................................................................................. 115
4.90 SIGN............................................................................................................................................. 115
4.91 SIN 115
4.92 SORT ........................................................................................................................................... 116
4.93 SQRT ........................................................................................................................................... 116
4.94 STEP ............................................................................................................................................ 118
4.95 TABLE .......................................................................................................................................... 119
4.96 TAN 122
4.97 TERMINAL ................................................................................................................................... 122
4.98 TERMT ......................................................................................................................................... 123
4.99 TRAN............................................................................................................................................ 124
4.100TRANZ ......................................................................................................................................... 126
4.101Type 128
4.102UNIF ............................................................................................................................................. 130
4.103UNIFI ............................................................................................................................................ 130
4.104VARIABLE.................................................................................................................................... 130
4.105XERROR ...................................................................................................................................... 130
Chapter 5 Macro Language.................................................................................................131
5.1 Introduction .................................................................................................................................. 131
5.1.1 Macro versus subroutine ....................................................................................................... 131
5.1.2 Macro definitions ................................................................................................................... 131
5.1.3 Features................................................................................................................................. 132
5.1.4 Forms of call .......................................................................................................................... 132
5.1.5 Concatenation........................................................................................................................ 132
5.1.6 INITIAL, DYNAMIC, DISCRETE, and TERMINAL sections .................................................. 133
5.1.7 Macro definitions ................................................................................................................... 133
5.1.8 Macro definition header ......................................................................................................... 134
5.1.9 First form................................................................................................................................ 134
5.1.10 Second form .......................................................................................................................... 134
5.1.11 Substitutable symbols............................................................................................................ 135
5.1.12 Concatenation........................................................................................................................ 135
5.1.13 Macro directive statements.................................................................................................... 136
5.1.14 Labels .................................................................................................................................... 136
5.1.15 MACRO ASSIGN................................................................................................................... 137
5.1.16 Arithmetic macro directives ................................................................................................... 137
5.1.17 MACRO CONTINUE ............................................................................................................. 138
Language Reference Manual
iv
5.1.18 MACRO DECREMENT ......................................................................................................... 138
5.1.19 MACRO DIVIDE .................................................................................................................... 138
5.1.20 MACRO EXIT ........................................................................................................................ 138
5.1.21 MACRO GO TO..................................................................................................................... 139
5.1.22 MACRO IF ............................................................................................................................. 139
5.1.23 MACRO INCREMENT ........................................................................................................... 139
5.1.24 MACRO MULTIPLY............................................................................................................... 140
5.1.25 MACRO PRINT...................................................................................................................... 140
5.1.26 MACRO REDEFINE .............................................................................................................. 140
5.1.27 MACRO RELABEL ................................................................................................................ 140
5.1.28 MACRO STANDVAL ............................................................................................................. 141
5.2 Macro examples........................................................................................................................... 142
5.2.1 Sampler ................................................................................................................................. 142
5.2.2 Dot product ............................................................................................................................ 143
5.2.3 Second type........................................................................................................................... 143
5.2.4 REDEFINE............................................................................................................................. 143
5.2.5 Dimensions ............................................................................................................................ 143
5.2.6 MACRO IF ............................................................................................................................. 144
5.2.7 Expansion .............................................................................................................................. 144
5.2.8 Pressure tank......................................................................................................................... 145
5.2.9 Concatenation........................................................................................................................ 145
5.2.10 Definition................................................................................................................................ 145
5.2.11 Invocation .............................................................................................................................. 145
5.2.12 Expansion .............................................................................................................................. 145
5.2.13 Constants and variables ........................................................................................................ 146
5.2.14 Alternative form ..................................................................................................................... 146
5.2.15 Advantages of concatenation ................................................................................................ 146
5.2.16 Matrix operations ................................................................................................................... 146
5.2.17 Matrix multiply macro............................................................................................................. 147
5.2.18 Dimensions ............................................................................................................................ 147
5.2.19 Invocation .............................................................................................................................. 147
5.3 Macro invocation .......................................................................................................................... 149
5.3.1 Single output.......................................................................................................................... 149
5.3.2 Standalone forms .................................................................................................................. 150
5.3.3 Argument substitution............................................................................................................ 150
5.3.4 Use of parentheses ............................................................................................................... 150
Chapter 6 Standard Block Libraries ...................................................................................152
6.1
6.2
6.3
6.4
6.5
6.6
6.7
6.8
6.9
Boolean ........................................................................................................................................ 153
Controls Operations ..................................................................................................................... 154
Filters Operations......................................................................................................................... 155
Linear Operations......................................................................................................................... 157
Math Operations........................................................................................................................... 159
Nonlinear Operations ................................................................................................................... 160
Plots Operations........................................................................................................................... 161
Sources Operations ..................................................................................................................... 163
Trigonometry Operations ............................................................................................................. 164
Appendix A
General Purpose Utilities...........................................................................166
Language Reference Manual
v
Chapter 1
Introduction
1.1 Simulation Language
The simulation of physical systems is a standard analysis method used to
evaluate designs prior to actual construction. acslX provides a simple method of
modeling systems described by time-dependent, nonlinear differential equations
and/or transfer functions. Typical continuous simulation applications include
control system design, chemical process representation, missile and aircraft
simulation, power plant dynamics, biomedical systems, vehicle handling,
microprocessor controllers, fluid flow, and heat transfer analysis. Users can
derive code for the simulation model from block diagrams, mathematical
equations, conventional C/C++ or Fortran statements, etc.
1.2 The Model Editor Windows
With acslX the user has the choice to describe models in textual or graphical
form. The acslX text code editor window can be used to build, edit, or display a
.csl file as well as other text files used within the acslX system.
Figure 1-1: acslX code window
Language Reference Manual
6
There are a few commands that are essential for work with the text editor.
•
•
•
•
To delete a line, place the mouse cursor just to the left of the line, and when
an arrow appears, click the left mouse button to highlight the line, then
press Delete.
To add a line, place the cursor at the end of the previous line, then press
Enter.
To add text, place the cursor at the location where the text should be and
start typing.
To copy/paste text,
•
•
•
•
•
Select the text to be copied.
Press Ctrl-C or right-click and select Copy from the pop-up menu.
Place the cursor where the text needs to be pasted.
Press Ctrl-V or right-click and select Paste from the pop-up menu.
To drag-and drop text, select the text, then click and hold the left mouse
button while dragging the text to the new position.
acslX allows you to describe models using graphical block diagrams as well. For
creating block diagrams the block diagram window and the schematic editor is
used.
Figure 1-2: acslX Block Diagram Window
Language Reference Manual
7
A block can be a compound block, which again is build from connected blocks, or
a PowerBlock, which contains a slightly modified version of CSL code. acslX is
delivered with a large set of standard block libraries. Additional toolkit libraries
are available for certain application areas and users can build their own block
libraries. The elements of the standard block libraries are described in Chapter 6.
1.3 Building Process
Once the process of defining and representing a model using either the graphical
block diagrams or a CSL model is completed the program is ready for the acslX
translators.
Model Translation
Model Translation takes place in two steps. In first stage translation the model
representation is converted to XML. The second stage translation converts the
XML to the desired target language, either C/C++ or FORTRAN.
Model Compilation
During this stage the model code is compiled and linked to create the model
executable (.dll) file.
Simulation Execution
Simulation Control Commands: simulation control commands, which exercise the
model, can be submitted in runtime files (so-called M-Files) or entered
interactively. Interactively you can run the simulation, look at the results, and
change constants to experiment with the model; for example, trying different
spring constants or actuator limits.
At this point, the compiled simulation can be run using one of the following
methods:
•
•
•
interactively at the command prompt of the command window (“>”)
by executing a runtime file
by selecting a toolbar or menu item which results in execution of the
simulation
1.4 Language features
Working from an equation description of the problem, acslX statements are
written to describe the proposed system. Plotting flexibility is provided by using a
number of external forcing functions. Many simulation-oriented operators such as
variable time delay, dead zone, backlash, and quantization are included. By
default, all calculations are double-precision.
The sorting of the continuous model equations is a feature of acslX, in contrast to
general purpose programming languages such as C/C++ Fortran where program
execution depends on statement order.
Language Reference Manual
8
The language consists of a set of arithmetic operators, standard functions, a set
of special acslX statements, and a MACRO capability. The MACRO capability
allows extension of the special acslX statements, either at the system level for
each installation, or for each individual user.
1.4.1
Operators and functions
The arithmetic, relational, and logical operators are described in Chapter 2. The
functions, listed in Chapter 4, consist of special acslX operators such as QNTZR
(quantization), UNIF (uniform random number), etc. In addition, library functions
are available; e.g., SQRT (square root), MOD (modulus), etc. describes the
available function blocks for block diagram programs.
1.4.2
Integration
Integration is a special acslX operator that is called by either INTEG (scalar) or
INTVC (vector). This is written in the form:
r = INTEG(x, rzero)
which implies:
T
r = rzero + ∫ x ⋅ dt
0
This integration operator is the heart of the simulation system. In building any
model, differential operators must be changed into integration operators by
expressing the highest derivative of a variable in terms of lower derivatives and
other variables. For example, consider the spring dashpot system excited by a
given function of time F(t). In general form, this is:
&x&( t ) + 2 ⋅ ζ ⋅ ω ⋅ x& ( t ) + ω 2 ⋅ x( t ) = F( t )
where ω is the natural frequency and ζ the damping ratio. Expressing this
equation in terms of the highest derivative, &x&
&x&( t ) = F( t ) − 2 ⋅ ζ ⋅ ω ⋅ x& ( t ) − ω 2 ⋅ x( t )
1.4.3
INTEG operator
This derivative can then be integrated once for x& and again for x. Since x&
appears on the right hand side, it must be given a name (xd). The two
integrations can be written in the program as:
xd = INTEG(F(T) - 2*ze*w*xd - w**2*x, xdic)
x = INTEG(xd, xic)
In general, this process transforms the original set of differential equations to a
set of first order equations which can be solved directly by integrating.
Language Reference Manual
9
1.4.4
Redundant state variables
Be careful to avoid introducing redundant state variables in the transformation
process. In the above sequence, the reference to x& (xd) could have been
avoided by calculating &x& (xdd) directly and embedding an INTEG operator in the
expression; i.e.,
xdd = F(T) - 2*ze*w*INTEG(xdd, xdic) - w**2*x
Now x is the second integral of xdd and can be calculated as follows:
x = INTEG(INTEG(xdd, xdic), xic)
In these two equations, there are three INTEG operators (each one a state
variable), but two are integrations of XDD with the same initial condition. One is
redundant and can be eliminated by explicitly naming the first derivative as
shown previously.
1.4.5
Limit cycle example
To introduce the process of coding a model, we will outline a simple example
using arithmetic operators and the SQRT and INTEG functions. The following
equations define a limit cycle:
x& = y +
y& = − x +
x ⋅ (1 − x 2 − y 2 )
x2 + y2
; x( 0 ) = 0 . 5
y ⋅ (1 − x 2 − y 2 )
x2 + y2
; y( 0 ) = 0 . 0
The equations are coded as follows:
r2 = x**2 + y**2
x = INTEG(y + x*(1.0 - r2)/SQRT(r2), 0.5)
y = INTEG(-x + y*(1.0 - r2)/SQRT(r2), 0.0)
While this series of statements completely describes the equations to be solved,
it does not represent the complete problem statement. The following listing
shows the complete running program including the runtime commands.
(1) DERIVATIVE ! limit cycle
(2)
CONSTANT xz = 0.5 , yz = 0.0 ,tf = 4.0
(3)
CINTERVAL cint = 0.2
(4)
r2 = x**2 + y**2
(5)
x = INTEG( y + x*(1.0 - r2)/SQRT(r2), xz)
(6)
y = INTEG(-x + y*(1.0-r2)/SQRT(r2), yz)
(7)
TERMT(t .ge. tf, `Time Limit')
(8) END
(9) output t x y
(10) start
Language Reference Manual
10
(11) % Change initial conditions and run again
(12) XZ=0.7
(13) start
Figure 1-3: Limit cycle example of model code and runtime commands
NOTE: Statements are numbered for reference.
(1) A DERIVATIVE statement defines the beginning of the program.
(2) It is better to use a symbol set to the value instead of literal constants (e.g.,
0.5). So X(0) and Y(0), and the stop time TF are preset in the CONSTANT
statement. Changes then occur in one place in the program, and values can also
be changed at runtime.
(3) The CINTERVAL operator specifies the communication interval (data logging
rate).
(7) The TERMT statement specifies the termination condition.
(8) The END statement matches the DERIVATIVE statement and completes the
program definition. This END statement tells the translator that no more acslX
statements are expected.
1.4.6
Runtime commands
NOTE: (9) through (13) of Figure 1-3 are examples of runtime statements of the
analysis language (also known as M-Languange).
(9) OUTPUT defines the variables to be listed on the screen at each
communication interval as the run progresses.
(10) The model is then executed by the command start.
(11) Comment, to document how the program should run.
(12) Changes the initial condition.
(13) Runs the model again.
The whole example is described in more details in the Examples Manual, which
gives more detailed explanations and shows examples of results and plots.
1.5 Coding procedure
When writing acslX models it is useful to follow some rules in placing statements
to make programs easier to read.
1.5.1
Separator
More than one statement can be placed on one line by separating the statements
with a semicolon (;). The $ character may also be used in place of the semicolon
to delimit statements.
Language Reference Manual
11
1.5.2
Continuation
Any statement can be continued on the next line by adding an ampersand (&) at
the end of the line, to the right of any nonblank information. Trailing blanks are
removed from the line containing the ampersand and the following line is added
directly. Starting with column 1, it is as though the characters were strung on the
end after the last nonblank character of the preceding line. Leading blanks of the
continuation line are not suppressed unless a leading ampersand is present on
the continuation line. Comments can be added after the trailing ampersand since
comments are stripped off first. An empty line needs two ampersands because a
single one can't be distinguished.
1.5.3
Comments
Everything after an exclamation point (!) is considered a comment and ignored by
the program translator and the runtime executive (in runtime commands).
In-line comments may be specified by placing the comment text between double
quotes, with the limitation that the double-quoted comment may not be inside of a
parenthesized expression (due to the ambiguity cause by quoted arguments to
macros).
Example:
Correct use of double-quote comment:
“Linear acceleration:”
accel = F/M “MKS Units”;
Incorrect use of double-quote comment:
C = C1*exp(-A1*t “exponential decay”);
1.5.4
Blank lines
Blank lines can be placed anywhere in the program and have no effect.
1.6 Reserved names
The only reserved names in the language are those of the form Znnnnn and
ZZaaaa, where n is any digit and a is any alphanumeric character. All generated
variables and system subroutine names are in this form. However, using names
that have already a meaning could always cause problems (e.g., defining MAXT
as a state variable).
1.6.1
System variable defaults
System variable default names are listed in Figure 1-4. These default names can
be changed to any name, but if names are not specified, the default names exist
so they can be set by program control in the model definition section.
NOTE: Other uses of these names (e.g., defining MAXT as a state variable)
could cause conflicts.
Language Reference Manual
12
Statement
Default name Default value Definition
ALGORITHM
IALG
5
Integration algorithm
CINTERVAL
CINT
0.1
Communication interval
ERRTAG
none
.FALSE.
Error flag
MAXTERVAL MAXT
1.0E+10
Maximum calculation interval
MINTERVAL
MINT
1.0E-10
Minimum calculation interval
VARIABLE
T
0.0
Independent variable
Figure 1-4: System Variable Defaults
1.6.2
Precedence of names
When using a symbol name at the command prompt, the system searches first in
the dictionary of acslX system symbols. However, if a system symbol is used as
a name in the program, it takes precedence over the acslX system symbol.
Generally duplicating system symbol names within the program interferes with
the ability to modify system default values.
Language Reference Manual
13
Chapter 2
Language Elements
2.1 Introduction
The following outline the major points of the acslX language. .
•
•
•
•
•
•
Coding - Free format in program lines, only restricted by the underlying
compiler.
Labels - Labels can be alphanumeric. Labels are separated from the their
statements by a colon; i.e., label: statement.
Due to conflicts with macro expansions within labeled statements, labels
should only be used with CONTINUE statements. See the section on labels.
Variable names - Name length is limited by the target language compiler.
Names should not be of the form Znnnnn or ZZaaaa where n is any number
and a is any alphanumeric character. Blanks are not allowed within names.
Types - All variables and functions are considered floating point (single or
double precision depending on the library specified) unless typed explicitly
otherwise.
Continuation - An ampersand (&) at the end of a line indicates continuation
onto the next line.
Comments - An exclamation point (!) indicates a comment. acslX ignores all
code from an exclamation point to the end of the line.
2.2 Constants
Constants may be integer, floating point (double precision), logical, or character.
It is better to assign constants to variable names (see section 2.3). Literal
constants can be used in the source code, but their values can not be changed at
runtime. To change a literal constant, all occurrences in the source code must be
changed and the program retranslated, compiled, and linked. It is better to give
all constants symbolic names using CONSTANT statements; i.e., rather than
area = 3.142*r**2
the following code is preferred
CONSTANT pi = 3.142
area = pi*r**2
2.2.1
Integer
An integer constant is a whole number, written without a decimal point, exponent,
or embedded blanks. Positive numbers may be prefixed with a plus sign;
negative numbers must be prefixed with a minus sign. The maximum length of an
integer is machine dependent. Subscripts of arrays are generally limited to five
digits. Examples of integer constants include:
0
Language Reference Manual
+526
-63
476
14
2.2.2
Promotion of integers
A number without a decimal point (1 instead of 1.0) can normally be used where
a floating point number is expected. The number is converted to floating point
before it is used. However, a decimal point (or a variable name) should be used
in arguments to functions, macros, or subroutines.
2.2.3
Floating point
A floating point constant is written with a decimal point and/or an exponent.
Positive numbers may be prefixed with a plus sign; negative numbers must be
prefixed with a minus sign. The exponential form is D for double precision.
Examples of floating point constants include:
3.1416
0.000345
31.416D-1
0.347D03
7.9566314D-4
-27.6D+220
3D1
Numbers entered with a decimal point and no exponent (e.g., 1.234) are given a
double precision exponent of D0 (e.g., 1.234D0) when the global double
precision translator option is selected. Numbers in expressions such as:
x = y*1.234
are handled by the compiler; i.e., the constant 1.234 is automatically promoted to
double precision if y is double precision. However, since 1.234 is not an exact
binary number, it is not as precise as 1.234D0. This promotion feature is primarily
used in arguments to subroutines where it is impossible for the compiler to
determine the precision of the subroutine argument when used inside the routine.
Use care when mixing integers and floating point numbers in subroutine
arguments because the type may change. For example:
CALL mysub(1, 1.234)
must have arguments that are an INTEGER and a REAL. To prevent a mismatch
in this situation, use the exponent form or one of the type conversion functions
DBLE or REAL. REAL(1.234) is always single precision, and DBLE(1.234) and
1.234D0 are always double precision, but 1.234E0 is changed to 1.234D0. To
ensure that the second argument is always single precision use the form:
CALL mysub(1, REAL(1.234))
2.2.4
Logical
Logical constants may be one of two values.
.TRUE.
.FALSE.
However, when logicals are plotted in acslX, zero corresponds to .FALSE. and
one to .TRUE.
Language Reference Manual
15
2.2.5
Character
Character constants are strings of letters, numbers, and other characters and are
defined by placing them in single quotes. Single quotes can be inserted by
doubling them; for example, to define a string abc'def, use
`abc''def'
SET TITLE = `Limit Cycle, Run1’
2.3 Variables
Variable names are symbolic representations, usually for numerical quantities,
that may or may not change during a simulation run. They refer to a location and
the value is equal to the current number stored in that location. Both simple and
subscripted variables may be used. Generally, variable name must start with a
letter and be followed by up to thirty letters and digits, but this is limited only by
the target language compiler. Underscores can be included in variable names to
make them more readable.
this_long_name = INTEG(motor_velocity, init_cont)
2.3.1
Types
There are four types of variables: INTEGER, REAL, CHARACTER or LOGICAL.
All acslX program variables are assumed to be DOUBLEPRECISION (single or
double precision, depending on the library specified) unless explicitly typed
otherwise. Type REAL specifies single precision. only; Examples of simple
variables include:
a
2.3.2
a57
ab57
d
k20
Subscripts
A subscripted variable may have up to six subscripts enclosed in parentheses.
Subscripts can be expressions in which the operands are simple integer
variables and integer constants, and the operators are addition, subtraction,
multiplication, and division only. For more information on storage allocation, see
DIMENSION. Examples of subscripted variable names include:
b(5,2)
c47(3)
b53(5*i + 2, 6, 7*k + 3)
array(2)
plate(2,2,3,3,2,2)
In the above examples, I and K must be declared explicitly to be INTEGER
variables.
2.3.3
Array order
Elements of arrays are written and accessed by column, then row; for example,
the elements of b(2,5)can be shown:
11 12 13 14 15
21 22 23 24 25
Language Reference Manual
16
Extracted as a single-dimensioned vector, the order is:
11 21 12 22 13 23 14 24 15 25
2.4 Labels
A label can be attached to a statement so that control is transferred to it by
GOTO statement. Labels are alphanumeric. acslX uses labels starting at 99999
and working downwards, therefore avoid labels with high numeric values to avoid
possible conflicts.
2.4.1
Syntax
A label is set off from the statement to which it applies by a colon (:), as in this
example.
L1: CONTINUE
x = a + b
1000: y = c + d
GO TO L1
2.4.2
Statement labels and macro expansion
Although statement labels can be attached to any executable statements, only
CONTINUE statements are recommended. The difficulty is that the labeled
statement may be translated into several statements; i.e., the effect of a macro
call inside a statement is that the macro is expanded first, followed by the labeled
statement.
For example, consider the random number generator GAUSS, which is a macro.
It could be used in a labeled statement in a PROCEDURAL as follows:
GO TO label
...
label: x = GAUSS(mean, sigma)
This expands to the Fortran code:
GO TO 99996
...
Z09999 = MEAN + GRV(ZZSEED)*(SIGMA)
99996 X = Z09999
With the macro call in a labeled statement, the intermediate variable Z09999 is
not assigned a value when the GO TO transition is executed. However, if a
CONTINUE is used at the labeled statement as follows:
GO TO label
...
label: CONTINUE
x = GAUSS(mean, sigma)
The code expands into the correct sequence as follows:
Language Reference Manual
17
GO TO 99996
...
99996 CONTINUE
Z09999 = MEAN + GRV(ZZSEED)*(SIGMA)
X = Z09999
2.4.3
CONTINUE statements
Attaching the LABEL to the first line of the code generated from the macro can
work. However, DO loops become a problem, since the label must be the last
operation of the loop (statements after the labeled statement are not in the loop).
Even if acslX differentiates between the DO loop labels, the language allows a
loop with direct GO TOs to the terminating statement label; e.g.,
DO label i = 1, 20
...
IF (condition) GO TO label
2.5 Expressions
An expression is a combination of operators and operands which, when
evaluated, produces a single numerical value. Expressions may contain
arithmetic, relational, and logical operators.
2.5.1
Arithmetic operators
The arithmetic operators are:
+
*
/
**
addition
subtraction
multiplication
division
exponentiation
Two arithmetic operators can not appear next to each other in an arithmetic
expression. If minus is to be used to indicate a negative operand, the sign and
the element must be enclosed in parentheses if preceded by an operator; e.g.,
b*a/(-c) -a*b - c a*(-c)
are all valid, but the following is not:
b*a/-c
2.5.2
Parentheses
Parentheses can be used to indicate groupings as in ordinary mathematical
notation, but they cannot be used to indicate multiplication.
Language Reference Manual
18
2.5.3
Warning - dividing by integer
Dividing by an integer (i.e., assuming that the integer is promoted to floating
point) sometimes gives incorrect results. For example, the first calculation results
in zero, but specifying the 2 in floating point gives the correct result:
x = 1/2/pi
x = 1/2.0/pi
zero
correct
ANSI standard forbids changing I/J/R to a supposedly equivalent I/(J*R). The
following guidelines apply:
1/2
1/2.0
1/(2*pi)
1/pi/2
2.5.4
integer zero
floated to floating point
okay
okay
Relational operators
The relational operators, the results of which can be only TRUE or FALSE, are:
.EQ.
.NE.
.GT.
.LT.
.GE.
.LE.
2.5.5
equal to
not equal to
greater than
less than
greater than or equal to
less than or equal to
Logical operators
.EQV.
combines two logical expressions to give
the value TRUE when they are equivalent; otherwise,
the value is FALSE
.NEQV.
combines two logical expressions to give
the value of TRUE when they are not equivalent and
FALSE when they are equivalent.
.NOT.
reverses the truth of the logical
expression that follows it
.AND.
combines two logical expressions to give
the value TRUE when both are TRUE; otherwise, the
value is FALSE
.OR.
combines two logical expressions to give
the value TRUE when either is TRUE; otherwise, the
value is FALSE
2.5.6
Operands
Operands may be constants, variables (simple or subscripted), or functions.
Examples of arithmetic expressions include:
a
5.76 -(c + del*aero)
3 + 16.5
Language Reference Manual
19
b + a(5)/2.75
b - SQRT(a**2 + x**2))/2.0
Relational expressions
Relational expressions are a combination of two arithmetic expressions with a
relational operator. The relational expression will have the value TRUE or FALSE
depending on whether the stated relation is valid or not. The general form of the
relational expression is:
a1 op a2
where ai are arithmetic expressions and op is a relational operator. A relational
operator must have two operands combined with one operator. Examples of valid
relational expressions include:
a .EQ. b
a57 .GT. 0.0
a + d .LT. 5.3
5.0*b - 3.0) .LE. (4.0 - c)
Logical expressions
Logical expressions are combinations of logical operands and/or logical
operators which, when evaluated, will have a value of TRUE or FALSE. The
general form of the logical expression is:
l1 op l2 op 13 op ln
where li are logical operands or relational expressions. Examples are:
LOGICAL aa, cc, lfunc
aa .AND. (b .GE. c) .OR. cc .AND. lfunc(x,y) &
.AND. (x .LE. y) .OR..NOT. aa
NOTE: The symbolic names aa, cc, and lfunc have been declared to be of type
LOGICAL, and lfunc is a function with a TRUE or FALSE result calculated from
the value of the variables x and y.
Character expressions
Character constants and variables can be joined together by the // operator.
Substrings of characters can be selected by a colon (:) operator; a substring may
not be of zero length. For example:
c1 = c2(5:10)//c3
where c1, c2, and c3 are character variables. A character variable may not
appear on both the left and right hand side of the same statement.
Mapping for the CHAR function depends on the character code used by the
compiler. ASCII is almost universal. Integers can be converted to characters
through the CHAR function; for example:
name = first//last//CHAR(period)
Language Reference Manual
20
Single characters can be converted to integer (in the opposite direction to CHAR)
by the ICHAR function.
Expressions in functions
Arguments of functions may, in general, be expressions. Since expressions can
contain functions, an arbitrary depth of complexity can be generated. Using the
SIN and COS function as an example, the following is a valid expression:
a + SIN(x*COS(5*x + y) - COS(a + z/SIN(5.3*c) &
c*y/SIN(SIN(x + y)*pi)))
The sole requirement for an expression is that it have only one value when
evaluated numerically.
Language Reference Manual
21
Chapter 3
Program Structure
3.1 Implicit and explicit structure
When an acslX simulation model contains only PROGRAM and END statements
to outline the model structure, the model is said to have implicit structure: i.e., it is
implied that the whole program is a DERIVATIVE section. This simple structure
has limitations, especially in handling initial conditions.
The more flexible explicit structure includes INITIAL, DYNAMIC (with embedded
DERIVATIVE and DISCRETE), and TERMINAL sections, as shown in Figure
3-1. If this method is chosen, any or all of the five explicit blocks may be
included. The order of the sections must be as shown, and each section must be
terminated with its own END statement.
PROGRAM
INITIAL
Statements executed before the run beings.
State variables do not contain the initial conditions yet.
END !of Initial Section
DYNAMIC
Statements executed each communication interval.
DERIVATIVE
Statements to be integrated continuously.
END !of Derivative Section
DISCRETE
Statements executed at discrete points in time.
END !OF Discrete Section
END !of Dynamic Section
TERMINAL
Statements executed after the run terminates.
END !of Terminal Section
END !of Model
Figure 3-1: Outline of Explicitly Structured Program
3.2 Program flow
Figure 3-1 outlines the flow of an acslX program with explicit structure. A
program is activated with a runtime start command
Language Reference Manual
22
Figure 3-2: Main Program Loop of acslX Model
3.2.1
INITIAL
The program proceeds sequentially through the INITIAL section, the section for
calculations performed once before the dynamic model begins. Initial condition
values are moved to the state variables (outputs of integrators) at the end of the
INITIAL section, but not all initial conditions will have been defined. Usually some
Language Reference Manual
23
initial conditions are calculated at this point. Any variables that do not change
their values during a run can be computed in INITIAL. However, CONSTANT
statements are not required to be placed in the INITIAL section; they are not
executable and can be placed anywhere in the program.
3.2.2
DERIVATIVE DISCRETE
The integration routine is initialized when control transfers out of the INITIAL
section. To ensure that all calculated variables are known before recording the
first data point, the initialization procedure involves transferring all initial condition
values into the corresponding states and evaluating the code in the DERIVATIVE
and DISCRETE sections once.
NOTE: It may appear from the program listing that the DYNAMIC section is
executed before the DERIVATIVE section; in fact, DERIVATIVE and DISCRETE
are evaluated first and should not rely on calculations in the DYNAMIC section to
initialize variables for DERIVATIVE or DISCRETE sections. On the other hand,
all values calculated in the DERIVATIVE and DISCRETE sections are available
in the DYNAMIC section.
3.2.3
DYNAMIC
After initialization and evaluation of the DERIVATIVE and DISCRETE code, the
STOP flag is reset and the program executes the code within the DYNAMIC
block. There are no restrictions on the variables that can be referred to in this
DYNAMIC section. All the states have values, and intermediate calculations in
the DERIVATIVE and DISCRETE sections have been executed.
3.2.4
STOP flag
After the DYNAMIC section has been evaluated, the STOP flag is tested; if the
flag has been set, control is transferred to the TERMINAL region. The STOP flag
is set by the TERMT statement; if any TERMT statements are included in the
DYNAMIC block, control is transferred at this check when one of the arguments
of TERMT becomes true. If the STOP flag has not been set, the program writes
out the values of all the variables specified in the output and prepare lists, the
former to the output file or terminal, the latter to a scratch file for later plotting
and/or printing.
3.2.5
Integration
The integration routine is now asked to integrate over a communication interval
(or until a termination condition is met) using the code embedded in the
DERIVATIVE blocks to evaluate the state variable derivatives.
The integration routine returns with the states advanced through the
communication interval and again the STOP flag is tested. At this point, the flag
Language Reference Manual
24
may have been set by a TERMT statement in a DERIVATIVE or DISCRETE
section; if not, the program loops and re-executes the DYNAMIC section.
3.2.6
Transfer control
Control can be transferred between some sections using GO TO statements and
statement labels, if needed. It is illegal to transfer into the DYNAMIC region,
since the integration initialization then could not be performed correctly. Transfer
from the dynamic region to either INITIAL or TERMINAL is quite acceptable; so
also is transfer between INITIAL and TERMINAL blocks. Control cannot be
transferred either into or out of DERIVATIVE or DISCRETE sections since these
are changed into a separate subroutine and, as such, are inaccessible to the
main program loop.
3.2.7
TERMINAL
Program control transfers to the TERMINAL section when the STOP flag has
been set TRUE. On passing out of the last END, control returns to the acslX
executive, which reads and processes any further runtime commands (PLOT,
DISPLAY, etc.). Note that if a jump (GO TO) sends control from the TERMINAL
section back to the INITIAL, the last output is not written out unless the LOGD
operator is used (see Chapter 4).
3.3 Program sorting
The acslX translator sorts the code in the DERIVATIVE section so that outputs
are calculated before they are used. Normal statements are sorted individually;
PROCEDURAL sections are sorted as a unit based on the declared inputs and
outputs, and no sorting is performed within the PROCEDURAL. Sorting takes
place only within sections, never across sections. The sort algorithm is relatively
simple and consists of two passes.
•
•
Pass number one-examines each statement; output variables are marked
as calculated and an input variable list consisting of all variables on the right
of the equal sign is established for the statement. A variable name may
appear simultaneously on both left and right hand sides of an equal sign in
either an assignment statement or PROCEDURAL header. In this case,
sorting takes place only on the left hand or output variable so that the block
is positioned before any use of the variable.
Pass number two-examines the list of statements one at a time. If, for a
particular statement, none of the variables on the input variable list have
their calculated flags set (meaning that the variable has already been
calculated), the statement is added to the output statement list and the
calculated flag for the output variable (or variables) is turned off. If any
variables on the input variable list are marked calculated, the statement is
placed in a temporary "saved" list and the next statement examined. If any
statement has been added to the output statement list, all the saved
statements are re-examined to see if they can now be added to the output
Language Reference Manual
25
statement list and their output variables reset. This algorithm works because
any output variables that have already been processed have their
calculated flags reset. Only output variables appearing later in the program
are flagged and as such can hold up statements that depend on these
outputs.
3.3.1
States
State variables are not flagged as calculated. States are calculated by the
integration routine before all derivative evaluations.
3.3.2
CONSTANT
For code readability, CONSTANT statements may be placed where they are
used, thought it is recommended that constants be defined prior to their frst use.
3.4 Program Structure Preset of User Variables
3.4.1
Algebraic loops
Algebraic loops are identified during translation by the fact that statements are
left over at the end of the DERIVATIVE section sort. This is considered an error
since true algebraic loops should be broken by calculations, PROCEDURALs, or
the implicit integrators IMPLC (scalars) or IMPVC (vectors).
Most algebraic loops are errors caused by incorrect PROCEDURAL headers or
missing state equations. For example, the following code:
PROCEDURAL (a, b = c, d)
a = c
b = d
END ! of procedural
d = a
causes an algebraic loop to be reported since it implies that a is a function of
both c and d, although this is not actually the case. Use PROCEDURALs
sparingly and with care. Using many small PROCEDURALs is better than using a
few large ones.
3.4.2
Diagnosing loops
When an algebraic loop is diagnosed, first check the PROCEDURALs for errors.
Second, check for a modelling error such as a missing state in a control loop.
3.4.3
Multiple INITIAL, DYNAMIC, and TERMINAL sections
INITIAL sections and TERMINAL sections can be placed anywhere in a program.
The translator appends each INITIAL section to the end of any collected
previously (to a default null INITIAL if there is no explicit user INITIAL before the
DYNAMIC or DERIVATIVE). Similarly, TERMINAL sections are collected as the
Language Reference Manual
26
translator sorts through the program, each appended to any collected previously.
Thus, any TERMINAL sections defined in a DERIVATIVE section, for example,
occur before the code in an explicit final TERMINAL section.
3.4.4
Section nesting
Any section (INITIAL, DYNAMIC, DERIVATIVE, DISCRETE, or TERMINAL) can
be nested within any other section, to any level of nesting. For example, in a
DERIVATIVE section, one can write:
SCHEDULE burnout .XN. acceleration
DISCRETE burnout
INITIAL; dt = GAUSS(0.050, 0.001); END
SCHEDULE separation .AT. t + dt
END ! of burnout
3.5 Preset of user variables
The acslX executive presets all floating point variables to 5.5555E33, integers to
55555333, and logicals to .FALSE. This helps prevent unknowingly using wrong
values if the variable is used before it is calculated, particularly where a value of
zero would allow the program to proceed when it should not.
NOTE: When variables are not calculated before being used and where more
than one start is executed in a runtime session, all runs after the first use values
left at the end of the previous run. Setting all user variables to a large number
aids in identifying uncalculated variables in the first debugging runs.
3.6 Preset of derivatives
The acslX executive presets all derivatives and residuals (as defined in INTEG,
INTVC, IMPLC, and IMPVC statements) before each start to 3.33333333E-33.
After the initial evaluation of the DERIVATIVE section, the executive checks that
all derivatives have changed from the preset value; if not, an error message is
produced:
DERIVATIVE NO. n NOT CALCULATED
This message usually indicates that a derivative calculation has been skipped or
that a derivative is specified with a CONSTANT statement, which is not
executable. Determine which derivative is referenced in the message by
checking a DEBUG dump or DISPLAY/ALL and counting down the list of
derivatives.
Language Reference Manual
27
Chapter 4
acslX Statements
4.1 Introduction
This chapter describes in detail all the basic statements recognized by the acslX
translator.
acslX places no restriction on column placement of the code. The generic form of
functions is recommended; e.g., use ABS instead of IABS, DABS, or CABS and
MAX instead of AMAX0, AMAX1, MAX0, MAX1, DMAX0, or DMAX1. To specify
a typed (non-generic) function reduces flexibility, while the generic functions
adapt to single or double precision, INTEGER or REAL type, automatically.
4.1.1
Documentation convention
In the following examples and descriptions, elements in lower case are
syntactical elements (i.e., variables) and may be replaced with any character
string that satisfies the definition. Elements shown in upper case must be exactly
as spelled out in the statement (although not necessarily in upper case). In
specifying the integration operator, for example, the word INTEG must be given
exactly while all the other elements are variables you name as part of the model.
The form is specified as:
state = INTEG(deriv, ic)
An example would then be in the form:
x = INTEG(xd, xic)
4.1.2
!&;:
The use of these characters in program code is described in this chapter under
Comment (!), Continuation (&), and Separator (;). The ampersand (&) is also
used for concatenation in macros (see Chapter 5). Statement labels, using a
colon (:), are discussed in Chapter 2. Wild cards (* and ?) are available for many
of the runtime commands, but are not used in program code.
4.1.3
CONSTANT recompilation
Variables defined in CONSTANT statements generally should not also be
defined in assignment statements. If the translator encounters this situation, it
issues the following warning message:
Warning: Re-computing a constant
See the section on CONSTANT in this chapter. The warning message can be
suppressed.
Language Reference Manual
28
4.1.4
Debugging
Calls to LOGD can help debug a program when a system debugger is not
available. See LOGD in this chapter for a description of this procedure.
4.1.5
Equal sign (=)
acslX uses the equal sign in an unfamiliar way. In translating a program, acslX
needs to know the each statement's inputs and outputs so that the statement
sequence can be sorted into the correct order. In assignment statements, all
variables to the right of the equal sign are inputs; the variable to the left is given
the single numerical value of the right hand expression and thus is the output.
This concept is extended to cases where more than one element is an output;
i.e., all elements to the left of the equal sign are considered outputs and those to
the right are considered inputs.
4.1.6
Equal sign in PROCEDURAL
This concept of the use of equal signs is extended to the PROCEDURAL, which
has the following possible form:
PROCEDURAL(a, b, c = d, e)
... block of statements
END
This code tells the translator to treat the statements bracketed by the
PROCEDURAL and its matching END statement as a block (i.e., not to rearrange
the order within the block); that D and E are inputs; and that A, B, and C are
outputs. Only variables calculated elsewhere in the same DERIVATIVE section
must be listed on the input list. Constants need not appear on the list. State
variables (output of state operators) must not appear on the list.
See the PROCEDURAL section in this chapter for details on when and how to
use this structure. See Chapter 3 for information on program flow and statement
sorting.
4.1.7
Operators for simulation models
This chapter includes descriptions of several functions especially designed for
simulation models. In general, the output of each function is a single number
(usually floating point) and the arguments are arithmetic expressions of arbitrary
complexity; i.e., these expressions may contain functions which contain
arguments which contain functions to any depth. Logical or relational expressions
are used to determine switching criteria in the special functions. Only .TRUE. or
.FALSE. are used for logical constants. Other logical representations may not be
recognized because the bit pattern of logicals depends on the installation and
compiler in use.
Language Reference Manual
29
4.1.8
State operators
Some operators involve state variables and can be invoked only from within a
DERIVATIVE section. While they may be included in a first level PROCEDURAL
block, these operators are always executed and cannot be successfully bypassed by jumping around them. They also cannot be iterated in a DO loop.
Figure 4-1 is a partial list of such operators:
Figure 4-1: State operators
If an attempt is made to skip around any of these statements, the derivative for
the state variable is usually left a non-zero value (constant while the operator is
skipped) so that the internal state variable continues to change. The correct
method for stopping a state variable from changing is to ensure that the
derivative is set to zero.
4.1.9
Array name conflicts
acslX operator macro names should not be used for arrays names because of a
potential conflict. There is no problem with scalars, but when an array element is
referenced on the right side of an equal sign, it is seen as an argument to the
system macro. acslX cannot check that the name is also defined as an array
because the TABLE statement defines an array to hold the data and a macro of
the same name for table lookup. acslX operators whose names should not be
used for arrays are shown below in Figure 4-2
Figure 4-2: acslX operators that should not be used for arrays
4.1.10
Standalone form of operators
Some operators are defined as macros. When the operator has only one output,
two alternative forms of invocation (conventional and standalone) are possible.
For example, consider the conventional use of REALPL, the first order lag:
Language Reference Manual
30
y = k1*REALPL(t1, x)
The state variable (output of the real pole function) is given a dummy name (a Z
variable). It usually helps to multiply the input rather than the output by constants
(synonymous if the operator is linear) as follows:
y = REALPL(t1, k1*x)
Now the input to the operator is an expression and in this form the standalone
macro invocation can be used as follows:
REALPL(y = t1, k1*x)
In this case (only) the variable y is assigned to the state table. This standalone
form is usually preferred to minimize the number of dummy variables, and still all
forms are numerically equivalent.
Operators that can be given in standalone form are noted in their individual
descriptions. They are listed below in Figure 4-3
Figure 4-3: Operators that can be given in standalone form
4.1.11
Precision of acslX operators
By default, the precision of operators in acslX is DOUBLEPRECISION.
4.1.12
Forcing precision
Forcing precision is usually necessary only if a variable is to be an argument to
an external subroutine within which a particular precision is specified. Assume a
subroutine MYSUB with two scalar real arguments, one scalar double and one
vector double precision arguments; i.e.,
CALL mysub(rs1, rs2, ds1, dv2)
Then types would be specified as follows to ensure consistency within the
subroutine:
REAL rs1,rs2
DOUBLEPRECISION ds1,dv2(20)
Another approach is to use the generic type changing functions REAL( ) and
DBL( ) for the scalars. Then the type has to be specified only for the vector as
follows:
DOUBLEPRECISION dv2(20)
CALL mysub(REAL(rs1), REAL(rs2), DBLE(ds1), dv2)
Language Reference Manual
31
This is the preferred way since the actual precision of the variables RS1, RS2,
and DV1 is immaterial in the acslX program.
4.2 ABS
Form:
y = ABS(x)
Description:
The output y is the absolute value of x where x is an expression. The output type
(INTEGER, or REAL, DOUBLEPRECISION) depends on the input type.
Example:
cd = cdz + cdal*al + cdde*ABS(dle)
4.3 ACOS
Form:
y = ACOS(x)
Description:
The output y is the arc cosine of x where x is a floating point variable or
expression lying between -1.0 and +1.0. The result, in radians, lies between zero
and p. The result type (REAL or DOUBLEPRECISION) depends on the input
type.
Example:
th = ACOS(x/r)
4.4 AINT
Form:
y = AINT(x)
Description:
The output y is the truncation of x where x is a floating point variable or
expression. The output type (REAL or DOUBLEPRECISION) depends on the
input type. This function differs from INT where the output is type INTEGER for
any type input. In the following example, the result is -3.0.
a = AINT(-3.7)
Language Reference Manual
32
Since INT( ) is promoted to REAL or DOUBLE as appropriate in any expression,
the only situation where it is necessary to use AINT( ) is in the argument to a
subroutine in order to force the type.
Example:
If the first argument of MYSUB is floating point, the following ensures a truncated
(integer) value, but transmitted as a floating point number:
CALL mysub(AINT(v1), ...)
Using INT( ) in this situation doesn't work since the argument is passed with type
integer.
4.5 ALGORITHM
Form:
ALGORITHM name = integer constant
Default:
name:IALG
integer constants: 5
Description:
Where name is the new name for the integer defining the runtime algorithm. This
statement can change the system variable name and/or the choice of integration
routine. The name IALG is the default and its value may be set numerically at
runtime even if the ALGORITHM statement has not been specified in the
program.
4.5.1
Array with multiple sections
Description:
If a program contains only one DERIVATIVE section and no DISCRETE
sections, ALGORITHM name (referred to by its default name IALG hereafter) is a
scalar. If the program has more than one DERIVATIVE and/or DISCRETE
section then IALG becomes an array. The elements in IALG then correspond to
the sections in the order they are encountered in the source code. If
ALGORITHM is defined outside a DERIVATIVE section, then it is the global
default for all DERIVATIVE sections. DISCRETE sections have their algorithm
slot set automatically zero. To change the algorithm for a specific DERIVATIVE
section, put an ALGORITHM statement with a unique name in the section.
Example:
DERIVATIVE
ALGORITHM fastalg = 4
Language Reference Manual
33
The scalar name given is equivalenced to the array element; for example, if the
DERIVATIVE section is first in the program, FASTALG is equivalenced to
IALG(1). At runtime, either the array element or the local name can be
referenced.
IALG(1) = 1
FASTALG = 8
NOTE: Do not change during run. The choice of integration algorithm cannot be
changed during a run because table space has to be allocated before the run
begins. After acslX determines the IALG for a run, it does not look again to see if
it has changed. The communication interval and/or integration step size can be
changed.
4.5.2
Recommended integration control
Description:
Figure 4-4 lists the available integration algorithms. For fixed step algorithms, we
recommend setting NSTEPS (NSTP) to 1 so that you control the step size with
MAXTERVAL (MAXT) and the data logging rate with the communication interval
CINTERVAL (CINT). The integration step size for fixed step algorithms is
calculated by:
H = MIN(MAXT, CINT/NSTP)
H = MIN(H, time_to_next_event)
CINT is divided by NSTP. If NSTP is 1 and MAXT is less than CINT, then MAXT
sets the integration step size and CINT affects only the data logging rate. Events
include DISCRETE sections (usually controlled by an INTERVAL statement),
state events or time events activated by SCHEDULE statements, and CINT.
CINT does not have to be an even multiple of MAXT since the integration steps
up to it automatically.
Language Reference Manual
34
IALG
Algorithm
Step
Order
1
Adams-Moulton
variable
variable
2
Gear's stiff
variable
variable
3
Euler
fixed
first
4
Runge-Kutta
fixed
second
5
Runge-Kutta
fixed
fourth
8
Runge-Kutta-Fehlberg
variable
second
9
Runge-Kutta-Fehlberg
variable
fifth
13
Adams-Bashforth
fixed
Second
14
ODEPACK
variable
variable
15
CVODE
variable
variable
Figure 4-4: Available Integration Algorithms
4.5.3
Fixed step algorithms
Description:
The Runge-Kutta routines (IALG = 4 and 5) evaluate the derivatives at various
points across a step. A weighted combination of these derivatives is then used to
step across the interval. Euler (IALG=3) makes just one derivative evaluation and
the step size must be small compared to that of other algorithms to achieve
acceptable accuracy. Euler is used for any integrations required by operators in
DISCRETE sections. Runge-Kutta second order advances the state with two
derivative evaluations per step. This usually needs a somewhat smaller step than
Runge-Kutta fourth order (four derivative evaluations per step). For the same
step size, it should run about twice as fast. Optimizing the step size and
algorithm is generally worth the effort.
The Adams-Bashforth routin (IALG = 13) is a multistep method which obtains
additional accuracy for a fixed number of derivative evaluations by retaining
derivative evaluations from the previous step to compute updates to the states.
4.5.4
Runge-Kutta procedure
Description:
Figure 4-5 shows the procedure for the fourth order Runge-Kutta algorithm. If x is
the state, h is the integration step size, and t is time, the derivative k is evaluated
at the beginning, twice at the midpoint, and once at the end of the integration
step as follows:
Language Reference Manual
35
The new state is then calculated by:
The second order Runge-Kutta routine follows a similar procedure, making one
derivative evaluation at the beginning and another at a point two-thirds across
the step as follows:
The new state is then weighted by one-fourth and three-fourths and calculated
by:
MINT, XERROR, and MERROR (discussed below for the variable step
algorithms) do not affect the fixed step algorithms in any way.
Language Reference Manual
36
Figure 4-5: Runge-Kutta fourth order algorithm
4.5.5
Variable step algorithms
Description:
The Adams-Moulton (IALG=1) and Gear's Stiff (IALG=2) are both variable step,
variable order integration routines that are self-initializing. In general they attempt
to minimize the step changing by always choosing a step size that divides evenly
into the time-to-go to the next event and keeping the per-step error in each state
variable below an allowed value. This desired value is obtained by taking the
maximum of the corresponding absolute allowed error (XERROR) and the
relative allowed error (MERROR) multiplied by the maximum absolute value of
the state so far:
The order of integration starts at one and then changes dynamically as the
program progresses. The step size also changes dynamically as the integration
routine attempts to take the largest possible step consistent with the allowed
error bounds.
For more information on mechanization of the variable step, variable order
integration routines, see subroutine DIFSUB in Numerical Initial Value in
Ordinary Differential Equations, C.W. Gear, Prentice-Hall, NJ 1971 pp 150 et seq
4.5.6
Adams-Moulton
Description:
Adams-Moulton is useful for models in which the step size changes significantly
during a simulation, as for a satellite in a highly eccentric orbit. In this case, a
much larger step size can be used when the satellite is far from the earth than
when it is near. This algorithm can also help determine an appropriate step size
for fixed step runs, as described below.
Language Reference Manual
37
4.5.7
Gear's stiff
Description:
Gear's algorithm is for stiff systems that have frequencies of three or four orders
of magnitude difference, where the high frequency motions are extremely active
at some point (such as in a chemical reaction, explosion, etc.) and then smooth
to essentially zero amplitude. The Gear's stiff algorithm is then able to take large
time steps since only the low frequency motions are of interest.
Gear's stiff integration can take steps that are orders of magnitude larger than the
smallest time constant in a stiff system. There is an overhead involved, however,
since a linearized state transition matrix must be formed and inverted. Tests have
shown that for problems where the range of time constants differs by only one or
two decades, there is little benefit in using this method; Adams-Moulton is
invariably faster. If the range of time constants covers more than three or four
decades, then this technique may be significantly faster than any other.
4.5.8
Runge-Kutta-Fehlberg
Description:
The Runge-Kutta-Fehlberg algorithms (IALG = 8, 9) are fixed order but variable
step. They are useful for models with a number of discontinuities, such as a
system in which a spring is encountered periodically. The Adams-Moulton
method uses information from previous steps to determine the size of the current
step, but the Runge-Kutta-Fehlberg method starts fresh each step, thus having
less difficulty with discontinuities. These routines adjust the step length to keep
the error per step less than that specified by XERROR and MERROR. The
relative error (MERROR) values are applied to the largest absolute value of the
state so far, not the current value.
Algorithm 8 evaluates the derivative three times per step and makes a second
order state advance; algorithm 9 evaluates the derivative six times and makes a
fifth order state advance. If any error in a state is larger than that allowed, the
step size is reduced (by no more than 0.1 at a time) until the error criteria are
satisfied for all states or the minimum step size (MINT) is reached. After a
successful step, the new step size is set to be 0.8 (for IALG = 8) or 0.9 (for IALG
= 9) of a step size which would result in the maximum allowable error (as
calculated during the previous step), except that the new step size is not less
than the previous successful one.
The lower order algorithm (IALG = 8) is recommended for most applications
because it usually uses less computer time.
Language Reference Manual
38
4.5.9
ODEPACK and CVODE
Description:
These integrators are based on the popular stiff-system ODE solver packages of
the same names. They are particularly suited to systems which exhibit a sparse
Jacobian; for such systems, these solvers may yield a significant performance
improvement over the Gear algorithm.
For the CVODE algorithm, the sparsity structure of the Jacobian may be
specified using the UBWITG and LBWITG system variables; these are used to
set the upper and lower Jacobian bandwidths, respectively.
By default, ODEPACK automatically determines the sparsity structure of the
system.
4.5.10
MINT with variable step algorithms
Description:
The variable step algorithms never take steps smaller than MINTERVAL (MINT).
The integration step size for variable step algorithms is calculated as for the fixed
step algorithms with the addition of a check on the minimum step size as follows:
H = MAX(MINT, MIN(MAXT, CINT/NSTP))
4.5.11
NSTP with variable step algorithms
Description:
NSTP can be set to help a variable step algorithm start off. If the first try
(CINT/NSTP) is too large (i.e., if the estimated error is larger than the allowed
error), the algorithm reduces the step size and tries again, until it finds a small
enough step size to start off. Setting NSTP to a fairly large number (1000, for
example) starts the routine at small step size, which is then increased
automatically as the run progresses until it reaches the most efficient size.
Beware of leaving NSTP at a large value and switching to a fixed step algorithm.
4.5.12
Error summary
Description:
An error summary is produced automatically at the end of simulation runs using
variable step algorithms, giving the weight each state had in controlling step size.
The error criteria (XERROR and MERROR) can be adjusted using this
information. The number of times the predictor-corrector algorithm failed to
converge and caused a general step size reduction is also listed. This is usually
considered a more serious failure than bumping into the allowable error
tolerance. The summary may be suppressed by setting the system variable
Language Reference Manual
39
WESITG (write error summary, integration control) to FALSE. Current step size
(CSSITG) and current integration order (CIOITG) are available as system
variables that can be output or prepare.
4.5.13
Determining appropriate step size
Description:
Determining an appropriate step size for a fixed step algorithm is important. If a
step size is too large, the results are inaccurate or even catastrophic; if too small,
computer time is wasted.
One approach is to use a variable step algorithm to see what acslX believes to
be appropriate. Use the Adams-Moulton routine and the system variables for
current step size and current integration order as follows:
IALG=1
prepare T CSSITG CIOITG ...
start
plot(_t,_cssitg)
Check that the step size is not being constrained by CINT. If it is, increase CINT
and MAXT and run the simulation again. Look at the shape of CSSITG. If it is
steady, use a fixed step size just slightly larger than the values chosen by the
variable algorithm (the system choice of step size is somewhat conservative, so
a slightly larger step is usually adequate). If the curve varies widely, however,
consider using one of the variable algorithms. The system choice of CIOITG
should also be steady and can be factored into the choice of algorithm order and
step size.
4.5.14
Efficiency and accuracy
Description:
The efficiency of the various algorithms can be compared with the tic and toc
analysis commands.
Example:
IALG = 4
tic;start @NoCallback;toc
IALG = 5
tic;start @NoCallback;toc
Each toc command lists the cpu time elapsed since the previous tic command.
Compare the accuracy of the results by printing (or plotting) significant variables
or by getting debug dumps.
Language Reference Manual
40
4.6 ANINT
Form:
y = ANINT(x)
Description:
The output y is the nearest whole number of x where x is a floating point variable
or expression. The output type (REAL or DOUBLEPRECISION) depends on the
input type.
Since NINT is promoted to REAL or DOUBLE as appropriate in any expression,
the only situation where it is necessary to use ANINT( ) is in the argument to a
subroutine to force the type.
Example:
If the first argument of MYSUB is floating point, the following ensures the nearest
whole number (integer) value, but transmitted as a floating point number:
CALL mysub(ANINT(v1), ...)
4.7 ASIN
Form:
y = ASIN(x)
Description:
The output y is the arc sine of x, where x is a floating point variable or expression
between -1.0 and +1.0. The output is in radians (-p § 2 <= y <= + p§ 2 ); its type
(REAL or DOUBLEPRECISION) depends on the type of the argument.
Example:
ASIN could be used as follows:
area = 0.5*pi*r**2 - x*SQRT(r**2 - x**2) +
(r**2)*ASIN(x/r))
4.8 Assignment statements
4.8.1
Arithmetic
Form:
variable = expression
Language Reference Manual
41
Description:
Where variable may be simple or subscripted. If a subscripted variable is used in
a sorted section, it must be enclosed in a PROCEDURAL block. On execution,
the single value of the expression is stored into the location defined by variable;
for example, the results of the expression on the right side of the following
statement is stored into location y:
y = a*b + c/d
A special form of the assignment statement is the integration statement. The use
of the INTEG operator marks the variable as a state variable.
Example:
In this example, a is marked as a state variable and ad is stored as the derivative
of A.
a = INTEG(ad, aic)
Type conversion is performed automatically from an integer, real, or double
precision expression to an integer, real, or double precision variable.
4.8.2
Logical
Form:
lvariable
= lexpression
Description:
where lvariable may be simple or subscripted and lexpression is a logical
expression formed from a logical operator.
Example:
flag = a .NE. b .OR. flag2
4.8.3
Character
Form:
cvariable
= cexpression
Description:
where cvariable is a character variable or substring and cexpression is a
character expression.
Example:
cvar(5:10) = string(1:4)//'Z'
Language Reference Manual
42
concatenates a Z to four characters extracted from STRING and places them in
character positions 5 through 9. Unfilled character positions in cvariable are filled
with blanks. If the length of cexpression exceeds that for cvariable, the character
expression is truncated on the right.
4.9 ATAN
Form:
y = ATAN(x)
Description:
The output y is the arc tangent of the floating point argument x where x is
unlimited except for infinity and the result is in radians in the range (-p § 2 < y <
+p§ 2 ).
Example:
al = ATAN(-vmm(3)/vmm(1))
For full coverage of the circle, it is better to use ATAN2.
4.10 ATAN2
Form:
z = ATAN2(y, x)
Description:
The output z is the arc tangent of an angle formed by the point with floating point
coordinates x, y and the positive x-axis; x and y can be both positive and
negative, defining the full circle of revolution. The result is in radians in the range
(-p < z <= + p ).
Example:
pdgn = ATAN2(dlq, dlp + 1.0E-30)
4.11 BCKLSH
Form:
y = BCKLSH(ic, dl, x)
BCKLSH(y = ic, dl, x)
Description:
ic =
dl =
Language Reference Manual
initial condition of y
half the width of the backlash
43
x =
input (a floating point variable or
expression)
The output always lies between the limits (x - dl) and (x + dl). Figure 4-6
illustrates the backlash mechanism.
Figure 4-6: Mechanism Illustrating BCKLSH Operator
For asymmetrical applications, the input x expression should be rewritten. For
example, if y is to move when x is greater than (Y+UL) or less than (Y-LL), then:
y = BCKLSH(yic, 0.5*(ul - ll), x - 0.5*(ul + ll))
NOTE: The BCKLSH operator must be in a sorted (DERIVATIVE) section.
4.12 BOUND
Form:
y = BOUND(bb, tb, x)
Dscription:
bb
= bottom bound
tb
= top bound
x = input (a floating point variable or expression)
The output y is as follows:
y
y
y
= bb when
= x when
= tb when
x < bb
bb < x < tb
x > tb
This function bounds or limits variables. It should not be used to limit the output
of an integrator since the integrator itself continues to wind up and must actually
integrate out of the limit. The function LIMINT should be used in this case.
Example:
MAXT = BOUND(maxtmn, maxtmx, maxtp)
Language Reference Manual
44
4.13 CALL
Form:
CALL name
CALL name (p1, p2, ..., pn)
CALL name (o1, o2, ..., on = p1, p2, ..., pn)
Description:
Where name is the name of a subroutine being called, pi are actual arguments
that may be expressions of arbitrary complexity for input values, and oi are
output variables (names or arrays). Arguments may be variables, arrays, or
subscripted variables.
In the third form, the translator cannot tell which arguments are inputs and which
are outputs. If the call is in a sortable section of the program, it should be
embedded in a PROCEDURAL block that describes the inputs and outputs. If the
call is any other section, a PROCEDURAL is recommended to avoid the "Symbol
used but not defined" diagnostic.
Example:
If oi are output variables and pi are input variables or expressions, then the
following statements are valid:
PROCEDURAL (o1, o2, o3 = p1, p2, p3, p4)
CALL subr(o1, p1, p2, p3, p4, o3, o2)
END
Now the translator sorts this section correctly since it has been told which
variables are inputs and which are outputs.
The third form of the call is available for the case in which the subroutine is
defined with the input expressions on the left and the output variables on the
right. In this form, the subroutine could be called with:
CALL subr(o1, o2, o3 = p1, p2, p3)
The translator rearranges the order and changes the equal sign to a comma so
that the resulting call to FORTRAN is:
CALL subr(p1, p2, p3, o1, o2, o3)
4.14 CHARACTER
See TYPE.
4.15 CINTERVAL
Form:
CINTERVAL name = real constant
Language Reference Manual
45
Default:
name: CINT
real constant: 0.1
Description:
Where name is a simple unsubscripted variable.
The communication interval CINTERVAL is the interval at which the DYNAMIC
section is executed and the variables on the output and prepare lists have their
values recorded. In general, no finer detail can be seen in output, print, or plot, so
it is important to choose this value with care. A communication interval that
generates about 100 to 200 data points during a run is sufficient detail for most
applications.
Sampling effect
Be careful of the sampling effect where high frequency oscillations can be folded
down to lower frequencies or even a DC level if the sampling time is not small
enough.
4.15.1
Adjusting step size to CINT
If the next integration step to a communication interval is less than 1.0E-11
(1.0E-6 in single precision) of the current time (or CINT, whichever is larger), the
step is discarded as negligible. This situation can occur because of accumulation
and rounding on a binary machine. The integration algorithm takes steps up to
the next communication interval by accumulating the fixed step (for example, with
MAXT = 0.01and CINT = 0.1; after ten steps, the time is about 0.1 because of
rounding in both 0.01 and 0.1). To prevent accumulated round-off error, a small
adjustment is made to the communication interval. CINT is multiplied by a power
of ten until it is close to an integer, then time is accumulated as an integer but
divided by the multiplier before being used.
4.15.2
Calculating CINT
The value of the name defined in the CINTERVAL statement can be calculated in
the program so that different phases can be viewed at different data rates. For
example, assume that a missile simulation has the following four phases of flight:
1)
2)
3)
4)
Initial turn
Midcourse
Acquisition
Terminal
It is useful to measure these phases at different rates; e.g., initial turn at a fairly
fine level of 0.1 second, the long midcourse only every second, and acquisition
and terminal at a fine rate of 50 msec. Figure 4-7 outlines a procedure for setting
the communication interval for each phase. In the INITIAL section, PHASE is
declared to be an integer and initialized to one. An array CINTTAB is defined and
Language Reference Manual
46
filled with the communication intervals to match the phases of flight as numbered
above. In the DYNAMIC section, the communication interval (using default name
CINT) is set using the current value of the flight PHASE (which ranges from one
to four). In the DERIVATIVE section, the value of PHASE is computed from the
logic used to establish the different flight regions. This code is shown as a block
since the algorithm depends on the implementation of the model; but no matter
how it is implemented, the value of PHASE is maintained in the range one to
four.
INITIAL
INTEGER phase
DIMENSION cinttab(4)
CONSTANT cinttab = 0.1, 1.0, 0.05, 0.05
phase = 1 ! Initialize phase to start
...
END ! of initial
DYNAMIC
DERIVATIVE
! Compute phase of flight
PROCEDURAL(phase = , , ... )
...
END ! of procedural
...
END ! of derivative
CINT = cinttab(phase)
...
END ! of dynamic
Figure 4-7: Outline of program to vary communication interval
4.15.3
Changing default name
The name of the variable defining the communication interval can be changed
from the default CINT;
Example:
CINTERVAL CI = 0.001
Now all references are to CI when the value is recorded or changed.
Language Reference Manual
47
4.15.4
Bound on integration step
CINTERVAL acts as an upper bound on the integration step size (and also for
the last integration step of a communication interval) since the model is
advanced no further than to the data recording time no matter how large the
calculated integration step size. This subject is discussed in more depth under
DYNAMIC. The actual integration step is obtained from the following algorithm:
H = MIN(MAXT, CINT/NSTP)
H = MIN(H, time_to_next_event)
This applies a bound of MAXT to CINT/NSTP and then limits the step to be no
more than the time left in the current communication interval or to the next other
event.
4.16 CMPXPL
Form:
y = CMPXPL(p, q, x, ic1, ic2)
CMPXPL(y = p, q, x, ic1, ic2)
Description:
This operator, listed in Figure 4-8, implements a second order transfer function
where the output y is related to input x through the transfer function:
such that:
Language Reference Manual
48
MACRO cmpxpl(y,p,q,x,ic1,ic2)
MACRO STANDVAL ic1=0.0,ic2=0.0
MACRO REDEFINE ydot
ydot = INTEG(((x)-(y)-(q)*ydot)/(p), ic1)
y = INTEG(ydot, ic2)
MACROEND
Figure 4-8: Macro for 2nd order transfer function
Restrictions
The same restrictions on initial conditions apply as for the INTEG operator, and
both ICs may be omitted if zero. The time constants p and q may be expressions
of arbitrary complexity. However, do not set p to zero because it results in
division by zero, as can be seen in Figure 4-8.
NOTE: This operator (as all the memory operators) should be used only in sorted
sections and should not be used in a PROCEDURAL block. The CMPXPL
operator could be used as follows:
x = k2*CMPXPL(a, b, xp)
4.17 Comment (!)
Form:
!string
Description:
A comment is all text after an exclamation point to the end of the line. The text is
reproduced in the listing and then discarded.
Example:
! ------------ Calculate the derivative
x
= a + b
! Add `a' and `b' and place in `x'
a
= sin(w*t) ! Forcing function acceleration
Language Reference Manual
49
Comments can be added after continuations (& at end of code) because
comments are stripped off before the translator analyzes the rest of the line.
cm = cmz + cmal*al & ! pitch moment coefficient
+ cmde*dle + (cb/(2*v))*(cmad*ald +
cmtd*q)
4.18 CONSTANT
Form:
CONSTANT d1 = a1, d2 = k*a2, d3 = a31, a32, k*a33
Description:
di = identifiers representing simple variables or array names. Implied DO loop
notation may not be used. If di is an array name, integer subscripts may be used
to fill individual elements within the array, or else the entire array must be filled.
ai = literals and signed or unsigned constants or PARAMETER names.
k = integer constant or integer PARAMETER name repetition factors; the literal
following the asterisk is repeated k times.
The CONSTANT statement is used to preset symbolic locations with numeric
data. Since it is not an executable statement, it can be placed anywhere in the
program. The recommended placement is just before the statement using the
CONSTANT value.
Examples
Examples of the correct use of the CONSTANT statement include:
LOGICAL switch1
INTEGER ii
DIMENSION a(2)
CONSTANT switch1=.TRUE., ii=2, a=2*1.0, b=-5.76
CONSTANT vs. assignment statement
The CONSTANT statement effect is quite different from that of an assignment
statement. The assignment statement moves data from one place to another
(into the location for the variable to left of the equal sign) every time control
passes through the statement. The CONSTANT statement, on the other hand,
just presets the variable to the left of the equal sign when the simulation is loaded
into memory. The variable can then be overridden by assignment statements or
at runtime.
Assignment statements for constants, such as the following, should be avoided:
INITIAL
k1 = 5.70
k2 = 7.63
Language Reference Manual
50
END
Although these values can be changed at runtime at the command prompt, they
are returned to the original value as soon as the assignment statements are
executed. This precludes doing runs with different values of the parameters.
Replace the code above with a CONSTANT statement as follows:
CONSTANT k1 = 5.70, k2 = 7.63
Now the values of k1 and k2 can be changed at runtime and remain that value
until changed again from the command prompt.
> K1 = 6.0
> K2 = 8.0
Initializing counters
CONSTANT statements should not be used to initialize counters. For example,
counters are often initialized in the INITIAL section and then incremented later:
INITIAL
INTEGER n
n = 0
END
DYNAMIC
n = n + 1
...
If the counter were initialized using a CONSTANT statement, the results would
be correct for the first run, but any subsequent runs would start with the value left
over at the end of the previous run.
Warning message
When a variable is given a value in a CONSTANT statement and later appears
on the left side of an equal sign, the translators issues a warning message:
Warning: Re-computing a constant.
The warning does not abort translation. Warning messages can be suppressed
with a switch on the call to acslX.
4.19 Continuation (&)
Form:
statement &
[&]continuation
Description:
Any model source code (or runtime) statement can be continued onto another
line by ending the first line with an ampersand (&). Any number of continuation
lines is allowed (although the resulting Fortran code may be limited to twenty
Language Reference Manual
51
packed lines) and the ampersand may appear in any column up to 72. The
translator removes blanks between the end of the code and the ampersand on
the first line but carries blanks at the beginning of the continuation line onto the
compile file.
cm
= cmal*al + (cmq*wm(2)
&
+ cmbep*be*wm(1))*d/(2.0*vmam(1))
If the continuation line begins with an ampersand, then blanks at the beginning of
the line are dropped; this allows name and character strings to be continued
without starting the continuation line in column one.
charactervariable = `longcharact&
&erstring'
In other words, blanks between the two ampersands are eliminated.
Blank lines
Because the syntax analyzer looks for the leading ampersand in continuations, a
blank line results in a syntax error. To introduce blank lines in continuations, use
two ampersands; for example:
TABLE
xyz, 1, 10
&
/-10.0 , 0.0
, 150.0 , 180.0
&
, 8.33 , 8.33
, 5.2
, 6.6
&
&
, 30.0 , 60.0 , 120.0 &
, 210.0 , 240.0 , 270.0 &
&
, 4.0
, 1.6
, 5.2
&
, 8.3
, 10.7 , 16.7 /
Comments
Comments can be added to a continued line as follows:
x
= a + b
& ! Comment on the sum
+ SIN(a/b)*m ! Explanation of sine function
The translator strips comments off before looking back from the end of the line
for an ampersand.
4.20 CONTINUE
Form:
label: CONTINUE
Description:
CONTINUE is normally used to transfer control after a GO TO command or to
terminate a DO loop. It is the preferred statement for all labels due to problems
with macro expansions as explained in Chapter 2. Note that code using
Language Reference Manual
52
CONTINUEs and labels generally requires the use of PROCEDURALs in sorted
sections.
4.21 COS
Form:
y = COS(x)
Description:
The output y is the cosine of x where x is a floating point variable or expression in
radians. The result is in the range (-1.0 <= y <= + 1.0 ). The type (REAL or
DOUBLEPRECISION) of the output and function depends on the type of the
argument.
Example:
simd = (wm(2)*COS(fim) - wm(3)*SIN(fim))/COS(thm)
4.22 DBLE
Form:
DBLE(x)
Description:
This function converts an integer, single precision, or double precision argument
x to double precision.
The main use of DBLE is to force the precision of arguments to subroutines
where the precision of the argument cannot be deduced by the compiler. If a
subroutine requires a double precision argument, then the type can be forced in
the form.
Example:
CALL mysubr(DBLE(x1), DBLE(x2), ... )
NOTE: See Type Reference
4.23 DBLINT
Form:
DBLINT(x, xd = xic, xdd, xdic, bb, tb)
Description:
x =
xd =
Language Reference Manual
displacement
velocity ()
53
xic =
x(0); i.e., initial condition of x
xdd =
)
the input, acceleration (
xdic =
.
bb =
tb =
x(0); i.e., initial condition of
bottom bound
top bound
macro dblint(x,v,xic,a,vic,lbx,ubx)
macro redefine vl,ic
constant ic=0.0
callzzdlim(v,vl=ic,x,integ(zzlimf(x,a,lbx,ubx),vic),lbx,ubx)
x=intvc(v,xic)
macroend
Example:
Figure 4-9: DBLINT operator macro
The DBLINT (double limited integration) operator, shown in Figure 4-9, is for
integrator limiting when the limited output is the second integral of an
acceleration.
Language Reference Manual
54
Figure 4-9: Alternate implementation for DBILINT
Mass-spring damper system
This type of limiting can best be explained in terms of the mass-spring-damper
system described by:
such that:
where physical stops constrain the mass to move only between xbb (bottom
bound) and xtb (top bound); i.e.,
xbb < x < xtb
When the displacement (x) of the mass reaches its limit, the mass must stop,
implying that the velocity ( ) is zero. The mass must remain stopped until the
force acting on it (f (t) - cx) changes sign.
Alternate implementation
An alternate way of performing this operation is to wrap a stiff spring around the
loop when the wall is approached; this corresponds to what happens physically
since the wall always has a finite spring constant. Figure 4-9 is a block diagram
of such a system where Ks is spring stiffness, Kw wall stiffness, and Kd the
Language Reference Manual
55
damping constant. The problem with this representation is in the behavior of the
digital integration routine in the vicinity of the wall when the wall stiffness is
extremely high. A more accurate but more complex approach is to use the
SCHEDULE operator to find times of both wall impact and wall leaving (when the
force changes sign or crosses zero).
NOTE: This operator (as all memory operators) can be used only in
DERIVATIVE sections and should not be put in a PROCEDURAL block.
4.24 DEAD
Form:
y = DEAD(bb, tb, x)
Description:
The DEAD operator implements a dead zone in output y when x lies between a
specified bottom bound bb and top bound tb. The results can be represented as
follows:
y = x - bb ; x < bb
y = 0.0 ; bb < x < tb
y = x - tb ; x > tb
Example:
The dead zone operator could be used as follows:
v2 = v1 + k*DEAD(vmn, vmx, v3)
4.25 DELAY
Form:
y = DELAY(x, ic, tdl, nmx, delmin)
DELAY(y = x, ic, tdl, nmx, delmin)
Description:
x = the input (an arithmetic expression of arbitrary complexity).
ic = the initial value of the output until the independent variable has advanced by
the delay, tdl. This argument must be a variable name (rather than a literal
constant) for the runtime command REINIT to work. REINIT needs a name into
which to store the current DELAY output as the initial condition for subsequent
runs.
tdl = the delay time between input and output (any expression with a value 0.0).
Language Reference Manual
56
nmx = a literal integer giving the maximum number of saved data points needed
to represent the delay. The integration step size may vary but the sum of nmx
integration steps must always be greater than the current time delay.
NOTE: This integer must be a literal integer or a parameter name with an integer
value. For example:
co = DELAY(ci, cic, cdl, 1000, cmn)
Using a PARAMETER variable:
INTEGER cmx
PARAMETER(cmx=1000)
co = DELAY(ci, cic, cdl, cmx, cmn)
This integer nmx allocates space in a circular buffer to hold the history data of
previous sample times and previous input values. If delmin is defined, then nmx
should be somewhat larger than the maximum delay times expected (tdl) divided
by this delmin (or by the integration step if it is larger).
delmin= minimum interval between saving of data points in delay buffer. This
argument may be omitted, in which case a default of zero is used. Typically
delmin can be a tenth or a hundredth of the expected delay time and still
represent dynamics adequately.
The DELAY operator delays a variable in time to model transport effects such as
passage through a pipe. It should not be used lightly since it may require
considerable storage unless delmin is specified.
Implementation
The DELAY operator is implemented by allocating a dummy array, 2*nmx words
long, and prefilling it with the value of ic, extending over all past history. Each
entry in the table is associated with a time, and at each new integration step (or
delmin, whichever is larger) a new value is inserted into the array, treating it as a
circular list. To compute the output value, tdl (the current time delay) is
subtracted from the independent variable value and the table is searched for time
values that bracket this required previous time. A linear interpolation is performed
between the corresponding input values. If not enough data points are present,
an error is reported and the run terminates.
Varying time delay
When tdl changes dynamically, this operator approximates the pipeline with a
varying flow rate.
Direct feedback not allowed
The operator provides an algebraic path from input to output, so direct feedback
(without an integrator) is illegal; the following for example is not allowed:
y = DELAY((n - y)/k, yic, tdl, 1000, 0.1)
Language Reference Manual
57
If direct feedback is really necessary, the output of the DELAY can be filtered
through a real pole to break the loop. This is a good idea anyway since it
eliminates jumps in the slope of the DELAY output produced by the straight line
interpolation. For example:
y = REALPL(tfilt, DELAY((in - y)/k, yic, tdl, 1000,
0.1))
In this situation, TFILT is chosen to be small relative to the delay time (tdl).
4.26 DELSC
Form:
state = DELSC(xn, ic)
DELSC(state = xn, ic)
Description:
state = a simple variable (DELVC handles vectors)
xn = an arithmetic expression of arbitrary complexity; i.e., may contain further
DELSC statements or other functions or macros.
ic = a simple non-subscripted variable, a real constant, or a general expression
enclosed in parentheses.
DELSC produces a one-step delay between the calculation of the xn value and
its assignment to the state so that it shows up in the variable at the beginning of
the next step.
DELSC may be embedded in any legal expression as a function that has a single
output: the value of the state. When the delay statement is alone, then the state
name can be identified; embedding it in an expression means that an acslXgenerated variable (i.e., in the form Znnnnn) is used for the state name.
NOTE: The DELSC statement can be placed only in a DISCRETE section, not a
DERIVATIVE section.
With initial conditions
Since DISCRETE sections are not in general sorted, if an expression is used for
the initial condition, then the DELSC expression must be placed before any
reference to the state and after the calculation of the next value, so that this form
is normally to be avoided. The implementation of the expression form involves
the following expression:
if(zzicfl) state = ic
so it is only after the expression is seen that the states has a value the first time.
Language Reference Manual
58
In the more general case, the initial condition variable is equivalenced into the
initial condition table and the values for all the states are moved at once before
any DERIVATIVE or DISCRETE section code is executed at all.
Placement
In unsorted DISCRETE blocks, DELSC must be placed after the calculation of its
inputs.
See the description of the INTEG statement for a general description of the way
the acslX system build tables of states, derivatives, and initial conditions. DELSC
places the state in the state table, the next state in the derivative table, and the
initial condition value in the initial condition table. The integration algorithm knows
to update the delay state variables by:
xn+1 = xn
whereas the continuous states are updated by:
xn+1 = xn + h*xd(effective)n
Examples of the use of the DELSC statement include:
y = DELSC(5.0*(x(2) + c), yz)
x = 4.0*DELSC(4*y, 0)
z = DELSC(znext, zic)
4.27 DELVC
Form:
x = DELVC(xn, xic)
DELVC(x = xn, xic)
Description:
Where X, XN, and XIC are arrays of the same size and correspond to state,
derivative, and initial conditions, respectively.
The restrictions on the DELSC operator with regard to arrays can be avoided by
using this vector integrator operator. The restrictions on the DELVC operator are
identical to those on the INTVC operator with the additional one that the DELVC
statements can appear only inside DISCRETE blocks.
In unsorted DISCRETE blocks, DELVC must be placed after the calculation of its
inputs.
Example:
DIMENSION x(1), xic(10), m(5,5), mn(5,5), mic(5,5)
y = DELVC(yn, yic) ! scalar delay
x = DELVC(xn, xic) ! vector delay
m = DELVC(mn, mic) ! matrix delay
Language Reference Manual
59
4.28 DERIVATIVE
Form:
DERIVATIVE [name]
...
END
Description:
The DERIVATIVE keyword identifies the beginning of a block of code performed
at the request of the integration routine to evaluate the state variable derivatives.
The DERIVATIVE statement must be paired with a matching END statement.
Implementation
The integration routine is called from the DYNAMIC section and asked to
advance the state over the next communication interval using the code
embedded in the DERIVATIVE blocks to evaluate the state variable derivatives;
i.e., the integration algorithm calls the DERIVATIVE section. The actual number
of evaluations depends on the integration algorithm employed.
Transfers illegal
All the statements in the DERIVATIVE section are translated into a separate
subroutine, so it is illegal to transfer control by GO TO's from DERIVATIVE
sections to other sections (INITIAL, DYNAMIC, DISCRETE, or TERMINAL) or
vice versa.
Barriers at CINT, DISCRETE, or SCHEDULE
The only break in the regular progression is at a communication interval or at an
equivalent barrier represented by a DISCRETE section or a SCHEDULE event.
The times for all DISCRETE, SCHEDULE, and communication actions are
entered onto the event list where all actions are ordered in time; the next time on
the event list is called the barrier time.
For the DERIVATIVE block, the current step size is checked against the current
time (T) and the barrier time from the next event list. If integration with the current
step size would exceed the barrier time, the actual step is reduced so that the
last step is made exactly up to the event. All states then line up in time for the
event to take place.
CINT as integer multiple of step size
Integration step sizes and communication intervals are usually chosen to be
integer multiples of each other. The acslX system does not require this. For
example, it is acceptable to choose a fixed step length for the continuous section
of 4 msec, a sampling INTERVAL in the DISCRETE block of 11 msec, and a
Language Reference Manual
60
communication interval of 20 msec. The first few integration step sizes would
then be (in msec):
4, 4, 3, 4, 4, 1, 2, 4, 4, 3, 4, 3, 4, ...
The first short step of 3 msec brings time up to 11 msec, the first barrier time,
which is due to the DISCRETE section. Then two more normal steps are followed
by a short step of 1 msec to bring time up to the communication time of 20 msec.
The next barrier is the DISCRETE block at 22 msec causing a step size of 2
msec, and so on. Variable step algorithms look ahead to the next barrier to
compute a constant step size which reaches the barrier without requiring a final
short step.
4.29 DERIVT
Form:
y = DERIVT(ic, x)
DERIVT(y = ic, x)
Description:
ic = y(0)
x = the input (an arithmetic expression)
The derivative function differentiates x and can be implemented if absolutely
necessary.
NOTE: It is never necessary to invoke a derivative. The derivative can be
expressed instead in terms of all the other states in the system.
Since the derivative operator is a first order approximation, it can lead to
instability if it is used to represent any major loop. The only time this may be
justified is for a minor term where a large amount of extra calculation may be
needed to reform the problem in terms of the states.
PID example
As an example of how DERIVT can be avoided, consider the D term in a PID
(proportional, integral, derivative) controller. There is a tendency to use DERIVT
for this term, but in hardware, it is always implemented by a differentiation over a
first order lag; i.e.,
This formulation can be represented by a single line of acslX code:
y = (k*x - INTEG(y, ic))/t1
Nature never has a free differentiator; it is always combined with a lag to make it
realizable.
Language Reference Manual
61
Jabobian
Sorting
Initial
Condition
The use of DERIVT invalidates the Jacobian calculation from the
ANALYZE command, including all the derived data (zeros, root
locus, and frequency response plots). This is another good reason
not to use DERIVT.
The DERIVT operator (as all memory operators) should be used only
in sorted sections and should not be put in a PROCEDURAL block.
Use a variable name rather than a literal constant for the initial
condition so that REINIT has a place to store it; otherwise REINIT
tries to overwrite the global zero with the one in the common block.
Example
An example of a DERIVT statement could be:
ald = DERIVT(alic, al)
4.30 DIM
Form:
y = DIM(x1, x2)
Description:
The output y is the positive difference between x1 and x2 where x1 and x2 can
be variables or expressions. DIM takes its type and types its output based on the
type of the arguments. The result can be represented as follows:
y = x1 - x2
y = 0.0
;
;
x1 > x2
otherwise
The following logic is often used:
PROCEDURAL(x = y,z)
x = y - z
IF(x .LT. 0.0) x = 0.0
END
a = SQRT(x)
One line using DIM can solve the same problem:
a = SQRT(DIM(y, z))
DIM is useful for representing cable spring stiffness. Negative extension cancels
zero force with a cable.
4.31 DIMENSION
Form:
DIMENSION v1(a...), v2(a...), ..., vn(a...)
Language Reference Manual
62
Description:
The variable names vi may have up to six integer constant subscripts separated
by commas; e.g., SPACE(5,5,5,5,5,5). The subscripts may be symbolic if the
symbols are declared INTEGER and defined in a PARAMETER statement. This
operator allocates space for up to six dimensions to be associated with a variable
name. The statement can appear anywhere in the program, but it must appear
before any invocation of a macro that uses dimension information.
Type declaration
Arrays can also be dimensioned using the REAL, DOUBLEPRECISION, or
INTEGER statements. DIMENSION is preferred for floating point variables
unless the type of precision needs to be forced. Using DIMENSION allows the
type to adjust depending on the global option (single or double precision)
selected.
NOTE: Names of certain acslX macros should not be used as arrays. acslX
cannot check that the name defined as an array is also a macro because the
TABLE statement defines an array to hold data and a macro of the same name
for table lookup. The names of the following acslX operators should not be used
for arrays (as scalars is not a problem):
Array order
Elements of arrays are written and accessed by column, then row; i.e., (a(i,j)
where i = row, j = column). For example, the elements of b(2,5) can be shown:
11 12 13 14 15
21 22 23 24 25
Extracted as a single-dimensioned vector, the order is:
11 21 12 22 13 23 14 24 15 25
Examples
An example of a DIMENSION statement is:
Language Reference Manual
63
DIMENSION rm(3), em(3,3), hold(2,n), x(3,4,2,4,3,5)
4.32 DISCRETE
Form:
DISCRETE [name]
...
END
Description:
The keyword DISCRETE introduces a section to be executed by either an
INTERVAL statement or the SCHEDULE operator. The section is concluded by a
matching END statement.
DISCRETE sections are intended primarily for modeling digital sampled data
controllers where the communication to and from the continuous world occurs at
fixed times known in advance. Another common application is changing state or
other variables when a state event occurs (in which case execution of the
DISCRETE section is handled by a SCHEDULE statement).
Sorting
The translator does not automatically sort the code. Use the SORT keyword to
have code within a DISCRETE section sorted. Code is never sorted across
sections, nor are the sections themselves sorted.
Explicit structure level
DISCRETE sections are at the same level as any DERIVATIVE sections. If a
DYNAMIC section is used, DISCRETE sections are placed inside it. (See
Chapter 3 for further information on explicit program structure.)
Executed at discrete event
DISCRETE sections are executed at a discrete event or time point. The time of
the execution is controlled by the keyword INTERVAL or by a SCHEDULE
statement. Like the DERIVATIVE section, each DISCRETE section has a time
associated with it that is entered into an event list. This time becomes a barrier
for DERIVATIVE sections, ensuring that the integration routine takes a final step
(which may be short) up to the barrier time before the code in the DISCRETE
section is executed. If execution is controlled by an INTERVAL statement, the
section is re-entered on the event list with a time of execution equal to the current
time plus the current value of the INTERVAL variable.
Language Reference Manual
64
4.33 DO
Form:
DO n i = m1, m2[, m3]
...
n:CONTINUE
Description:
n = a label (numeric or symbolic) of the terminal statement of the loop.
i = a simple integer variable called the index variable. With each repetition, its
value is altered by the increment parameter m3. This variable may not be
changed within the loop.
m1 = initial parameter, the value of i during the first loop.
m2 = terminal parameter. When the value of i surpasses the value of m2, DO
execution is terminated and control goes to the statement immediately following
the terminal statement.
m3 = increment parameter, the amount i is increased with each repetition. The
default value of m3 is 1.
The m1, m2, and m3 may be integer constants, variables, or expressions of
arbitrary complexity; if variables, they must be declared explicitly to be INTEGER
variables. A DO statement makes it possible to repeat a group of statements a
designated number of times using an integer variable whose value is
progressively altered with each repetition. The initial value, final value, and rate
of increase of this integer variable are defined by the set of indexing parameters
included in the DO statement. The range of the repetition extends from the DO
statement to the terminal statement, which must follow the DO statement, and
this whole sequence is called the DO loop.
PROCEDURAL in sorted sections
This is the standard DO statement. Using a PROCEDURAL is not necessary
within INITIAL, DYNAMIC, DISCRETE, or TERMINAL sections.
Error checking
For more information on the structure of the DO statements, refer to the specific
language reference manual. The acslX translator checks the syntax of the DO
statement but does not validate the correct nesting of loops or terminal
statements. Errors of structure are indicated by the language compiler.
4.34 DOUBLE PRECISION
See TYPE.
Language Reference Manual
65
4.35 DYNAMIC
Form:
DYNAMIC
...
END
Description:
The DYNAMIC keyword identifies the beginning of a section of code that is
performed every CINTERVAL communication interval throughout the run. It must
be accompanied by a matching END statement.
The DYNAMIC section is the place to put output-related calculations so they can
be performed at the usually slower data recording rate rather than at each
derivative evaluation. Examples of calculations generally performed in this
section are unit conversions (such as radians to degrees), which do not affect
DERIVATIVE calculations. Most calculations that affect code in the DERIVATIVE
section should be in a separate DISCRETE section so model behavior is
independent of the data recording action; the DYNAMIC section is not intended
for computing variables to be input to DERIVATIVE or DISCRETE sections.
The time to the next communication interval can be calculated in the model,
based on some simulation phase or configuration, thus obtaining variable data
recording rates (see CINTERVAL for an example).
Code in the DYNAMIC block is not sorted automatically. Use the SORT keyword
to have it sorted.
4.36 END
Form:
END
Description:
An END statement denotes the end of a block (e.g., a PROCEDURAL block) or
section (DYNAMIC, DERIVATIVE, etc.). Chapter 3 shows the use of ENDs in
structuring an explicit program.
One of the most common errors in programming a model is not getting the right
number of ENDs to balance the program sections. The following error messages
are issued when the count is incorrect.
...Not enough ends
...Too many ends
The END statement acts like a right parenthesis in an arithmetic expression,
except that it terminates blocks of statements; an incorrect count corresponds to
unbalanced parentheses.
Language Reference Manual
66
4.37 ERRTAG
Form:
ERRTAG name
Description:
Where name is a simple unsubscripted variable. ERRTAG defines the system
variable name that is used to indicate an attempt to reduce the step size below
the minimum, MINT. This statement changes the name of the variable to a name
of your choice. The value of this name is set TRUE to indicate an attempt by a
variable step size integration algorithm to reduce the integration step size to
satisfy the error bounds. The type of name is automatically set to LOGICAL and
the value is preset to FALSE. The variable step integration routine calls the
derivative subroutine once with the name given under ERRTAG set to TRUE if it
needs to reduce the step size below the specified minimum MINT. If it is still
TRUE on return, the termination flag for that run is set. Control should then revert
to the TERMINAL section (if any) and the executive, and the next runtime
command is read. If provision is made to handle this case and reset the flag, then
care must be taken that a very small step size does not result in excessive
computer time being used.
4.38 EXP
Form:
y = EXP(x)
Description:
The output y is the exponential of the floating point argument x, where x is limited
in size such that the maximum machine word size should not be exceeded by the
exponential.
Example:
The expression is represented mathematically:
y = ex
4.39 FCNSW
Form:
y = FCNSW(p, x1, x2, x3)
Language Reference Manual
67
Description:
The output y of the function switch operator is determined by the input function p
as follows:
y = x1 p < 0.0
y = x2 p = 0.0
y = x3 p > 0.0
Note that zero almost never exists in the span of real numbers unless some other
action forces it there.
Example:
v = FCNSW(ain, vneg, vzer, vpos)
4.40 GAUSI, UNIFI
Form:
GAUSI(k)
UNIFI(k)
Description:
The output of these functions is the seed for the random number generator. Input
k is an integer constant or expression and should be a large, positive odd
number for a maximal length sequence. The macro for and GAUSI operator
macros is shown in Figure 4-10.
Figure 4-10: GAUSS and GAUSI operator macros
Only one of the initialization routines should be used since they both set the
same seed variable; either may be used with any other routine as they perform
exactly the same function.
Language Reference Manual
68
The random number generators are provided with a default seed initialization, so
these initialization routines are required only when you wish to override the
default. The default seed number is 55555555.
The GAUSI or UNIFI operator should be invoked only in the INITIAL section of an
explicit program, or provision must be made to skip over it except at the
beginning of each run in an implicit program. If the operator is executed
repeatedly, the random numbers do not change.
The seed need not be specified for each invocation of the random number
generators since subsets of random sequences are also uncorrelated random
sequences.
4.41 GAUSS
Form:
y = GAUSS(m, s)
GAUSS(y = m, s)
Description:
Where m is the mean and s is the standard deviation. The output y is a normally
distributed random variable. Figure 4-10 gives a listing of the operator macro.
Seed
The seed for a random sequence can be reset by UNIFI or GAUSI. If not set, a
different random sequence is in effect for each run.
NOTE: GAUSS is not intended for use in a DERIVATIVE section because the
power density (or, what is usually more important, the low frequency power)
depends on the integration step size. Instead, use the OU operator.
Example:
vmic = GAUSS(0.0, vmsg)
4.42 GO TO
Form:
GO TO label
GO TO (n1, n2, ..., nm), i
Description:
Where ni are statement labels that correspond to a possible label and i is a
simple integer variable that has been given a value between 1 and m. GO TO
statements transfer control to labeled statements whose references are fixed or
which are assigned during execution of the program.
Language Reference Manual
69
Transfers between sections
The statement labels used in the GO TO statements must be associated with
executable statements in the same program unit as the GO TO statement. In
explicit programs, the INITIAL, DYNAMIC, and TERMINAL sections exist in a
single program unit. However, control cannot be transferred into the DYNAMIC
region. The reason for this is that the integration routines must be initialized at
the start of the run; this initialization operation is done on leaving the INITIAL
section and entering the DYNAMIC section. Control can be transferred from the
DYNAMIC region to the INITIAL or TERMINAL section and between INITIAL and
TERMINAL sections.
DERIVATIVE DISCRETE
The DERIVATIVE section is a separate program block and control cannot be
transferred into or out of it. Control also cannot be transferred between
DISCRETE and DYNAMIC, INITIAL, or TERMINAL sections because DISCRETE
sections are in the same subroutine as the DERIVATIVE section.
Statement labels
A statement label may be either numeric or symbolic. Execution resumes at the
statement with the referenced label. We recommend using a CONTINUE as the
labeled statement to avoid possible problems with sorting.
Example:
Examples of valid GO TO statements include:
GO TO loop
GO TO (100, 200, 300, 400, 500), ibin
A large number of GO TOs is considered harmful to the successful completion of
any simulation project.
4.43 HARM
Form:
y = HARM(tz, w, p)
The output y is a sinusoidal or harmonic drive function with the results:
y = 0.0 T < tz
y = sin (w * (T - tz ) + p ) T
tz
Descrption:
tz = delay (sec)
w = frequency (rad/sec)
p = phase shift (rad)
Note that if p is nonzero, a discontinuity is involved.
Language Reference Manual
70
Example:
drive = HARM(tdrive, w1, phased)
4.44 HISTORY
Form:
HISTORY(y, yic, n)
Description:
y = a variable name that will be used to create an array.
yic = a scalar variable or expression of arbitrary complexity that is stored in the
first slot (y(1)) in the output array while the other elements in the array are
pushed down. Extracting past history is then just a reference to y(2) for two time
steps ago, y(3) for three time steps ago, etc.
n = must be an integer constant or integer parameter name (not a variable name)
that gives the number of history elements to keep track of. Since the output is a
vector, this statement cannot be invoked as an assignment statement; in general,
only scalar values can be passed across the equal sign.
Example
As an example, the following statement records four samples of a sine wave into
a history array:
HISTORY(sinhist, sin(2*w*t + fi), 4)
and then we can form a filter by extracting the history elements as equivalent
delay line taps:
filt = b0*sinhist(1) + b1*sinhist(2) +
b4*sinhist(4)
Placement
HISTORY can appear only in DISCRETE sections since it makes use of the
DELVC operator to delay the history elements. In unsorted DISCRETE sections,
HISTORY should be placed after the calculation of all its input variables. The
elements of the array are initialized to zero the first time.
4.45 IF, IF-THEN-ELSE
Form:
IF(lexpr) statement
IF(lexpr) THEN
block1
Language Reference Manual
71
ELSE IF(lexpr1) THEN
block2
ELSE
block3
END IF
Description:
IF statements are used to transfer control or perform calculations conditionally. At
the time of execution, an expression in the IF statement is evaluated and the
result determines whether the rest of the statement is executed.
The logical expression lexpr is a logical or relational expression, one that
produces a single value (either TRUE or FALSE).
Logical IF
Description:
In the logical IF form, statement is any executable statement. Only a single
statement can be included in the logical IF statement.
Examples:
IF(a .LT. 5.0) a = a + 0.1
PROCEDURAL(x = )
IF(x .GT. xmax) GO TO finish
x = k*xprev
xprev = x
finish: CONTINUE
END
Logical IF statements that transfer control in sections that are sorted by acslX
(DERIVATIVE sections or implicit programs) must be enclosed in PROCEDURAL
blocks, as in the second example, in order to maintain statement order. This
example however would be better handled with a block IF construct.
Block IF
Description:
Block IF statements conditionally execute blocks (groups) of statements, a
sequence of zero or more complete CSL statements including other IF-THENELSE blocks. Such a sequence is called a statement block.
Examples:
IF(ABS(force) .GT. breakout) THEN
vdot = netforce/mass
ELSE
vdot = 0.0
Language Reference Manual
72
END IF
IF(a .GT. b) THEN
d = b
f = a - b
ELSE IF(a .GT. b/2) THEN
d = b/2
f = a - b/2
END IF
Initializing variables
Note that the same output variables should always be defined in all branches of
the logic. If they are not, the last value placed in the variable is left around and
used in subsequent integration steps. For example, in the following code, either
VDOT or YDOT is not initialized:
IF(a .GE. b) THEN
vdot = f(a)
ELSE
ydot = f(b)
END IF
Assuming A starts off less than B, then VDOT is not given a value but YDOT is.
When A becomes greater than or equal to B, then VDOT is given a value but
YDOT continues to hold its last value. This is not necessarily wrong, just an issue
to consider when coding logic.
Statements on same line
The IF-THEN statement takes no additional statements on the same line unless
the separator (a semi-colon) is used, turning it into a separate statement; e.g.,
IF(lexpr) THEN ; I = 1 ; ENDIF
Memory operators
Memory operators such as INTEG, REALPL, TRAN, etc. should not be used
inside statement blocks. It's possible to step over an integration statement with
logic, but that doesn't stop the integration from taking place; it just means that the
derivative is not being calculated. This results in the last calculated value being
used. If you don't want a state to be integrated, make the derivative zero.
PROCEDURAL
PROCEDURAL blocks are used to hide logical code from the translation sorting
process, but IF blocks are moved as one and don't require the PROCEDURAL.
The sorting algorithm looks at all the outputs of the block (those variables on the
left side of an equal sign) and all the inputs (those variables on the right side of
an equal sign) and positions the block according to the normal sorting rules. Thus
the block is placed after the calculation of all the input variables and before the
use of any of the output variables.
Language Reference Manual
73
4.46 IMPLC
Form:
z = IMPLC(r, zic)
Description:
z = a simple algebraic variable (IMPVC handles vectors)
r = residual, an arithmetic expression of arbitrary conplexity (i.e., may contain
functions, macros, or other integration statements)
zic = a simple unsubscripted variable, a floating point constant, or a general
expression enclosed in parentheses. If it is a simple variable (preferred), then this
variable name must not be used as another initial condition, state, derivative, or
system variable name.
Implicit integration
In implicit integration, algebraic constraints are defined by an expression that
evaluates to a residual; this residual is then kept at or close to zero. One use of
this feature is in solving for pressure or voltages at junctions, where the junction
has flows or currents that sum to zero (Kirchoff's Law). Specifying the unknown
quantity (pressure or voltage) as dependent on the residual of the sum of the
flows allows it to be adjusted until the sum is really zero.
Examples
The example Tank with Boiling Benzene in Appendix A illustrates a PI controller
with the implicit operators. The aircraft example ACRFTS also uses IMPLC.
Must be in DERIVATIVE
The implicit operators must be in DERIVATIVE sections, and they cannot be
skipped over in logical structures such as PROCEDURAL or IF-THEN-ELSE
blocks.
Residual
The residual expression must be related to the algebraic variable by a path such
that the partial derivative of all the residuals, taken as a vector with respect to all
the algebraic variables again taken as a vector, is a non-singular matrix.
The state and algebraic variables can be seen more clearly in the following:
Y = F(Y, Z )
0 = G(Y, Z )
Here the Y's are the state variables and the Z's are the algebraic variables. This
is now expressed for scalars as:
Language Reference Manual
74
y = INTEG(F(Y, Z), yic)
z = IMPLC(G(Y, Z), zic)
or, for vectors:
y = INTVC(f, yic)
z = IMPVC(g, zic)
where now F and G are vectors that have been filled with derivatives and
residuals respectively in a separate operation. Of course scalar and vector
variables can be used and mixed freely. The acslX translator builds a complete
vector of states and a complete vector of residuals for all the component parts.
Since we must be able to solve the residual relationships for Z, this means that
the partial of G with respect to Z must be non-singular; i.e.,
Derivative
It sometimes is not possible to extract the derivative explicitly from the left-hand
side of an equation, so that the model equations are expressed as:
To handle this, case we have overloaded the IMPLC and IMPVC syntax by
defining a second variable on the left. For scalars, the above equation would be
written:
y, yd = IMPLC(F(y,yd,t), yic)
In actual implementation, this is transformed into an integration statement and an
algebraic constraint as follows:
y = INTEG(yd, yic)
yd = IMPLC(F(y,yd,t), 0.0)
DAE Implementation
The acslX translator builds up vectors for states, derivatives, and initial conditions
using the INTEG and INTVC operators. At this level, we have added to these
vectors the algebraic variables (to the state vector), residuals (to the derivative
vector), and initial guesses for the algebraic variables (to the initial condition
vector). These now look like the following:
Language Reference Manual
75
states
derivatives
ICs
s1
d1
ic1
s2
d2
ic2
s3
d3
ic3
...
...
...
a1
ig1
a2
r2
ig2
a3
r3
ig3
This matrix is the one used in the Gear stiff algorithm since every time the
derivatives are evaluated the Z variables are simultaneously adjusted to force the
residuals to zero.
The nonlinear equation solver to find the Z variables is similar to the one used by
the runtime ANALYZE command. It essentially computes a Newton-Raphson
step:
and a steepest descent step:
Then it takes a linear combination of these two calculations depending on how
successful the iteration is or has been. Since changes are usually small from one
iteration step to the next, this iteration usually converges in one or two
evaluations using the Newton-Raphson step. The usual problem is finding the
algebraic (Z) variable at the very beginning when the initial guesses may be far
from the true solution.
4.47 IMPVC
Form:
z = IMPVC(r, zic)
Description:
Where Z, R, and ZIC are arrays of the same size and correspond to algebraic
variable, residual, and initial condition, respectively. The mechanization of this
operator is explained under IMPLC above.
Language Reference Manual
76
Restrictions apply to the IMPVC operator that are similar to those for vector
integration, INTVC; i.e.:
1. IMPVC cannot be used in an expression.
2. The residual array cannot appear any where else as a state,
algebraic variable, or initial condition.
3. The initial condition must be a variable name, it cannot be a
literal constant or an expression.
4. The array size may be one, or, equivalently, a simple
undimensioned variable can be used instead. In this case,
the residual name is equivalenced directly into the array of
residuals and no extra assignment statement is generated.
Example:
PROCEDURAL(rv = a,b)
rv(1) = a + b
rv(2) = c - b
END
x = IMPVC(rv, xz)
4.48 INCLUDE
Form:
INCLUDE ‘filename’
Description:
Where `filename' is in single quotes.
Example:
INCLUDE ‘../mod1.inc’
Procedure
The INCLUDE statement directs the acslX translator to suspend reading
statements from the current file and read the statements from the INCLUDE file.
The INCLUDE file must comprise complete acslX statements and must result in a
valid program when combined with the surrounding code.
INITIAL, DYNAMIC, TERMINAL
INCLUDE files can contain separate INITIAL, DYNAMIC, and/or TERMINAL
sections with their matching END statements. These blocks are added to the
current sections being built as the acslX translator works its way through the
model definition file.
Language Reference Manual
77
Example
An example of using INCLUDE files is to break a simulation into modules which
are then brought into a skeleton; e.g.,
DERIVATIVE
INCLUDE `seeker.inc'
INCLUDE `autopilot.inc'
INCLUDE `actuator.inc'
INCLUDE `airframe.inc'
END ! of derivative
Nesting
INCLUDE files can themselves contain other INCLUDE statements.
4.49 INITIAL
Form:
INITIAL
...
END
Description:
The INITIAL keyword identifies the beginning of a section of code that is
performed just once at the start of each run. The INITIAL statement must have a
matching END statement. Refer to Chapter 3 for rules of explicitly structured
programs.
Sorting
Code within the INITIAL section is not automatically sorted. Use the SORT
keyword to have an INITIAL section sorted.
Multiple INITIAL sections
Any number of INITIAL sections may be used within a program, at any nesting
level. This feature is particularly useful in conjunction with INCLUDE files and/or
acslX macros; i.e., modules can be developed in separate files with their own
INITIAL sections, then brought into a DERIVATIVE section in a larger model by
means of INCLUDE statements.
The translator collects all the INITIAL sections in the order encountered and adds
them to the end of the INITIAL section to be executed. If the sections of code to
be added need to be in a particular order (so that a variable is defined before
being used, for example), the SORT keyword can be used.
NOTE: MACROs with INITIAL sections cannot be called from within
PROCEDURAL sections. This is because at the moment the INITIAL keyword
must be at a PROCEDURAL nesting level of zero.
Language Reference Manual
78
4.50 INT
Form:
n = INT(x)
Description:
The output n is the integerization of the argument x. The implementation is that n
is the sign of x times the largest integer <= | x |. INT could be used as in the
following example:
INTEGER ibin, ibin1
ibin = ibin1 + INT(xz + x*y)
Example:
INT or AINT can be used on the right side of an equal sign;
y = INT(x)
In this case, the value of x is integerized, but then the result is floated according
to normal conversion rules. The type of the arguments to subroutines however
cannot be inferred, so INT or AINT must be chosen to match the argument type.
In the following, for example, the first argument is forced to be INTEGER and the
second, REAL.
CALL mysubr(INT(x1), AINT(x2), ...)
Now the arguments won't change type with a change in the acslX translator
mode.
4.51 INTEG
Form:
state = INTEG(deriv, ic)
Description:
state = a simple variable. (INTVC handles integration of vectors.)
deriv = an arithmetic expression of arbitrary complexity; i.e., may contain further
INTEG statements, functions, or macros.
ic = a simple non-subscripted variable, a real constant, or a general expression
enclosed in parentheses. If it is a simple variable (preferred), then this variable
name must not be used as another initial condition, state, derivative, or system
variable name. If an expression is used, both the initial condition and the state
are given dummy variable names; a consequence of this is that XERROR and
MERROR do not recognize the state name.
Language Reference Manual
79
INTEG may also be embedded in any legal expression as a function that has a
single output, the value of the state. When the integration statement is alone,
then the state name can be identified; embedding it in an expression means that
an acslX-generated variable (i.e., in the form Znnnnn) must be used for the state
name.
Initial conditions as expressions
If an expression is specified for an initial condition, the expression is sorted in
such a way that all components in the expression are evaluated before the state
value is assigned in the first (initialization) evaluation of the derivatives.
Equations using the state then follow. Problems may occur when using this form
with the REINIT command at runtime. The expression is always evaluated and
substituted for an initial condition established by the reinitialization operation.
Implementation
All integration in an acslX program is handled by a centralized integration routine.
In performing integrations, the integration algorithms utilize two intervals: (1) the
integration step size and (2) the communication interval. Since digital integration
is basically a discrete process, the integration step is the fundamental interval
over which the state variables are updated. No finer detail is accessible except
by some interpolation method. All integration schemes for the set of first order
differential equations in the form:
are transformed into:
where (0.0 <= a <= 1.0) and h is the integration step size. The problem is to find
the effective derivative to use in updating the state vector. Note that with suitable
conditions on continuity and differentiability, the mean value theorem guarantees
that an a exists that produces an exact answer for the state trajectory; finding it is
another matter, however. Different integration schemes approximate the
derivative in different ways, usually by expanding the derivative function in a
Taylor series about the current state. For an example of how this is implemented,
see the explanation of the Runge-Kutta fixed-step fourth order algorithm in the
section on ALGORITHM.
Examples
Examples of use of the INTEG statement include:
y = INTEG(5.0*x(1) + c, yic)
z = p*INTEG(zdot, 0.0) + bt
w = INTEG(wdot, (2.0*al*SIN(th)))
Language Reference Manual
80
Z in the above is not a state since the INTEG function appears embedded in an
expression.
Integrating vectors
The INTVC operator should be used for integrating vectors or multidimensional
arrays.
Initial condition names
Names of initial conditions can be only names not used as states, other initial
conditions, or system variables. The following statements are all illegal when
used with above example statements, except that CINT can be used if the
system default name for the communication interval has been changed with a
CINTERVAL statement:
yy = INTEG(yyd, yic) ! yic is IC for y defined
above
zz = INTEG(z*4.0, w) ! w is a state defined above
zk = INTEG(kk, CINT) ! CINT is a system variable
4.52 INTEGER
See TYPE.
4.53 INTERVAL
Form:
INTERVAL name = floating point number
Description:
where name is a simple unsubscripted variable name. The INTERVAL statement
schedules repeated execution of a DISCRETE section and can be used only in a
DISCRETE section. It is used to define both the name of the variable controlling
the repetition period and its initial value.
No defaults
There is no default for the INTERVAL name or value. A DISCRETE section
without an INTERVAL statement is not executed automatically. An alternative
means of activating a DISCRETE section is with a SCHEDULE statement.
An example of an INTERVAL statement could be:
DISCRETE dac
INTERVAL dt = 0.1
...
END
Language Reference Manual
81
In MINT array
The mechanization of the INTERVAL feature is to use the slot in the global
MINTERVAL array corresponding to the DISCRETE section. The INTERVAL
variable is equivalenced into this array. If no INTERVAL statement is placed
within the DISCRETE block, a value of -1.0 is used as the default. This flags the
DISCRETE section as not to be executed during the initialization phase.
Changing value
The INTERVAL value may be changed (anywhere in the program, or at runtime).
It is the value which is current when the DISCRETE section has completed
execution which determines the next execution time. Once the DISCRETE
section is on the event list, changes in the INTERVAL value do not affect the next
execution time.
Strobe effect
When the INTERVAL for activating a DISCRETE section is a decimal fraction, it
is possible for small errors in timing to result in a beating or strobe effect. The
problem is that decimal fractions (0.1 for example) are never exact on a binary
machine. In order to maintain accuracy, acslX finds an integer multiplier of
CINTERVAL such that the result is an integer (to machine accuracy). If CINT is
0.1, for example, the multiplier is 10. The communication interval times are
obtained by accumulating integer ones and finding the end point by dividing by
ten. A thousand 0.1s by this method is 100 exactly, while a thousand additions of
0.1 (not a power of two and so a rounded number) has significant error. Since
CINT is adjusted and INTERVAL statements are not, a difference can develop. If
this is an important consideration, double precision can help, or else the
INTERVAL value can be biassed by setting it to, for example, 0.1000001 or
0.099999999 instead of 0.01.
4.54 INTVC
Form:
x = INTVC(xd, xic)
Description:
where x, xd, and xic are arrays of the same size and correspond to state,
derivative, and initial condition, respectively. The missile example in Appendix A
uses INTVC.
Restrictions
The restrictions on the INTEG operator with regard to arrays can be avoided by
using this vector integrator operator. The restrictions on the INTVC operator are
as follows:
Language Reference Manual
82
5. INTVC cannot be used in an expression.
6. The derivative array must not appear anywhere else as a
state. If a state must be used as a derivative (velocity, for
instance, which has been integrated from acceleration and is
then the derivative of range), use the block transfer
(XFERBR) subroutine to move it into another array before
using INTVC.
7. The initial condition must be a variable name; it cannot be
either a constant or an expression.
8. The array size may be one. A single undimensioned variable
can also be used, in which case, the derivative name is used
explicitly and no extra assignment statement is generated.
INTVC is the preferred method for integrating scalars if the
derivative is a scalar as well.
9. The derivative array cannot be preset with a CONSTANT
statement since it is cleared automatically to a small number
before the derivative evaluation routine is called the first time
(at the end of the INITIAL section) after every start.
Examples
Following are examples using INTVC:
DIMENSION
x(10),xd(10),xic(10),m(5,5),md(5,5),mic(5,5)
y = INTVC(yd, yic) ! scalar integration
x = INTVC(xd, xic) ! vector integration
m = INTVC(md, mic) ! matrix integration
NOTE: A variable cannot be a derivative in one INTVC statement and a state in
another. For example, if r, v, and a are range, velocity, and acceleration vectors:
DIMENSION r(3), ric(3), v(3), vic(3), a(3)
the following is illegal:
v = INTVC(a, vic)
r = INTVC(v, ric)
since these statements ask for v to be considered as both a state and a
derivative at the same time. Using the XFERBR (transfer block) subroutine and
defining an RD (R dot) array, the sequence becomes:
DIMENSION r(3), rd(3), ric(3), v(3), vic(3), a(3)
v = INTVC(a, vic)
CALL XFERBR(rd = v, 3)
r = INTVC(rd, ric)
Use in sorted sections only
INTVC should be used only in sorted sections or implicit programs, and it should
not be used in a PROCEDURAL.
Language Reference Manual
83
4.55 LEDLAG
Form:
y = LEDLAG(p, q, x[, ic])
LEDLAG(y = p, q, x[, ic])
Description:
The lead-lag compensator output y is related to input x through the transfer
function:
Such that:
Restriction on initial condition
The initial condition, ic, has the same restrictions as the initial condition of the
INTEG operator; i.e., if it is a variable name, the name must not be used as
another initial condition, state, derivative, or system variable name. If the initial
condition ic is not specified, it is given a default of zero.
Time constants
The time constants p and q may be expressions of arbitrary complexity. The lag
value q may not be zero or else a division by zero results.
Setting p to zero makes LEDLAG behave like a pure lag (see REALPL). Setting p
equal to q makes LEDLAG behave like an assignment statement:
y = x
Use in sorted sections only
This operator (as all memory operators) should be used only in sorted sections or
implicit programs. It should not be used in a PROCEDURAL.
An example using LEDLAG is:
xp = k1*LEDLAG(ta1, ta2, e)
Language Reference Manual
84
4.56 LIMINT
Form:
y = LIMINT(yd, ic, bb, tb)
LIMINT(y = yd, ic, bb, tb)
Description:
yd = derivative (variable name or expression)
ic = initial condition of y, with the same restriction as on the INTEG initial
condition (i.e., if it is a variable name, the name must not be used as another
initial condition, state, derivative, or system variable name); may be omitted if
zero (but comma must be included)
bb = bottom bound on y
tb = top bound on y
Example:
The LIMINT operator could be used as follows:
dl = LIMINT(dld, dlic, -dlmx, dlmx)
Figure 4-11: Effect of LIMINT Operator
Use with BOUND
Integrators should not be limited using the BOUND function since the integrator
continues to integgrate and then must integrate out of the limit when the
derivative changes sign. The LIMINT operaator holds the integrator at the limit as
long as the derivative is of such a sign to drive it further into limit. When the
derivative reverses sign, the integrator immediately comes off the limit. However,
LIMINT and BOUND can be used together to force a hard limit:
y = BOUND(0.0, 1.0, LIMINT(2.0*t, 0.0, 0.0, 1.0))
Language Reference Manual
85
SCHEDULE alternative
The LIMINT operator can penetrate the limit, especially if the approach is at high
velocity (i.e., large values for the derivative and step size). If it is necessary to
find the limit points with more precision, use the SCHEDULE operator to force
iteration until the limit penetration point is found, then execute a DISCRETE
section to set the derivative to zero. Use another SCHEDULE statement to find
the point at which the integrator comes back out of the limit and execute another
DISCRETE section to begin using the calculated derivative again.
SCHEDULE with LIMINT
The integration routine can be forced to step up to the limit by using SCHEDULE.
In this case, the LIMINT operator is used and no DISCRETE section is executed.
In the following example, SCHEDULE forces an iteration to the point when X just
crosses the symmetric boundary ±xmx.
x = LIMINT(xd, xic, -xmx, xmx)
SCHEDULE .XP. ABS(x)-xmx
Varying the limits
The limits should not vary in time while the system is in the limit.
Use in sorted sections
This operator (as all memory operators) should be used only in sorted sections or
implicit programs, and it should not be used in a PROCEDURAL.
4.57 LOG
Form:
y = LOG(x)
Description:
The output y is the natural logarithm of x where x is a floating point variable or
expression.
Example:
An example using LOG is:
y = a - LOG(ABS(SIN(w*t)))
4.58 LOG10
Form:
y = LOG10(x)
Language Reference Manual
86
Description:
The output y is the common logarithm (i.e., to the base 10) of x where x is a
floating point variable or expression.
Example:
An example using LOG10 is:
gdbn = 10.0*LOG10((dlp**2 +
dlq**2)*(w/pi*xmag))**2)
4.59 LOGICAL
See TYPE.
4.60 LSW, RSW
Form:
i = LSW(p, j1, j2)
y = RSW(p, x1, x2)
Description:
Where LSW is the integer switch, and RSW is the real (floating point) switch. The
outputs i or y take on the value of the second argument, j1 or x1, when the logical
expression p has the value TRUE; otherwise they have the value of the third
argument, j2 or x2. The j1 and j2 are any integer expressions; x1 and x1 are
floating point expressions. The LSW function is typed INTEGER intrinsically;
RSW is floating point.
Example:
Examples of LSW and RSW statements are as follows:
INTEGER ncount
LOGICAL count
ncount = LSW(count, ncount+1, ncount-1)
cmal = cmalf(mach)*RSW(mach.GT.machmx, (xcg xcp)/d, 1.0)
Alternative for logicals
For logical switches, assignment statements are simpler and clearer. In the
following example, switch is TRUE when x is greater than xmin and FALSE
otherwise:
switch = x .GT. xmin
NOTE: All arguments in the statement are evaluated, whether or not they are
used. The following statement, therefore, results in an error if p becomes zero:
y = RSW(p .EQ. 0.0, x, x/p)
Language Reference Manual
87
Writing the statement as follows avoids the problem of division by zero:
y = x/RSW(p .EQ. 0.0, 1.0, p)
However, the following solution is preferable because it eliminates an IF
statement:
y = x/(p + 1.0E-33)
The probably of p being -1.0E-33 is effectively zero!
4.61 MACRO
Form:
MACRO name(x1, x2, ..., xn)
Description:
The keyname MACRO denotes the beginning of a MACRO definition (if not
already within a MACRO definition). Within a definition, it denotes special
subcommands to be interpreted by the macro processor. For a full description of
the macro capability, see Chapter 5.
4.62 MAX
Form:
y = MAX(x1, x2, ..., xn)
Description:
The output y is the value of the maximum argument, where the arguments xi are
variables or expressions; a maximum of ten arguments may be included.
Negative values are considered less than positive values.
Example:
The type (INTEGER, REAL, or DOUBLEPRECISION) of the output is implied
from the arguments.
nmax = MAX(num1, num2, 2*jj)
w = MAX(wmn, kw*w)
4.63 MAXTERVAL, MINTERVAL
Form:
MINTERVAL name = real constant
Default:
name = MINT
Language Reference Manual
88
real constant = 1.0E-10
Description:
Where name is a simple, unsubscripted variable. The maximum and minimum
value of the integration step size can be controlled and renamed with these
statements.
MAXTERVAL
MAXTERVAL is the upper bound on the integration step size for both variable
step and fixed step algorithms.
MINTERVAL
If a variable step size integration algorithm attempts to take a step smaller than
the value of the applicable MINTERVAL, the error tag variable (see ERRTAG), if
any, is set. If the error tag has already been set, then the termination flag is set.
Fixed step algorithms ignore MINTERVAL.
Arrays with multiple sections
If a program contains only one DERIVATIVE section and no DISCRETE
sections, MAXTERVAL name (referred to by its default name MAXT hereafter) is
a scalar; however, more than one DERIVATIVE and/or DISCRETE section
results in MAXT becoming an array. The elements in MAXT then correspond to
the sections in the order they are encountered in the source code. If
MAXTERVAL is defined outside a DERIVATIVE section, then it is the global
default for all DERIVATIVE sections; the elements for DISCRETE sections are
ignored. To change MAXT for a specific DERIVATIVE section, put a
MAXTERVAL statement with a unique name in the section; for example,
DERIVATIVE
MAXTERVAL maxtsm = 0.0001
The scalar name given is equivalenced to the array element; if the DERIVATIVE
section is first in the program, for example, MAXTSM is equivalenced to
MAXT(1). At runtime, either the array element or the local name can be
referenced.
MAXT(1)=0.001
MAXTSM = 8.05
MINTERVAL is similar, except that for DISCRETE sections the MINTERVAL
elements contain the value of the INTERVAL statement; a -1 indicates that there
is no INTERVAL statement for the corresponding section.
Language Reference Manual
89
Integration step size
The integration step size H for fixed step algorithms is calculated from
CINT/NSTP (see CINTERVAL and NSTEPS statements) and then bound by
MAXT; i.e.,
H = MIN(MAXT, CINT/NSTP)
For variable step algorithms, a lower bound of MINT is added:
H = MAX(MINT, MIN(MAXT, CINT/NSTP))
Control of fixed step integration
For fixed step algorithms, we recommend setting NSTP to 1 and MAXT to the
desired step size. This approach decouples control of the step size from the
communication interval CINT. CINT then is the data logging rate, MAXT is the
integration step size, and each can be set separately without affecting the other.
Runtime
The values of these variables can be set by assignment statements in the
program or by SET commands at runtime. For example, if the following
statement is in a program,
MAXTERVAL MAXT1 = 1.0E-6
then at runtime its value can be changed at the command prompt with:
> MAXT1 = 2.0E-6
Even if the MAXTERVAL and MINTERVAL statements are not included in the
program, they can be accessed at runtime using the default names of MAXT and
MINT. It is seldom necessary to change MINTERVAL.
4.64 MERROR, XERROR
Form:
MERROR v1=real constant, v2=real constant, ..., vn
XERROR v1=real constant, v2=real constant, ..., vn
Description:
Where MERROR is the relative error bound, XERROR is the absolute error
bound, and vi are nonsubscripted variable names that are state variables (i.e.,
appear on the left side of an INTVC or INTEG statement that is not embedded in
an expression). The state itself can be an array, but then the errors specified
apply to all elements in the array. Individual elements cannot be given separate
error tolerances. If any relative or absolute errors are specified, the first
specification encountered is applied to all integrators that are unspecified.
Language Reference Manual
90
Example:
MERROR x=1.0E-4, y=1.0E-6
where:
x = INTEG(xd, xic)
y = INTEG(yd, yic)
z = 5.0*INTEG(zzz, 0.0) + COS(x)
Note that z in the above example cannot have any error bounds specified since it
is not a state. The actual state is a generated variable name in the Znnnnn form
that is placed in the translated assignment statement instead of the INTEG
operator. The MERROR and XERROR statements have meaning only for the
variable step integration algorithms and are used to limit the error introduced at
each step. Based on the maximum absolute value of a state variable |vi |max
since the start of the run (a continue runtime command is considered the start of
a run in this context), the allowable error bound is defined to be:
Ei = MAX (Xi, Mi |vi| max)
If any of the predicted errors in an integration step is greater than the
corresponding allowable error Ei, the step size is reduced appropriately. If the
error is still too large after the step size has been reduced to the minimum
(MINTERVAL), the ERRTAG variable, if any, is set TRUE and the run aborted.
For states that are always less than 1.0, the absolute error dominates, which can
potentially be a problem. Absolute error is used to cover cases when the variable
is near zero. Usually relative error is the important consideration.
4.65 MIN
Form:
y = MIN(x1, x2, ... xn)
Description:
The output y is the value of the minimum argument, where arguments xi are
variables or expressions. A maximum of ten arguments may be included.
Negative values are considered less than positive values.
Example:
The type (INTEGER, REAL, or DOUBLEPRECISION) of the output is inferred
from the arguments.
ilo = MIN(imn+1, j, k5)
maxtc = MIN(period/nstmn, maxtxz)
4.66 MINTERVAL
See MAXTERVAL.
Language Reference Manual
91
4.67 MOD
Form:
y = MOD(x1, x2)
Description:
The output y is the remainder of x1 divided by x2, where x1 and x2 are
constants, variables, or expressions. The type (INTEGER or FLOAT) of the
function and the output is inferred from the arguments. The generic MOD
function is preferred over the more specific AMOD1, MOD0, etc.
The actual implementation can be written as:
x1 =
where [ ] is an integer with magnitude of not more than the argument and with the
same sign.
Example:
Examples of MOD are:
INTEGER j, k, idiv, icount
icount = 100 + MOD(j*k+100, idiv)
fis = MOD(INTEG(fisd, fisic), twopi)
4.68 NINT
Form:
n = NINT(x)
Description:
The output y is the nearest integer of x where x is a floating point variable or
expression. The output type is always INTEGER. This function differs from INT or
AINT, which truncate the input, and from ANINT, which is the nearest whole
number with output of type REAL or DOUBLEPRECISION.
Example:
NINT could be used in a subroutine argument list as follows:
CALL mysub(NINT(v1), ...)
4.69 NSTEPS
Form:
NSTEPS name = integer constant
Language Reference Manual
92
Default:
name: NSTP
integer constant: 10
Description:
Where name is a simple, nonsubscripted variable. The NSTEPS statement
defines the integration step size in terms of the communication interval; i.e.,
NSTEPS is the number of integration steps in a communication interval.
The NSTEPS statement can also be used to rename the variable something
different from the default of NSTP.
Type
The variable named in the NSTEPS statement is automatically typed INTEGER.
Variable step algorithms
The effect of NSTEPS with variable step algorithms differs from that with fixed
step algorithms. Setting NSTP to a relatively large number is a means of helping
a variable step algorithm start at an appropriate size. For variable step
algorithms, the step size H is determined by:
H = MAX(MINT, MIN(MAXT, CINT/NSTP))
In other words, the communication interval is divided by NSTP and then the
results is bounded by MINT and MAXT. If the first try is too large (i.e., if the
estimated error is larger than the allowed error), the algorithm reduces the step
size and tries again, until it finds a small enough step size to start off. Setting
NSTP to a fairly large number (1000, for example) starts the routine at a small
step size, which is then increased automatically as the run progresses until it
reaches the most efficient size.
NOTE: Beware of leaving NSTP at a large value and switching to a fixed step
algorithm.
Fixed step algorithms
For fixed step algorithms (IALG = 3, 4, or 5), MINT is ignored so the step size is
calculated by:
H = MIN(MAXT, CINT/NSTP)
We recommend that NSTP be set to 1 so that the integration step size can be
controlled by MAXT, specified based on knowledge of the plant dynamics; for
example:
NSTEPS nstp1 = 1
MAXTERVAL maxt1 = 0.001
CINTERVAL cint = 0.1
Language Reference Manual
93
With this procedure, the data logging rate (CINT) is decoupled from the
integration step size (now simply MAXT1) so that each can be set independently
without affecting the other.
Array of NSTP
When a program contains more than one DERIVATIVE and/or DISCRETE
section, NSTEPS becomes an array of length ZZNBLK (the number of sections
in the program). The elements of the array correspond to the sections in same
order as they appear in the program. For DERIVATIVE sections, each slot
contains the appropriate value of NSTEPS, which can be set either globally or
else individually for each section. For DISCRETE sections, the slot in NSTEPS is
ignored and INTERVAL is used for the step size of any integrations.
4.70 OU
Form:
y = OU(t, m, s)
OU(y = t, m, s)
Description:
t= low-pass filter time constant; the break frequency is 1/( (2p t) Hz
m = mean value of y
s = standard deviation (RMS value) of y
The OU operator may be used only in a sorted section or implicit program. It
should not be used in a PROCEDURAL. For a random number generator in a
nonsorted section, use GAUSS or UNIF.
Band limited white noise is implemented by this Ornstein-Uhlenbeck function. A
normal random number generator (GAUSS) delivers a fixed total power (RMS
value), but the frequency spread depends on the current step size. Usually the
low frequency power density is important, so casual use of GAUSS into a low
pass filter leads to ill-defined variation of this quantity as the step size is
changed. The Ornstein-Uhlenbeck process maintains a constant source of power
over a specified frequency band, thus eliminating any problem of having to
include the current integration step size in the standard deviation of the random
variable.
NOTE: that in general the roll-off time constant t should be at least twice the size
of the maximum integration step; use MAXTERVAL to enforce this constraint.
The operator is implemented by generating a correlated noise sequence from the
general formula:
Language Reference Manual
94
where:
t = correlation time constant
D t = sample interval
wi = Gaussian random variable
In order to find the wi that produces the correct noise power such that:
square the above equation for n i+1 and take the expected values:
It can be assumed that the random drive is uncorrelated with the noise
sequence; i.e.,
But:
so:
and now the sequence can be expressed by
where gi is a Gaussian random variable of zero mean and unit variance. An
example using the OU operator is:
Language Reference Manual
95
noise = OU(ta1, mean, sigma)
4.71 PARAMETER
Form:
PARAMETER(p1 = e1[, p2 = e2] ...)
Description:
The PARAMETER statement associates the symbolic name with an expression
that can be made up of constants and/or previously defined parameters but not
variables. The symbolic name may then be used whenever an integer, real,
logical, or character constant would normally appear in the program code.
Dictionary
The PARAMETER name pi does not appear in the program dictionary and is
replaced everywhere by the value of the corresponding expression ei.
Expression
The expression (ei) can consist of literal constants, PARAMETER names, and
arithmetic operators (+, -, *, /).
Type INTEGER
PARAMETER variables are not automatically typed INTEGER, even if they begin
with letter I, J, K, L, M, or N. Include an INTEGER type statement for any integer
PARAMETER variable names before they are used.
Placement in program
The PARAMETER statement must appear in the program before the parameter
is used; otherwise, the translator produces an error message:
...Parameter already defined NAME
Example:
PARAMETER statements are useful for defining things like array sizes and for
keeping the definitions in one place. For example,
INTEGER maxdim
PARAMETER (maxdim = 5)
DIMENSION a(maxdim,maxdim), v(maxdim), r(maxdim)
CONSTANT v = maxdim*1.0
Language Reference Manual
96
4.72 PROCEDURAL
Form:
PROCEDURAL(output list = input list)
...
END
Description:
output list = v1, v2, ..., vn
input list = e1, e2, ..., enand vi
are nonsubscripted variable names while ei may be variables or expressions.
The PROCEDURAL header must be paired with a matching END statement.
The PROCEDURAL keyword denotes the beginning of a block of PROCEDURAL
code to be executed in the sequence given; i.e., the code within the
PROCEDURAL block is not sorted by the acslX translator. PROCEDURAL
blocks are required only in sections that are sorted. They are permitted but not
required in non-sorted sections of the program.
Arguments
The header list should contain only nonsubscripted variable names. The variable
names may belong to arrays, however, in which case the entire array must be
filled within the block. The sort algorithm requires that values appear as outputs
only once in sorted code; otherwise the error message "Multiply defined symbol"
is issued. States and constants do not need to be included in the argument list
because they are available all the time. Calculated variables are needed because
they tell the sorter where to put the procedural in relation to calculations.
Array example
As an example, the following statements in a sorted program result in the
variable A being flagged as defined twice:
a(1) = x + y
a(2) = y + z
This is illegal. An acceptable form would embed this sequence in a
PROCEDURAL block, informing the sort routine to place the block before
reference to any element of the array A, as follows:
PROCEDURAL(a = x, y, z)
a(1) = x + y
a(2) = y + z
END
Language Reference Manual
97
Sorting operation
The entire PROCEDURAL block is moved by the translator within a DERIVATIVE
section so that it is placed after the calculation of all variables on the input list
and before the use of any variables on the output list. Although other variables
may be present on the list, sorting is only with respect to variables calculated
within the same DERIVATIVE section. The sort operation never moves code
across section boundaries. The entire DERIVATIVE section can be made a
PROCEDURAL, and since it then cannot be moved, no input or output argument
list is necessary. It is better to use more small PROCEDURALs rather than fewer
large ones.
When required
PROCEDURAL blocks should always be used in sorted sections around code
constructs in which the order must not be changed. Typical operations which
must be enclosed in PROCEDURAL blocks include DO, GO TO, IF, and array
calculations. The IF-THEN-ELSE block does not require a PROCEDURAL even
in sorted sections.
With subroutine calls
Another construct which may require a PROCEDURAL is the subroutine call. If
acslX is not informed which arguments are inputs and which are outputs, a
subroutine call may not be sorted correctly. Enclosing subroutine calls in
PROCEDURAL blocks or using an equal sign in the subroutine argument list are
methods of clarifying input and output lists for the translator (see CALL).
With algebraic loops
Experts may lie in specifying what is on the input/output lists. The acslX
translator never looks inside the PROCEDURAL block to ensure compliance with
the list supplied, so it is possible to break algebraic loops for approximate
solution by omitting one of the loop variables from the PROCEDURAL input list.
Since this variable is used before it is calculated, initialization in the INITIAL
section is required. In breaking implicit loops this way, the last value of the
variable is used, which is satisfactory in a large number of cases. Be warned
however that the results change with step size and a variable phase shift is
present in traversing the implicit block. This also destroys the validity of the
Jacobian and all derived quantities such as eigenvalues, zeros, etc. Use IMPLC
to handle algebraic loops.
NOTE: Statements involving memory operators should not be included in
PROCEDURAL blocks because parts of these operators must be separated for
sorting. These operators are BCKLSH, CMPXPL, DBLINT, DERIVT, LIMINT, and
OU.
Language Reference Manual
98
Integration operators
Using integration operators (INTEG, REALPL, etc.) inside PROCEDURAL is not
illegal but does not make sense. States cannot be computed procedurally, only
derivatives can.
4.73 PROGRAM
Form:
PROGRAM [string]
...
END
Description:
Where string may contain any number of characters, which are ignored. The
PROGRAM statement is the first line in an explicit model definition. It must be
accompanied by a matching END statement to terminate the model definition.
The character string is not used in any way and serves merely to identify the
model file and listing.
Example:
PROGRAM a missile 6DOF simulation
For implicit programs (i.e., those with no explicit structure statements), use
DERIVATIVE rather than PROGRAM. This approach is required because some
system macros have INITIAL sections, which expect explicit structure with the
PROGRAM statement. A DERIVATIVE statement can include a name, but for a
title with more than one word, use the comment indicator.
DERIVATIVE ! title of program
...
END
4.74 PTR
Form:
PTR(x, y = r, th)
Description:
The polar to rectangular operator resolves angle q (which must be expressed in
radians) and radius r into Cartesian coordinates x and y (with the same units as
r) by the following equations:
x = r cos q
y = r sin q
Language Reference Manual
99
This form is not a functional representation since there are two outputs. Thus,
this statement cannot be embedded in an expression; it can only stand alone.
An example of PTR is:
PTR(rt1, rt2 = lrt, fi)
4.75 PULSE
Form:
y = PULSE(tz, p, w)
Description:
Where y is a pulse train (0.0 or 1.0) starting at the first integration step at which
time equals or exceeds tz. The period is p and width is w, as shown in Figure
4-12. The width cannot be zero.
The independent variable, default T, drives the PULSE function. Note that the
integration step size may affect the answers in that too large a step could cause
the pulse to seem to stay on indefinitely. The output is always turned on (y = 1.0)
at the beginning of the first integration step following the exact turn-on time. The
width is not synchronized to the integration step size, so it should be significantly
larger than the step size.
Do not use PULSE as a strobe to periodically activate parts of a program. This is
a job for DISCRETE sections executed by means of INTERVAL statements or
the SCHEDULE operator.
Example:
PULSE could be used as follows:
drive = k*PULSE(tdrive, period, width)
Figure 4-12: Mechanization of PULSE Function
Language Reference Manual
100
4.76 QNTZR
Form:
y = QNTZR(p, x)
Description:
Where x and p are real variables or expressions. The output y is the value of x
quantized in discrete steps of resolution p. This is a zero centered system, as
shown in Figure 4-13.
Example:
An example of QNTZR is:
epq = QNTZR(ep, signal - oldsig)
Figure 4-13: QNTZR quantizer function
4.77 RAMP
Form:
y = RAMP(tz)
Description:
The RAMP function generates a linear ramp of unit slope, starting at a specified
time tz. It is another way of applying a dead zone to the independent variable.
RAMP starts at the first integration step that equals or exceeds tz. The output
can be expressed as follows:
y = 0.0 ; T < tz
y = T - tz ; T > tz
Example:
An example of a RAMP statement is:
z = k1 + k2*RAMP(tramp)
Language Reference Manual
101
4.78 REAL
Form:
REAL(x)
Description:
This function converts an integer, double precision, or single precision argument
x to a single precision value. See DBLE for a discussion of usage.
See also REAL as a single precision floating point variable type under TYPE.
4.79 REALPL
Form:
y = REALPL(p, x[, ic])
REALPL(y = p, x[, ic])
Description:
The REALPL operator produces a first order lag where output y is related to input
x through the transfer function:
where:
y(0) = ic
Figure 4-14 lists the macro to implement this operator.
Figure 4-14: REALPL operator macro
The initial condition has the same restrictions as the INTEG operator; i.e., if it is a
simple variable (the preferred form), this variable name must not be used as
another initial condition, state, derivative, or system variable name. If the initial
condition is zero, it may be omitted. The time constant p may be an expression of
arbitrary complexity, but it cannot be zero or division by zero results.
Language Reference Manual
102
Example:
An example of a REALPL statement is:
xm = k3*REALPL(ta3, x)
4.80 RESET
Form:
RESET("EVAL")
RESET("NOEVAL")
Description:
This special operator is provided for use in the INITIAL section to initialize the
state variables and optionally perform intermediate calculations.
Argument
The arguments EVAL and NOEVAL specify whether or not a complete derivative
evaluation is to be attempted. Be sure that unknown initial conditions have
reasonable values to prevent arithmetic errors (division by zero, for example).
When states are initialized
The states are initialized at the beginning of the INITIAL section, the equivalent of
RESET("NOEVAL"). Previously, states had been initialized at the end of the
INITIAL section, so there was more reason to use this operator. Now only
RESET("EVAL") is needed.
Accelerometer example
RESET could be used for example in calculating the initial conditions on
accelerometer filters in a missile simulation. To obtain the nominal acceleration,
the missile velocity vector must be rotated into the missile axes, the angle of
attack determined, and the aerodynamic coefficient data looked up to obtain
force coefficients. This code must be expressed in terms of the initial condition
variables rather than the state variables unless the RESET operator is used. If
the RESET("EVAL") statement is placed at the beginning of the INITIAL section,
the derivative subroutine calculates body acceleration using the state variable
names.
NOTE: The problem in using RESET is that the process is not selective.
Calculation of all state variable derivatives is attempted. In the above example,
the output of the accelerometer filter is used later and if initialized indefinite leads
to an arithmetic error. If the undefined initial conditions are preset in a
CONSTANT statement (0.5 is a useful default number), then the calculation can
proceed and the meaningless numbers can be disregarded. The important
consideration is that all the calculations be able to proceed without arithmetic
errors
Language Reference Manual
103
4.81 RSW
See LSW.
4.82 RTP
Form:
RTP(r, th = x, y)
Description:
The rectangular to polar operator resolves the input Cartesian coordinates x and
y into polar angle q (which is in radians in the range - p to + p depending on the
magnitude and sign of x and y) and radius r (which has the same units as x and
y) by the following equations:
q = ATAN2 (y, x )
Figure 4-15 shows the mechanization of this operator as a system macro. Note
that the second argument of the arc tangent (ATAN2) is modified by the addition
of a very small amount. This enables inputs of 0.0, 0.0 to return an angle of zero
instead of indefinite.
Figure 4-15: RPT operator macro
This form of the operator is not a functional representation since there are two
outputs. Thus, this statement cannot be embedded in an expression; it can be
used only in the standalone form as shown.
4.83 SAVE
Form:
SAVE
Description:
The macro tables containing the macro names and packed definitions are written
(in binary) on the acslX system macro file. The SAVE operation allows you to
maintain your own files of macros separate from the system file.
Language Reference Manual
104
Normally the system reads the contents of the user macro file into the macro
definition tables before the translation begins. If such a file does not exist, no
user macro definitions are present.
The action of SAVE is to write the current contents of the macro tables back on
this file, thus destroying the original contents. To use SAVE, you must have
WRITE permission on the current macro file.
4.84 SCALE
Form:
SCALE(smn, smx = ymn, ymx)
Description::
ymn, ymx = minimum and maximum values
smn, smx = scaled minimum and maximum to be used on a plot (i.e., rounded
multiples of 1, 2, 4, or 10).
The SCALE operator rounds the inputs so that they are suitable for plotting. The
inputs ymn and ymx are usually collected in the DYNAMIC section by keeping
track of the smallest and largest values of the variable of interest. The SCALE
operator is then used in the TERMINAL section of an explicit program to
establish scale factors for subsequent PLOT commands. It is used only when two
or more plots need the same, originally unknown, scale factors.
The first two arguments need not be distinct from the second; i.e., the following
statement replaces actual minimum and maximum values with the rounded ones:
SCALE(ymn, ymx = ymn, ymx)
4.85 SCHEDULE
Form:
SCHEDULE
SCHEDULE
SCHEDULE
SCHEDULE
block/flag
block/flag
block/flag
block/flag
.AT.
.XZ.
.XP.
.XN.
time-expression
real-expression
real-expression
real-expression
Description::
block = optional block name of DISCRETE section to be executed after the state
has been advanced just over the boundary
flag = optional flag name that is automatically made type LOGICAL and set
TRUE when the event has occurred (may not be an array)
.AT. = following expression specifies time at which block is to be activated (may
not be used in a DERIVATIVE section)
Language Reference Manual
105
.XZ. = zero crossing (positive or negative direction) of following expression
initiates execution of a discrete event.
.XP. = zero crossing (positive direction only) of following expression initiates
execution of a discrete event.)
.XN. = zero crossing (negative direction only) of following expression initiates
execution of a discrete event.
The block / flag is optional; however, flag cannot be used without a block also
being present. SCHEDULE can be used without a block or flag in order to force
integration to a certain point.
Flag setting
If a flag is specified, it is set TRUE just before the DISCRETE section is
executed, stays TRUE during execution of the section, then is set back to
FALSE.
Flag example
The flag is available to handle logic, generally within a single DISCRETE section,
as in the following example:
PROGRAM
INITIAL
y = 0.0
END ! of Initial
DERIVATIVE
x = SIN(t)
SCHEDULE d/f1 .XZ. x+0.5
SCHEDULE d/f2 .XZ. x-0.5
TERMT(t .GE. tstp, `Stop on time');CONSTANT
tstp=4.9
END
DISCRETE d
IF(f1) THEN
y = 2.5
ENDIF
IF(f2) THEN
y =-2.5
ENDIF
END ! of Discrete
END ! OF Program
Expressions
The time-expression defines a time (real value) of the independent variable at
which the event is to be activated. The real-expression defines a function, the
zero crossing of which (in the appropriate direction) defines the event. This realexpression must be a true function of the state variables in that the same set of
state variables must produce identical values of the function no matter how many
Language Reference Manual
106
intermediate evaluations occur. If the real-expression is not a true function, the
following error message may be produced.
Event vanished - cannot proceed
WEDITG
A summary of the activity at the time of an event (i.e., finding and narrowing
thewindow and calculating the value of the expression at each evaluation) is
produced at runtime at each occurrence of an event. In the example, the event
finder is activated in the first line and the window is narrowed over five iterations.
The last two lines of the summary give the values of the independent variable
and the zero crossing expression along with the number of the DISCRETE
section (i.e., the position of the section among the DERIVATIVE and DISCRETE
sections in the program) executed.
This output can be suppressed by setting runtime system symbol WEDITG (write
event description, default TRUE) to FALSE.
Handling dicontinues
The SCHEDULE operator handles the introduction of discontinuities into an
otherwise continuous simulation. The integration algorithms used to solve
equations in the form:
conventionally require the function F to be continuous and differentiable within an
integration step. The automatic variable step algorithms such Adams-Moulton or
Gear's Stiff (IALG = 1 or 2) or Fehlberg (IALG = 8 or 9) reduce the step size in
the region of a discontinuity in F at the expense of increased processing time,
and it is debatable how well the error control mechanism works in the event of a
discontinuity in one of the state variables. Nature has no real discontinuities
given a sufficiently fine time scale; discontinuities arise from simplifying the
model and observing the system behavior in a macro time scale.
Bouncing ball example
In the example of a ball bouncing, the macroscopic view shows the velocity
changing discontinuously (by the coefficient of restitution) at the instant of
bounce. In the microscopic view, the spring constant of the ball is taken into
account and all the forces of deformation are calculated, significantly increasing
the model complexity but eliminating the discontinuity.
Digital controller example
Another example is a digital controller. From a macroscopic viewpoint, the output
is an analog control voltage through a digital to analog converter (DAC), which
Language Reference Manual
107
jumps discontinuously at the output time points. At a microscopic level, voltages
cannot change discontinuously since finite capacitances are always present and
must be charged through some sort of resistive network. A simulation normally
takes the macroscopic view (i.e., a voltage jump) for efficiency, the designer
deciding which time scale of events is important for model validity.
Switch point
If a point of discontinuity can be located, the solution on either side of the
discontinuity can be treated as piecewise continuous. A possible penalty is that
the variable step algorithms may have to be restarted after a discontinuity since
they keep track of an estimate of derivatives (a Nordsieck vector) which is
probably invalidated at a switch point.
Time vs. state events
Two types of discontinuity are encountered in general simulation models; one we
call a time event and the other a state event. Time events can always be defined
as state events, but for efficiency they are extracted as a separate case. State
events can be visualized as occurring at surfaces in state space. Such surfaces
include the zero height plane in the bouncing ball problem, the zero velocity
plane in Coulomb stiction/friction, and the critical temperature plane for a reactor
shutdown event. The integration algorithm advances in discrete steps which at
some point takes the model across the critical surface; the problem is in finding
the exact crossing point.
Finding the event
In the special case of a time event, which is a wall perpendicular to the time axis,
the integration step can always be taken as the minimum of the normal step or
the time left to the event, so no iteration is required. For state events, where the
boundary is a general surface in state space, an iteration brackets the event to a
finer and finer tolerance until a specified accuracy is reached. Mathematically the
problem is stated:
;
;
where the plane in state space distinguishing the event can be expressed by:
g(x, t) = 0
where g is a single-valued function of the state variables and time.
Changing boundaries
In actual fact, the situation can be complicated by the boundary function
changing when the state equations switch from F1 to F2. Examples of changing
boundaries include backlash, hysteresis, and Coulomb friction. In the friction
Language Reference Manual
108
model, the boundary function is zero velocity when the body is sliding and
applied force exceeding breakout force when the body is stuck.
NOTE: State events cannot be scheduled from IF constructs because acslX has
to keep a count of the state event statements. Time events can be used inside IF
or DO constructs in unsorted sections such as DISCRETE or INITIAL. Multiple IF
statements are dangerous; instead, use an IF-THEN-ELSE construct, which
covers all the bases so a value is not left around inadvertently.
4.86 SCHEDULE Time Event Specification
A time event is defined by the .AT. form of the SCHEDULE statement. The time
event SCHEDULE must be specified in a DISCRETE section (or in the INITIAL
section) and may not be included in a DERIVATIVE section. Every execution of
the time event operator places a marker in the event list to execute a block at a
particular time. If this were executed in a DERIVATIVE section where the code is
executed and re-executed many times under the control of the integration
algorithm, the event list would fill with these markers.
A simple example in an INITIAL section to execute DISCRETE switch:
INITIAL
CONSTANT swtime = 10.0
SCHEDULE switch .AT. swtime
...
END
Execution time
If the value of the time-expression is less than the current time, the block is
executed immediately after the current DISCRETE block has finished. Time in
the continuous section can never go backwards (with the exception of the entire
model moving backwards as described in Chapter 8).
Digital controller example
An example of the use of time events is the modeling of a digital controller with
an analog to digital converter (ADC) sampling values from the continuous
process, a delay while control output values are computed, and then transfer of
these values, usually as voltages through DACs, but also as switch closings to
activate solenoids and control valves. For example, for a sampling time of 10
msec and compute delay of 4 msec, the code for the relevant DISCRETE
sections could be as follows:
DISCRETE adc
INTERVAL tsamp = 0.010
outp = F(sampled inputs)
CONSTANT dlt = 0.004
SCHEDULE dac .AT. T + dlt
END ! of adc section
DISCRETE dac
Language Reference Manual
109
! Executed 4 msec after adc
out = outp
END ! of dac section
The DISCRETE section ADC contains an INTERVAL statement which ensures
that the section is executed every 0.010 sec. When it is executed, all the state
variables in the continuous section have been advanced to the sampling time, so
they are all available as though they had been passed across an ADC channel,
except for possible quantization noise. The output can be calculated but must be
hidden from the continuous world because it actually comes out of the DAC
some time later. In the program, it is hidden by giving it a different name (OUTP).
The SCHEDULE statement in the ADC section asks for the DAC time event to be
executed at T + 0.004 sec after the ADC section has executed. The DAC block is
entered on the event list and control returns to the integration algorithms to
advance the continuous state variables until the next event occurs. Time
advances the 4 msec and the DAC block is executed, transferring the hidden
output variable OUTP into OUT, the name used by the continuous part of the
simulation.
No INTERVAL
Since the DISCRETE section DAC has no INTERVAL statement, the only time it
is executed is when it is SCHEDULEd from the ADC section.
DISCRETE scheduling itself
As mentioned above, only DISCRETE sections can be scheduled for execution,
and time events must be specified within DISCRETE or INITIAL sections.
Scheduling time events in DERIVATIVE or DYNAMIC sections results in the
same event being scheduled many times (i.e., every time the DERIVATIVE or
DISCRETE section is executed). A DISCRETE section can schedule itself for
execution in the future, thus replacing the INTERVAL statement.
Event list
All time events are kept on the event list, which is ordered in time. The
communication interval for data recording is itself classed as an event and
entered on this list. When control is transferred to the continuous integration
section, it first checks the event list for the next time event and makes this its
goal, advancing with the normal step size selection mechanism until a short step
is required to reach the event. When all DERIVATIVE blocks have arrived within
the tolerance EPMX (explained in the section on the state event mechanization)
of the time event point, the event is deleted from the event list and the associated
DISCRETE block (if any) is executed. The Discrete Sampled Compensator
example in Appendix A shows how time events can be used in a digital data
system.
Language Reference Manual
110
4.87 SCHEDULE State Event Specification
Specifying an event boundary activates an iteration within the integration
algorithm to cross the event boundary with a minimum step size. The forms of
SCHEDULE which apply to state events are .XZ. (cross zero), .XP. (cross
positive), and .XN. (cross negative). They may appear only in DERIVATIVE
sections.
Bouncing ball example
An example of a state event specification is finding the bounce point of a ball
dropping (under the acceleration of gravity) with the following statement:
SCHEDULE bounce .XN. h
which executes a DISCRETE block called BOUNCE when height h crosses zero
in the negative direction. In the BOUNCE section, velocity is reversed and
modified by the coefficient of restitution as follows:
DISCRETE bounce
v = -kr*v
END
Flag vs. multiple DISCRETE
Handling multiple events with a single block usually requires a flag so that the
events can be sorted out, but using SCHEDULE operators with separate
DISCRETE blocks can remove that requirement.
NOTE: The state event SCHEDULE operator must be placed in a DERIVATIVE
section. It may not be placed inside a PROCEDURAL. It may not be skipped over
by the use of GO TOs or other control transfer mechanisms (such as the various
IF constructs) since acslX needs to keep a count of the SCHEDULE statements.
The statement may be placed anywhere in the DERIVATIVE section, but
execution is slightly more efficient if it is placed at the beginning of the section
since only the code necessary to evaluate the event zero crossing expressions is
executed when the time comes to test the event.
4.88 SCHEDULE State Event Mechanization
At the beginning of a simulation run, the DERIVATIVE code is executed. Each
call to the state event handler increments a counter so that acslX knows how
many events are in operation. If no active state events are present, then there is
no need to test for an event at each step. All state SCHEDULE statements must
be evaluated at every DERIVATIVE evaluation because they are known by the
count of order of appearance.
Implementation
After the integration algorithm has been initialized, the integration system saves
all the state variables at the beginning of a step, makes the step without regard to
Language Reference Manual
111
any events, and then calls the DERIVATIVE evaluation block one last time to see
if the states have crossed the event threshold. Testing is not done during
intermediate evaluations of the derivatives since these are extrapolations of
much lower accuracy in general than the final step. Since this final evaluation is
not part of the evaluation of the derivatives and states (its purpose is only to
evaluate the expressions required to execute the DISCRETE block associated
with the event), a count is kept and when all expressions corresponding to the
state event definitions have been evaluated, then the remainder of the code is
skipped. If the expressions are functions of only state variables, the sorter does
not have to move them. If they are functions of intermediate calculated quantities
(dynamic pressure, for instance), the event specification is sorted to a position
just after the calculation of its inputs, thus minimizing the code executed at the
threshold test phase.
The first derivative evaluation during the initialization process saves the current
value of the real-expression (EXPR) as the previous value (EXPP). At each
subsequent step, the current value is tested to see if EXPP and EXPR bracket
zero. The code is as follows:
IF(expr*expp .LT. 0 .AND. expp .NE. 0) GO TO event
Starting on zero
Note that if the previous expression EXPP is exactly zero, then no event is
signalled. An event is defined as starting from a non-zero value, with the new
value crossing or landing exactly on the zero point. An advantage of this method
is that the expression can start at zero and no event is indicated until the
expression returns to cross zero.
Multiple events
Any number of events can be specified and they all are found in sequence. A
crossing point is estimated for each event activated within a step, then the
smallest value of the independent variable (time) is selected.
Iterating to step
The iteration within a step proceeds until the zero crossing is within a window
less than the tolerance, in which case time is advanced to the most positive edge
of the window by calculating the appropriate step size from the saved state
condition (at the beginning of the activating step).
Executing DISCRETE
Once the step has been taken, the DISCRETE block (if any) associated with
each active event is executed so that model conditions can be changed. Usually
there is only a single event pending since it is separated in time from other
events. However, it is possible that more than one event occurs in the same step
Language Reference Manual
112
and then each associated DISCRETE block (which may be the same one called
by different events) is executed in servicing each event.
Re-evalutate DERIVATIVE
After each pending event has been serviced by executing the associated
DISCRETE block, the DERIVATIVE routine is executed one last time with a flag
set to cause replacement of all previous values (EXPP) with current values. Any
current events are thus taken off the active list since the expression must now
cross zero from the other side (.XZ.) or return to the other side in order to cross
zero from the same direction (.XP.) for the next event.
DISCRETE can change switching function
Note that the execution of the associated DISCRETE block can set variables in
such a way as to change the switching function completely. In the case of friction,
the switching function fi can be written:
fi = RSW(stuk, ABS(force) - breakf, veloc)
where the function RSW (real switch) returns the value of the second argument if
the first argument is TRUE; otherwise, it returns the third argument.
When the body is stuck (STUK is TRUE), the event occurs when the force acting
on the body (FORCE) exceeds a breakout force (BREAKF); i.e., when the
expression ABS(FORCE) - BREAKF crosses zero. When the body is not stuck, it
sticks when the velocity crosses zero. The units of the zero crossing function
thus change depending on the regime in which the model stands; i.e., Newtons
of force when the body is stuck, and meters per second for velocity when it is not
stuck.
Handling discontinuities
Confining discontinuities to the DISCRETE event servicing block is a sound
approach. The DERIVATIVE equations can then remain continuous through the
event, which allows the event to be found, slopes and states changed, and the
integration routine restarted so that past derivative history is discarded.
SIGN example
An example of a discontinuity to which the SCHEDULE operator can be applied
is the SIGN function. The following statement:
force = SIGN(kslid, -veloc)
indicates that FORCE is to change discontinuously to oppose the velocity, which
affects the integration step when the velocity crosses zero. The actual integration
step that crosses the boundary has trouble with the discontinuity. In some cases
it fails to cross the boundary entirely when the actual step is taken by adding up
the weighted intermediate calculated (i.e., fixed step algorithms such as Runge-
Language Reference Manual
113
Kutta fourth order with first order extrapolators). For this case, a better
implementation is as follows:
force = fslid
SCHEDULE handl .XZ. veloc
...
DISCRETE handl
fslid = SIGN(kslid, -veloc)
END ! of discrete
Now the force is continuous and differentiable (a constant) in the continuous
section, giving the integration algorithm an easier task.
NOTE: The event finder also has a problem with the acslX operators which have
their own internal memory (or state variables) when it is unable to back up and
reproduce the previous step before iterating to find the zero crossing. For
example, the backlash operator BCKLSH works by using the statement:
yl = MIN(MAX(yl, input - dl), input + dl)
output = yl
Thus, OUTPUT is the previous value YL (Y last) unless INPUT exceeds YL by
more than the backlash value DL. Backing up may leave YL at the same value,
so the zero crossing finder may find the expression on the same side of zero
after the single step backup, at which point it stops with the message Event
vanished. The operators that have internal state variables (potential sources of
problems with SCHEDULE) are:
BCKLSH DBLINT DERIVT GAUSS IMPL LIMINT OU UNIF
Operators that are implemented as differential equations (such as REALPL,
CMPXPL, and TRAN) have no problem. Algebraic operators (such as STEP and
RTP), which pass a signal directly with no memory, also work correctly. DELAY
is configured so that it works with SCHEDULE.
First order filter
One workaround for these situations is to put the variable through a first order
filter with a fast enough time constant to act the same as a step so the event
finder iterates on the continuous (though steep) function. Such a high frequency
pole can increase computer running time, however. Another approach is to write
a routine to perform the same function using integrators that can be handled by
the zero crossing finder.
NOTE: Be careful finding a stopping condition at the boundary since the
integration algorithm must take a step that crosses the boundary before
recognizing that an event has occurred. To stop on impact with the ground, do
not do the following:
SCHEDULE .XN. height
TERMT(height .LE. 0)
Language Reference Manual
114
The step that makes HEIGHT less than zero also sets the STOP flag so the run
is terminated before it can back up and find the zero crossing. Instead use a
DISCRETE section; for example:
SCHEDULE stop .XN. height
...
END
DISCRETE stop
TERMT(.TRUE., `Stopped on zero height')
END
Now the state event iteration takes the step to or just below the HEIGHT equal to
zero plane. Then the handler DISCRETE block is executed to set the STOP flag
and terminate the run.
4.89 Separator (;)
Form:
statement ; statement
Description:
A semi-colon (;) separates any valid acslX statements. Comments can be placed
only after the last statement on a line since everything after an exclamation point
(!) is ignored by the translator.
Example:
TERMT(t.GE.tstop); CONSTANT tstop=4.9 ! Stop Run
4.90 SIGN
Form:
y = SIGN(x1, x2)
Description:
Where x1 and x2 are floating point constants, variables, or expressions. The
output y is the sign of x2 times the absolute value of x1. SIGN could be used as
follows:
z = k*SIGN(zbase, zsign)
4.91 SIN
Form:
y = SIN(x)
Language Reference Manual
115
Description:
The output y is the sine of the floating point argument x, which must be in
radians; the result is in the range (- 1.0 <= y <= +1.0).
Example:
SIN could be used:
p = INTEG(y*SIN(w*t + fi), 0.0)
4.92 SORT
Form:
SORT
Description:
The SORT keyword notifies the translator to sort all statements from the keyword
to the end of the section (INITIAL, DYNAMIC, DISCRETE, or TERMINAL). All
DERIVATIVE sections are sorted automatically.
This feature could be used for INITIAL sections which have been built from a
number of INCLUDE statements without regard to correct order.
4.93 SQRT
Form:
y = SQRT(x)
y = SSQRT(x)
y = FSQRT(x, lam)
Description:
The output y is the square root of x where x is positive floating point variable or
expression. A negative argument results in a exception trap on most computer
systems.
Example:
An example using the SQRT function is:
miss = SQRT(xmt**2 + ymt**2 + zmt**2)
Alternative functions
Compilers on different systems handle situations such as negative arguments to
the square root function differently. In order to catch and handle any errors
gracefully, SSQRT (signed square root) and FSQRT (flow square root) functions
have been added to the library at Version 11.5. Both convert automatically to
Language Reference Manual
116
single or double precision. The functions are listed in Figure 4-16 and Figure
4-17.
The signed square root function takes the square root of the absolute value of
the input, and then gives the result the sign of the input. The flow square root
function switches to laminar flow when the pressure drop equals the second
argument.
Some mathematical models are physically incorrect when the state of the system
brings the simulation to the point where it is taking the square root of a negative
number. In this case, it should not only use SSQRT to avoid a numerical
problem, but also add a TERMT operator to stop the run and report the problem.
In some models, flows become zero and noise in the calculations can result in
small values on the negative side of zero. In these situations, the BOUND
function would probably be used to keep the variable from going negative.
Figure 4-16: Signed Square Root Function (SSQRT)
Language Reference Manual
117
Figure 4-17: Flow Square Root Function (FSQRT)
4.94 STEP
Form:
y = STEP(tz)
Description:
The STEP function output y changes from zero to one at a specified value tz of
the independent variable. The result is
y = 0.0 ; T < tz
y = 1.0 ; T > tz
Language Reference Manual
118
4.95 TABLE
Form:
TABLE name, n, d /list/
Description:
name = name of the function. The value is accessed by name(arg1), name(arg1,
arg2), or name(arg1, arg2, arg3) for functions of one, two, or three variables,
respectively. The arguments are of any arbitrary level of complexity.
n = an unsigned integer constant giving the number of independent variables;
this number must be 1, 2, or 3.
d = unsigned integer constants (may not be variable names); the number of
constants must correspond to the value of n. The values of the constants give the
number of discrete data points for each successive independent variable. A
dimension of one is illegal.
list = floating point constants. The values of the independent variable are listed
first. The number of these points must equal the sum of the dimensions. Then the
dependent values are listed with the fastest varying argument first. The number
of function data points must equal the product of the dimensions.
The TABLE statement describes any arbitrary function of one, two, or three
variables. A separate TABLE statement must be used to define each function.
Accessing a TABLE
TABLE statements must be defined before the table is referenced. The table is
accessed by name and the independent variable; for example, if CLP has been
defined as a table with one independent variable and MACH is a variable
calculated previously in the program:
cl = CLP(mach)
Accessing as a function
The table can also be accessed within a statement as with any function:
cd(1) = 0.5*CLP(mach)*b*wm(1)/mvm
More than one variable
For a function of more than one variable, the independent variables are all listed
in the call, in the order given in the table:
cl = CLP(mach, al)
Language Reference Manual
119
Breakpoints increase monotonically
All data points for the independent variables (breakpoints) must be of
monotonically increasing order; i.e., values may be identical but a breakpoint
must never be less than a preceding value. Each TABLE statement may contain
as many data points as desired. Once the function has been defined, it may be
referenced just like any other acslX function.
Repeat counts
Repeat counts may be used in the data specification (e.g., 5*6.7 results in 6.7
repeated five times). However, the breakpoints and data points are read into
separate locations by the translator and cannot be specified in the same repeat
count. In the following tables, the first statement is correct but the second results
in a translator error message.
TABLE tab1, 1, 10 / 10*0.0, 10*0.0 /
TABLE tab2, 1, 10 / 20*0.0 /
...Bad break data count....
Examples:
Examples of tables of one, two, and three variables are shown below. The
breakpoints are 2 for F1ARG, 5 for F2ARG, and 9 for F3ARG and the number of
data points are 2, 6, and 24, respectively. The first breakpoint appears first in the
data.
TABLE F1ARG,
TABLE F2ARG,
TABLE F3ARG,
1, 2 / a1, a2, f1, f2
2, 2, 3 / a1, a2, b1,
, f11, f21, f12, f22,
3, 2, 3, 4 &
/ a1, a2, b1, b2, b3,
/
b2, b3 &
f13, f23 /
c1, c2, c3, c4
&
, f111, f211, f121, f221, f131, f231
&
, f112, f212, f122, f222, f132, f232
&
, f113, f213, f123, f223, f133, f233
&
, f114, f214, f124, f224, f134, f234
/
Linear extrapolation and interpolation
If the calculated values of the independent variables lie outside the range
specified by the TABLE statement, the values for the function are obtained by
extrapolating linearly from the last values given. Values between breakpoints in
the table are interpolated linearly.
Language Reference Manual
120
Macro and array defined
The TABLE operator makes up a macro having the same name as the function
so that all references to the TABLE after its definition are caught. An array is also
defined with the same name and enough storage to contain both function data
values and the corresponding argument breakpoint values. This array name is
entered into the dictionary and it may be accessed in by SET, DISPLAY, etc.
runtime commands.
Order of data entry
One point to note is the order of data entry into the array: The function data is
listed first, then the breakpoint values follow. This order is the opposite from that
listed in the TABLE statement since it was considered that the more normal
operation at runtime is changing function values rather than breakpoints. As an
example, consider a pitching moment table as a function of Mach number:
TABLE cm, 1, 5 / 0.0, 0.8, 1.2, 1.5, 2.5 &
, 0.50, 0.51, 0.92, 0.83, 0.15 /
This statement produces an array CM(10) in which the first five elements contain
the function values 0.50, 0.51, 0.92, 0.83, 0.15 and elements six through ten
contain the breakpoint values 0.0, 0.8, 1.2, 1.5, 2.5. To change the function value
at Mach 1.5, the following runtime command can be used at the command
prompt:
CM(4) = 0.65
To change the breakpoint from Mach 1.5 to Mach 1.6, the position in the table is
calculated (5 + 4) and the command becomes:
CM(9) = 1.6
Multidimensional tables
For multidimensional tables, the function data is all listed in the array first, then
the breakpoint data in the order of first, second, third argument.
Function vs. array
The function name followed by parentheses (cm(2.0), for example) on the right
hand side of an equal sign implies a call to look up the function value, while the
table function name without parentheses stands for the array that contains the
function and breakpoint values. The elements of the array cannot be accessed in
the program because parentheses indicate a function call, but the array name
can be passed to a FORTRAN subroutine (or function) to return the value of the
array element. For example, to access the third element of array CM, returned in
array value D, call:
CALL getav(cm, 3, d)
where the subroutine is defined at the end of the acslX program:
Language Reference Manual
121
SUBROUTINE getav(f, n, av)
DIMENSION f(1) av = f(n)
RETURN
END
Reading data into array
Data can be read into a TABLE array, either by calling a subroutine within the
model or at runtime. Set up the table in the model, but fill the data by using a
multiplier; for example:
TABLE k, 1, 10 / 10*0.0, 10*0.0 /
or, if the breakpoints are known and only the data is to be filled in later:
TABLE k, 1, 10 &
/ 0.0, 0.0, 0.2, 0.4, 0.5, 0.6, 0.8, 0.9, 1.0, 1.0
&
, 10*0.0 /
4.96 TAN
Form:
y = TAN(x)
Description:
The output y is the tangent of the real argument x, which must be expressed in
radians.
Example:
TAN could be used as follows:
a = b + TAN(theta)
4.97 TERMINAL
Form:
TERMINAL
...
END
Description:
The TERMINAL keyword identifies the beginning of the block of code performed
at the end of each run. It must be paired with a matching END statement. Code
in the TERMINAL section is not sorted automatically; however, sorting can be
specified with the SORT keyword.
Language Reference Manual
122
To save calculating certain variables over and over again during the simulation
run, the calculations can be placed in the TERMINAL section and executed only
at the end of the run.
Multiple TERMINAL sections
Any number of TERMINAL sections can be used within a program. They may
appear in any other section (INITIAL, DYNAMIC, DERIVATIVE, and DISCRETE)
except PROCEDURAL. This feature is particularly useful in conjunction with
INCLUDE files and/or acslX macros. Modules can be developed in separate files
with their own TERMINAL sections, then brought into a DERIVATIVE section in a
larger program by means of INCLUDE statements.
The translator collects all the TERMINAL sections in the order given. This means
that code introduced in DERIVATIVE or DISCRETE sections appears before
code in the explicit TERMINAL section. If the sections of code need to be in a
particular order (so that a variable is defined before being used, for example),
use the SORT keyword.
4.98 TERMT
Form:
TERMT(logical expression[, `string'])
Description:
A run terminates when the logical expression in the TERMT statement becomes
TRUE. Any number of termination conditions may be specified, and the first
condition to become TRUE terminates the run.
The `string' argument is an option for printing out user information on the
condition that terminates the run. It is considered low volume data and so
appears on the screen as well as in the print file. It is useful to include this
argument even when there is only one stopping condition since it confirms the
run terminating normally.
Example
An example of a typical TERMT statement is:
TERMT((h .LE. 0.0) .OR. (v .LE. vmin) .OR. (T .GE.
tmax))
or, to provide information at runtime on which condition actually terminated the
run:
TERMT(h .LE. 0.0, `Termination on hitting ground')
TERMT(v .LE. vmin, `Termination on flying
backwards')
TERMT(T .GE. tmax, `Termination on TMAX time
limit')
Language Reference Manual
123
Placement in program
TERMT statements can be placed in any of the DYNAMIC, DERIVATIVE, or
DISCRETE sections. A TERMT statement placed in the DYNAMIC section of an
explicit program stops the run at a communication interval. In a DERIVATIVE
section, it stops the run at the integration step following the logical expression
becoming TRUE. In a DISCRETE section, the run stops at the execution
following the expression becoming TRUE.
With SCHEDULE
In some cases, a DISCRETE section is executed solely to terminate the run
when a state event is detected. For example, SCHEDULE finds the state event of
H (height) crossing zero, and a DISCRETE section contains the TERMT
statement:
SCHEDULE stop .XN. h
...
END ! of derivative
DISCRETE stop
TERMT(.TRUE., `Termination on hitting ground')
END ! of discrete stop
This procedure is useful for stopping runs at precise events (see, for example,
the description of stopping missiles at intercept).
Do not at the same time use an additional statement:
TERMT(h .LE. 0.0, `Termination on hitting ground')
For the SCHEDULE operator to work, h must actually cross zero. However, if the
statement above is around, it sets the stop flag, thereby stopping the run before
SCHEDULE has iterated to find the zero crossing. The result is that the run stops
on the other side of the zero crossing rather than precisely on it.
4.99 TRAN
Form:
y = TRAN(nn, nd, qn, qd, x)
TRAN(y = nn, nd, qn, qd, x)
Description:
nn = integer constant or PARAMETER name (may not be a variable name); the
order of the numerator polynomial
nd = integer constant or PARAMETER name (may not be a variable name); the
order of the denominator polynomial
qn = coefficient array for the numerator (can be an expression); may be a real
constant if nn is zero
qd = coefficient array for the denominator
Language Reference Manual
124
x = input; an arithmetic expression of arbitrary complexity
Transfer functions in the form of a ratio of polynomials in the Laplace operator, s,
may be directly implemented by the transfer function simulation operator. The
simple first order transfer functions REALPL and LEDLAG and second order
CMPXPL should be used when possible since the code generated is more
efficient than that for TRAN. TRAN is appropriate for higher order operators.
Order
The transfer function polynomials are in the form of highest power of s coefficient
first and any missing order with its coefficient input as zero. Note that nn+1 and
nd+1 numbers are required in the numerator and denominator arrays since it is
the order that is defined, not the number of coefficients.
NOTE: The order of the denomenator must be greater than or equal to that of the
numerator. If the order of the numerator and the order of the denominator are the
same and there is a feedback path around the operator, an unsortable statement
block may result.
Requirements
All initial conditions are taken as zero, and nn and nd must be literal integer
constants or PARAMETER names, but not variable names. Order can be
changed by arranging for common factors in the numerator and denominator
polynomials. The order cannot be changed artificially by setting the highest
power of the denominator polynomial to zero. QD(1) must be nonzero; otherwise
division by zero results.
Example
In the following example, note that the s1 term has to be filled in as a zero in the
Q (denominator) array. Note also that nn and nd must be entered as the numbers
themselves; variable names are not allowed. For the transfer function:
the model code becomes:
DIMENSION p(2), q(4)
CONSTANT p = 3.0, 2.0, q = 1.0, 2.0, 0.0, 5.0
out = TRAN(1, 3, p, q, in)
Arrays
Variable names as well as literal constants can be used in the arrays. When the
numerator is a single value (zero order), it does not need to be declared in an
array. Some way of calculating the value (constant, array element, assignment
statement, or expression) must be provided, however. For a transfer function in
the following form, for example:
Language Reference Manual
125
only one array is required and the code could be:
DIMENSION d(4)
CONSTANT d = 1.0, 0.0, 0.0, 1.0
z = TRAN(0, 3, k, d, 5*x + COS(th))
Macro implementation
Figure 4-18 Figure 4-18 lists the mechanization of the TRAN operator as a
system macro. This listing is an example of the complexities that can be
implemented using macros.
Figure 4-18: TRAN operator macro
Integration step size
When choosing the integration step size for the model, the reciprocal roots of the
denominator polynomial should be considered.
4.100 TRANZ
Form:
y = TRANZ(nn, nd, qn, qd, x)
TRANZ(y = nn, nd, qn, qd, x)
Language Reference Manual
126
Description:
nn = integer constant or PARAMETER name (may not be a variable name); the
order of the numerator polynomial
nd = integer constant or PARAMETER name (may not be a variable name); the
order of the denominator polynomial
qn = coefficient array for the numerator (can be an expression or real constant if
nn is zero)
qd = coefficient array for the denominator
x = input; an arithmetic expression of arbitrary complexity
Transfer functions in the form of a ratio of polynomials in Z-1 may be directly
implemented in acslX by the TRANZ operator.
Order
The transfer function polynomials are in the form of highest power of Z-1
coefficient first and any missing order with its coefficient input as zero. Note that
nn+1 and nd+1 numbers are required in the numerator and denominator arrays
since it is the order that is defined, not the number of coefficients. Usually the
qd(1) element is unity (1.0).
In the following example, note:
for which the model code becomes:
DIMENSION pn(2), qn(3)
CONSTANT pn = 1, 0.5
CONSTANT qn = 1,-0.166667,-0.166667
out = TRANZ(1, 2, pn, qn, in)
Coefficients If the number of coefficients in the numerator exceeds those in the
denominator, make the denominator order the same as the numerator and fill the
trailing coefficients with zeros. When there are no denominator coefficients, use a
denominator coefficient array with unity in the first element (qn(1) = 1.0) and the
remainder zeros; for example,
DIMENSION pn(4), qn(4)
CONSTANT pn = 1, 2, 3, 4
CONSTANT qn = 1, 0, 0 ,0
out = TRANZ(3, 3, pn, qn, in)
matches:
outn = 1*inn + 2*inn+1 + 3*inn+2 + 4*inn+3
Language Reference Manual
127
but this is probably better implemented using the
HISTORY operator.
Complex filters
For complex Z transform filters, a warning is in order concerning the accuracy of
the calculations. It is very easy to come up with a filter design that doesn't
behave correctly and needs double precision in order to work The TRANZ
statement must be placed inside a DISCRETE section.
4.101 Type
Form:
DIMENSION v1, v2, ..., vn
REAL v1, v2, ..., vn
DOUBLEPRECISION v1, v2, ..., vn
INTEGER v1, v2, ..., vn
LOGICAL v1, v2, ..., vn
CHARACTER v1*n, v2*n, ..., vn*n
Description:
Where the vi are either simple variable names or else subscripted arrays with up
to six integer constant subscripts separated by commas. The variables are typed
and (optionally) dimensioned at the same time. Subscripts must be numerical or
a symbol defined in a previous PARAMETER statement; variable names are not
allowed.
Examples:
INTEGER k, jj(10), fred(2, 2)
LOGICAL flag
CHARACTER mytitle*480
REAL x(5,5), k1
DOUBLEPRECISION vm(3), dot
Variables are considered to be floating point double precision unless typed
otherwise.
LOGICAL
LOGICAL variables can take on values of .TRUE. or .FALSE.
CHARACTER
The length of CHARACTER variables defaults to 1 if not specified.
Language Reference Manual
128
Floating point
Variables are cast as DOUBLEPRECISION by default. The variables can be
forced to single or double precision by explictly declaring them to be REAL
(single precision) or DOUBLEPRECISION.
System symbols
System symbols such as T, CINT, MAXT, and MINT, and also states, derivatives,
and initial conditions, are changed automatically by the acslX system and cannot
be specified their type.
Duplicates permitted
This is useful in graphic models when declared variables are output from acslX
blocks. The variables can be declared in all of the blocks that are wired together,
rather than only in the block that computes the variable. Declarations must match
exactly, or a diagnostic is produced.
Arguments
A potential problem with mixed single and double precision variables in a
program is in their being passed as arguments to subroutines and being returned
from functions. All the acslX subroutines change type automatically, but if any
other routines are used, provision must be made to force the appropriate type.
For example, the DOT product function returns the dot product of two threecomponent vectors. A total velocity magnitude could be obtained by:
REAL vm(3) mvm = SQRT(DOT(vm,vm))
If DOT is written to accept double precision arguments and return a double
precision result, then acslX must type these appropriately rather than relying on
automatic typing unless double precision mode is always used:
DOUBLEPRECISION vm(3), DOT
mvm = SQRT(DOT(vm, vm))
If DOT is single precision, the opposite must be specified; i.e.,
REAL vm(3), DOT
mvm = SQRT(DOT(vm, vm)
The generic SQRT adjusts automatically to the type of its argument and result.
Literal constants
Other problems occur when using literal constants as arguments to subroutines.
For example, quantizing a signal to 0.1 increments could be written, although it is
not good programming practice since the value cannot be changed at runtime.
Language Reference Manual
129
4.102 UNIF
Form:
y = UNIF(bb, tb)
Description:
The output y is a random variable uniformly distributed between a bottom bound
bb and a top bound tb. UNIF could be used as follows:
drive = k*UNIF(dlo, dhi)
This operator is not intended for use in a DERIVATIVE section because the
power density (or, what is usually more important, the low frequency power)
depends on the integration step size. Variable step integration methods can
produce peculiar results. See OU for details on generating noise in a
DERIVATIVE section.
4.103 UNIFI
See GAUSI.
4.104 VARIABLE
Form:
VARIABLE name [, ic name [= floating point
constant]]
Description:
The default independent variable is called T. It has an initial value of 0.0 and the
initial condition name is not accessible. Using the VARIABLE statement allows
you to designate the independent variable with a nonsubscripted name; the initial
condition name is then also accessible. The value for the initial condition cannot
be a name. If the variable name T is to be used for temperature, for example, the
independent variable could be called TIME and be given a negative initial
condition as follows:
VARIABLE time, timeic=-5.0
4.105 XERROR
See MERROR.
Language Reference Manual
130
Chapter 5
Macro Language
5.1 Introduction
Macros are useful for standardizing certain functions for an industry or discipline.
Macros can also be used to capture special expertise for other users to
incorporate into their programs.
acslX's language can be expanded using the macro capability to define new
operators. These operators are called from the program, usually with arguments.
From the macro directives, the translator generates the code (often referred to as
macro expansion) for compilation. Code is generated each time the macro is
called. Usually the code is slightly different with each call (because of arguments
resulting in different variable names, for example).
5.1.1
Macro versus subroutine
A macro is similar to a subroutine or function in FORTRAN or procedure or
function in C/C++ because it is defined once and then can be invoked as many
times and from as many places in the model code as needed. The translator
produces a set of statements in the target language compile file for each macro
invocation, but the extra storage used for such statements is usually small.
Macros are slightly more efficient and have the advantage of being able to define
operators involving integrators and memory functions.
Macros are used instead of target language subroutines:
•
•
•
5.1.2
if any acslX operators are involved
to gain visibility of internal variables
for concatenation to generate unique variables for each application of a
macro and the new variable values are used for printing and plotting.
Macro definitions
Macros can be defined:
•
•
in the program in which they are called, before the first invocation.
in a separate program containing only the macros. The program concludes
with a SAVE statement (see the SAVE command in Chapter 4) that saves
the macros to the current macro file.
In general, make a local copy of the system macro file and specify this local copy
as the macro file for the program to save macro definitions. On some systems,
this file must be given WRITE permission. The macro definitions are added to the
file (i.e., they are cumulative), so generally it is best to start with a fresh copy of
the system macro file. Only translation is required, so stop the acslX build
procedure before compilation.
Language Reference Manual
131
5.1.3
Features
Some of the more important features of the macro language are:
•
•
•
•
•
•
5.1.4
Variables and statement labels may be locally generated. This prevents
variables or labels being defined multiple times if the macro is called more
than once.
The number of macro input arguments is not limited. These arguments must
be valid expressions (of arbitrary complexity) with balanced parentheses
and any character string enclosed in quotation marks.
Macro definitions may invoke other macros to an unlimited level of
complexity. However, macro definitions may not be nested because nesting
would require a count of the nesting level within the definition to match up
with the correct MACRO END. Such a count is not performed and the first
MACRO END terminates the definition.
Macros may be placed anywhere within an acslX program, but they must be
defined before they are used. A macro may be redefined; the most recent
version is used in the expansion.
The concatenation operator (#) allows arguments to be placed together
without intervening spaces, a useful way of making up variable names.
Macro definitions can include INITIAL and/or TERMINAL sections.
Forms of call
Macros can be called in three ways. The second form, called standalone, is
generally preferred because it clearly identifies the usage of MACRO. This
makes the statement distinct from subroutine, procedures, and functions.
Subroutines or procedures must be invoked using the CALL statement. Function
calls return one value and are always in the form of y = func(a,b,c),. The third
form must be used with more than one output.
y = MAC(x)
MAC(y = x)
MAC(y,z = x)
5.1.5
Concatenation
The ampersand (#) is the concatenation operator that allows a substitutable
argument to appear next to a character string. Its use is discussed in more detail
under Macro Definition Header. In general, it enables generation of unique
names with multiple calls to a macro. For example, variable V1 is accessed in the
following expansion:
MACRO abc(x)
y = v#x#
MACRO END
abc(1)
...
y = v1
Language Reference Manual
132
The substituted name must be separated from any other characters by either a
space or an ampersand. No substitution would take place in the following
situation:
MACRO abc(x)
y = v#xgh
MACRO END
An additional ampersand after the x, however, sets it off so it can be substituted:
MACRO abc(x)
y = v#x#gh
MACRO END
abc(2)
...
y = v2gh
5.1.6
INITIAL, DYNAMIC, DISCRETE, and TERMINAL sections
INITIAL, DYNAMIC, DISCRETE, and TERMINAL sections can be used in macro
definitions. The translator collects all the code in the order presented (or
expanded in the case of macros). These sections are not sorted unless the
SORT keyword is specified. Argument strings are substituted for each
appearance of the macro argument name. If the argument is an expression, care
must be taken that the resulting code is correct after the substitution (see the
section on macro calls). Other names that may be substituted during macro
expansion are the ASSIGN variable (see MACRO ASSIGN), local variable
names identified by a REDEFINE (see MACRO REDEFINE), and local labels
identified by a RELABEL (see MACRO RELABEL).
5.1.7
Macro definitions
The macro definition is a block of code that consists of:
1) Macro definition header
2) Macro directive or acslX statements
3) MACRO END
The macro definition header specifies the name of the current definition and a list
of dummy reference parameters, analogous to dummy arguments in a target
language subroutine. The translator scans the statements in the macro body for
the appearance of these names, flagging them for substitution by the actual
argument supplied on invocation. The definition terminator, MACRO END, must
be present to flag the translator to return to direct translation. The translated
macro body with arguments substituted is referred to as the skeleton.
If a macro name is the same as one already defined, either in the system macro
file or the current model definition, the new macro definition replaces the old one.
No error message is issued since this is considered to be a feature whereby you
can always override an old macro definition.
Language Reference Manual
133
5.1.8
Macro definition header
There are two types of macros that can be defined. The first is preferred for most
applications send and accept variable names as arguments. The second is
useful for handling arrays and can be identified by headers starting MACRO
MACRO.
Form:
MACRO identifier(x1, x2, ..., xn)
MACRO MACRO identifier(p, q, r, s)
Description:
identifier = macro name
xi = variable names, constants, or expressions
p = primary argument specifying an array of input expressions
q, r, and s = secondary arguments giving the names of array dimensions
within the macro definition.
Arguments p, q, r, and s may be any unsubscripted variable name.
NOTE: If p is the name of the argument of a MACRO MACRO, then a variable
named p must not be used in the macro.
5.1.9
First form
The first macro form is preferred for most purposes. Anywhere the string of
characters xi is referred to in the macro definition, it will be replaced by the ith
argument (symbol or expression) when the macro is invoked; e.g.,
MACRO mult(x, y, z)
x = y*z
MACRO END
c = a*mult(5.0*b, d)
! definition
! invocation
In this example, the output of the function is the first argument x; but x does not
appear explicitly in the invocation. y is replaced by 5.0*B and z by d everywhere
throughout the definition.
5.1.10
Second form
The second macro form is useful when handling arrays of indefinite size. This
form has an extra MACRO in the header.
The argument p is the dummy reference parameter and may be thought of as a
vector, each element of which identifies the respective element in the argument
list at invocation time. You specify only p in the invocation. The secondary
arguments q, r, and s appear, if needed, in the definition header and may be
used in the macro definition, but do not appear in the invocation argument list.
Elements of p that are acslX arrays must be dimensioned prior to the macro
Language Reference Manual
134
invocation. Arguments q, r, and s may also be thought of as arrays, but only
those elements corresponding to arrays in the p array contain values. They refer
to the first, second, and third dimensions, respectively.
MACRO MACRO head(p, q, r, s)
... definition statements ...
MACRO END
DIMENSION b(9), g(2, 3), h(4, 4, 2)
head(a, b = 5*d, e+f, g, h, low)
! definition
! invocation
Arguments at invocation time are delimited by either commas or an equal sign.
Thus, in this example, p(1) appearing in the definition body is substituted by the
symbol a, the first argument, at invocation time. p(4) is replaced by the
expression e+f, the fourth argument.
Any reference to q for an array accesses the first dimension. In the example
above, q(2) has the value 9 from the dimension of b in the previous DIMENSION
statement, but p(1), p(3), p(4), and p(7) are not dimensioned arrays, so q(1),
q(3), q(4), and q(7) are scalar have a dimension of one.
Symbols substituted for the secondary arguments r and s act similarly to q except
they provide the second and third dimensions respectively; for example, r(5) is 3
and s(6) is 2.
Note that macros written in this second form are very hard to read since no
mnemonic symbols can be used for the arguments. The array expressions are
restricted to the following forms:
1) P(i) where i is a literal integer constant
2) P(n) where n is the ASSIGNed variable
3) P(n±i), combination of the above.
5.1.11
Substitutable symbols
In general, the substitutable symbols must be separated from other character
strings by non alphanumeric characters (i.e., *, +, -, blank) or the concatenation
symbol (#) in order for the scan to operate. If the above macro MULT contained
the statement:
ASSIGNz TO k
the symbol z would not be identified for substitution. Here the space is all
important, so the correct form is the following:
ASSIGN z TO k
5.1.12
Concatenation
The concatenation operator is the ampersand (#). It is used to allow a
substitutable argument to appear next to a character string. It serves as a
separator for symbol identification, but is removed when the macro is translated
into the skeleton. The following example, shows how to generate unique symbols
Language Reference Manual
135
by adding an F to the third argument of the MULT macro and including it in an
expression. The new name would be written F#Z (F concatenated with Z); i.e.,
X = Y*F#Z#
Invoking the MULT macro with:
a = mult(sam, joe)
results in the statement:
A = SAM*FJOE
where the new symbol FJOE has been defined. The above call MULT enters a
symbol JOE on the symbol table. If only the made up symbols are important, the
argument may be quoted using double quotes as:
a = mult(sam, "joe")
In this case, the same expression is generated but now the symbol JOE is not be
entered in the symbol table. The argument in double quotes has the quotes
removed and the literal string of characters (including any blanks) is substituted
for the appropriate argument symbol.
5.1.13
Macro directive statements
This section lists alphabetically the macro directive statements that may be
included within a macro definition. These statements do not produce code, but
can be used to provide extremely flexible control of the macro processing at
invocation time. The acslX statements themselves produce code, and symbols in
the statements are substituted for the appropriate argument at invocation time.
All these directive statements begin with the word MACRO to indicate that they
are instructions to the macro processor.
5.1.14
Labels
All macro directive statements can have labels attached to them; the labels can
be used by MACRO GO TO and MACRO IF directives. These labels must be
distinct from any labels attached to non directive statements. The label is
inserted after the leading MACRO of the directive; e.g.,
MACRO s1: RELABEL i
MACRO s2: CONTINUE
MACRO s3: END
NOTE: These labels control the sequence of the macro processor at macro
invocation time. The labels on non directive statements control the sequence at
runtime execution.
Language Reference Manual
136
5.1.15
MACRO ASSIGN
Form:
MACRO ASSIGN n
Description:
Where n is a symbol (usually N is used). The ASSIGN directive assigns the
number of arguments in the macro call to the variable N; N is always an integer.
If the dummy reference parameter contains a variable subscript, the variable
must be the same as the variable used in the ASSIGN statement. Whenever N is
used as part of the dummy reference parameter subscript, the current value of N
refers to the Nth argument in the macro call list at invocation time.
Example:
Using the second header type:
MACRO MACRO sam(P) ! definition
MACRO ASSIGN n
... MACRO END
sam(x, y, z) ! invocation
Within the macro definition, N is 3 since the invocation to SAM contains three
arguments, and therefore:
p(n) = Nth argument, which is z
p(1)(N) = x(3)
p(n-1)(N) = Nth element of the (n-1) argument;
i.e., y(3)
5.1.16
Arithmetic macro directives
Form:
MACRO
MACRO
MACRO
MACRO
INCREMENT i
DECREMENT i
MULTIPLY i
DIVIDE i
Description:
Where i is an unsigned integer constant, the secondary arguments (p, q, r, s) of
the second type of macro, or a macro argument name that has a literal numeric
integer value.
These directives provide arithmetic operations on the ASSIGN variable N. The
value of N may be added to, subtracted from, multiplied, or divided. All arithmetic
operations are performed in fixed point integer.
Language Reference Manual
137
Example:
MULTIPLY 0 makes the ASSIGN variable zero. To make the ASSIGN variable
equal to the dimension of the second argument, the following code can be used:
MACRO
MACRO
MACRO
MACRO
MACRO
MACRO
MACRO
MACRO bil(p, q)
ASSIGN n
MULTIPLY 0
s1: IF(n = q(2)) s2
INCREMENT 1
GO TO s1
s2: CONTINUE
On exit from this section, N (the assigned variable) has the integer value Q(2),
the dimension of the second argument. In this way N can be used as a counter or
control variable in addition to its basic purpose of transmitting the number of
arguments from the invocation.
5.1.17
MACRO CONTINUE
Form:
MACRO CONTINUE
Description:
This macro directive is included so that it can be labeled, as, for example,
MACRO L1: CONTINUE
The MACRO IF or MACRO GO TO can then branch to this section within the
definition.
5.1.18
MACRO DECREMENT
See Arithmetic macro directives.
5.1.19
MACRO DIVIDE
See Arithmetic macro directives.
5.1.20
MACRO EXIT
Form:
MACRO EXIT
Description:
The EXIT directive statement stops the generation of code at invocation time.
The action is the same as using a MACRO GO TO that transfers control to the
macro definition terminator (MACRO END). MACRO EXIT in a PROCEDURAL
Language Reference Manual
138
block can result in translator errors because the END statement will be missing
from the PROCEDURAL block.
5.1.21
MACRO GO TO
Form:
MACRO GO TO s
Description:
Where s is a statement label attached to another MACRO directive. The GO TO
provides an unconditional branch to a labeled macro directive within the
definition.
5.1.22
MACRO IF
Form:
MACRO IF(e1 = e2) s
Description:
Where s is a macro directive statement label and e1 and e2 can be the dummy
reference parameters corresponding to the call list, integer constants, character
strings, or the identifier used in the ASSIGN directive. They must not be
expressions. The IF directive provides for a conditional branch to the macro
directive label s inside the current definition if the relation e1 = e2 holds. The
strings e1 and e2 are tested character by character (excluding blanks) for
equality. In order to compare a character string with a string passed as a macro
argument, the string must be enclosed in quotes when the macro is invoked and
then the MACRO IF compares the argument with an un-quote string; i.e., if the
definition is as follows:
MACRO
MACRO
...
MACRO
MACRO
test(arg)
IF(arg = top) LAB1
LAB1: CONTINUE
END
and the invocation is:
test("top")
then the macro will expand via LAB1.
5.1.23
MACRO INCREMENT
See Arithmetic macro directives.
Language Reference Manual
139
5.1.24
MACRO MULTIPLY
See Arithmetic macro directives.
5.1.25
MACRO PRINT
Form:
MACRO PRINT
any character string except $
or ;
Description:
Error messages may be handled within the macro at invocation time by this
PRINT directive statement using any a string of any characters except the dollar
sign ($) or semicolon-colon (;). This directive lists the character string on the
output device. It will override any global list control. The primary use is for you to
diagnose your own errors at invocation time and print out informative messages.
The messages appear with the word "WARNING" at the beginning for easier
locating.
5.1.26
MACRO REDEFINE
Form:
MACRO REDEFINE v1, v2, ..., vn
Description:
Where vi are variable names appearing in the body of the macro. REDEFINE
identifies the variables as being locally defined and specifies that they are to be
replaced by unique symbols at each invocation. The generated variables consist
of the letter Z followed by five digits. The MACRO REDEFINE statement should
appear before any statements which reference the redefined variables, including
type declarations.
5.1.27
MACRO RELABEL
Form:
MACRO RELABEL 11, 12, ..., 1n
Description:
Where li is an alphanumeric label (i.e., starts with a letter although it may contain
numbers after the first character). RELABEL specifies that all symbols in the list
are locally defined statement labels which are to be substituted by unique
generated labels at invocation time. These labels must be attached only to acslX
Language Reference Manual
140
statements, not macro directive statements (statements beginning with the word
MACRO).
The following RELABEL statement is illegal because the label name begins with
a number:
MACRO RELABEL 110
It could be replaced by the following statement:
MACRO RELABEL L110
To relabel within a macro loop, call another macro from within the loop. For
example:
MACRO MACRO test(p)
MACRO ASSIGN n
...
MACRO L1: CONTINUE
MACRO IF(n=5) L99
mac2(p(n))
MACRO DECREMENT 1
MACRO GO TO L1
MACRO L99: CONTINUE...
MACRO mac2(arg)
MACRO RELABEL xyz
MACRO REDEFINE k
DO xyz k=1,25
... statements that use arg
xyz: CONTINUE
MACRO END
5.1.28
MACRO STANDVAL
Form:
MACRO STANDVAL arg1 = c1, arg2 = c2 ...
MACRO STANDVAL P(i) = c1, P(j) = c2, ...
Description:
Where argi are dummy argument names and ci are literal constants that can be
real (single or double precision), integer, or logical. In the second form, i and j are
unsigned integer constants. The STANDVAL statement is used to provide
standard values for arguments of a macro. If the specified argument is not given
in the macro call, then the constant is used in its place.
Omitted arguments
If arguments can be omitted from an argument list, they must be at the end of the
list.
Language Reference Manual
141
Placement
The STANDVAL directive must immediately follow the macro header in the
definition if it is used at all.
Example:
Several of the acslX operators use this statement. The operator for the second
order transfer function (complex pole), for example, begins as follows:
MACRO cmpxpl(y, p, q, x, ic1, ic2)
MACRO STANDVAL ic1=0.0, ic2=0.0
...
A call to this operator in the model source code then need not specify the two
initial conditions if they are to be zero:
CMPXPL(y = t1, t2, yp)
5.2 Macro examples
The following examples of macro calls demonstrate some of the uses of the
directive statements and direct parameter substitution.
5.2.1
Sampler
A sampler can be created with a switch and two zero order holds. For
convenience, the entire sequence can be embedded in a macro and invoked as
a function. The invocation could be:
sample(y = dl, x, yic)
When the sampler is repeated for every DL of the independent variable, x is the
variable to be sampled, and YIC is the initial value of Y. A macro to handle this
could be defined as follows:
MACRO sample(samp, dl, x, ic)
MACRO REDEFINE d, dt
INITIAL
samp = ic
END
DISCRETE d
INTERVAL dt=0.0
dt = dl
samp = x
END
MACRO END
Note that the output name must always be included in the argument list. (This
requirement for macros is distinguished from target language functions, where
the single result is returned into the name of the function.) At the sample time,
the DISCRETE section is executed. This action saves the input value x as output
value SAMP, which is substituted with the appropriate name from the macro
invocation.
Language Reference Manual
142
5.2.2
Dot product
The following call could be used to take the vector dot product of two arrays a
and b:
x = DOT(a, b)
where x is a scalar and a and b are vectors previously dimensioned in a
DIMENSION statement. Since it is a function and thus has one output, the
operator can be embedded in an arithmetic expression of arbitrary complexity.
The dimension of the vectors may change, so it should not be specified in the
call.
5.2.3
Second type
The second form of the macro header is required in
order to handle the array dimension. See MACRO
MACRO dot(p, q)
MACRO RELABEL loop
MACRO REDEFINE loop
MACRO IF(q(2) = q(3)) mll
MACRO PRINT Conflicting dimensions in dot product
MACRO EXIT
MACRO mll:COONTINUE
PROCEDURAL(p(1) = p(2), p(3))
p(1) = 0.0
DO loop I = 1,q(2)
p(1) = p(1)(i)*p(3)(i)
loop: continue
END ! of procedural
MACRO END
!Invocation of dot macro
DIMENSION y(10), z(10)
dot(x = y, z)
Figure 5-1 for a listing of a DOT macro. The header designates P as the primary
variable and Q as the secondary variable; Q accesses the dimension of the
corresponding primary argument.
5.2.4
REDEFINE
The REDEFINE statement ensures the variable I will not conflict with any other
use. If this were omitted, a program variable I could have its value changed when
the macro is executed, a potentially disastrous effect.
5.2.5
Dimensions
The test of Q(2) and Q(3) is needed to see if the second and third arguments
have the same dimension; if not, the DOT product is undefined and a macro error
Language Reference Manual
143
message is printed. If the dimensions are correct, the DO loop summation is
formed. Note that Q(2) and Q(3) are replaced at invocation time (as distinct from
execution time) by integers corresponding to the array size of the respective
arguments.
5.2.6
MACRO IF
The MACRO IF must branch to another macro directive statement, hence the
label is attached to a MACRO CONTINUE. This label can not be attached to the
following statement since it is not a macro directive statement but an assignment
statement.
5.2.7
Expansion
At invocation time, the variable I is changed into
a unique translator-generated variable (Z99999).
The call shown in MACRO MACRO dot(p, q)
MACRO RELABEL loop
MACRO REDEFINE loop
MACRO IF(q(2) = q(3)) mll
MACRO PRINT Conflicting dimensions in dot product
MACRO EXIT
MACRO mll:COONTINUE
PROCEDURAL(p(1) = p(2), p(3))
p(1) = 0.0
DO loop I = 1,q(2)
p(1) = p(1)(i)*p(3)(i)
loop: continue
END ! of procedural
MACRO END
!Invocation of dot macro
DIMENSION y(10), z(10)
dot(x = y, z)
Figure 5-1 results in the macro being translated into the following code:
INTEGER Z99999
X = 0.0
DO 99999 Z99999 = 1, 10
99999: X = X + Y(Z99999)*Z(Z99999)
If the call to DOT is embedded functionally in an expression, this code precedes
the expression evaluation and a translator-generated variable in the form Znnnnn
is used in the expression for the output variable name.
MACRO
MACRO
MACRO
MACRO
MACRO
MACRO
Language Reference Manual
MACRO dot(p, q)
RELABEL loop
REDEFINE loop
IF(q(2) = q(3)) mll
PRINT Conflicting dimensions in dot product
EXIT
144
MACRO mll:COONTINUE
PROCEDURAL(p(1) = p(2), p(3))
p(1) = 0.0
DO loop I = 1,q(2)
p(1) = p(1)(i)*p(3)(i)
loop: continue
END ! of procedural
MACRO END
!Invocation of dot macro
DIMENSION y(10), z(10)
dot(x = y, z)
Figure 5-1: DOT product macro and invocation
5.2.8
Pressure tank
This pressure tank example illustrates the use of concatenation in macros. A
similar example (physiological benchmark PHYSBE) appears in Appendix A.
5.2.9
Concatenation
One of the problems with using macros is the tendency to generate large
numbers of dummy variables (Znnnnn) which have no mnemonic meaning. All
REDEFINEd variables have this form. An alternate approach is to use the
concatenation feature to build unique symbols that are available for plotting or
printing. This technique can also reduce considerably the length of the argument
list; using a long argument list is the other alternative when unique symbolic
names are required.
5.2.10
Definition
In this example, a macro is defined for a gas holding tank. The flow into the tank
is calculated as the difference in pressure divided by a resistance. Total pressure
is the integrated net flow divided by a volume. The macro definition is thus:
MACRO tank(n)
f#n#i = (p#n#i - p#n#)/r#n#i
p#n# = (INTEG((f#n#i – f#n#o)/v#n#, p#n#ic)
MACRO END
5.2.11
Invocation
The basic equations for different vessels (tank 1 and tank 3, for example) can
now be established in the model by the statements:
tank(1) tank(3)
5.2.12
Expansion
The invocation TANK(3), for example, generates the following translated code:
Language Reference Manual
145
F3I = (P3I - P3)/R3I P3 = INTEG((F3I - F30)/V3,
P3IC)
5.2.13
Constants and variables
Constants must be defined elsewhere for the resistance R3I, the volume V3, and
initial pressure P3IC. Variables which must be defined elsewhere are the input
pressure node P3I and the output flow F3O. This macro then makes available to
other sections of the simulation the input flow F3I and tank pressure P3.
5.2.14
Alternative form
An alternative form of the macro invocation without the concatenation feature
would have to be a separate statement such as the following for each tank in the
system:
tank(f3i, p3 = p3i, r3i, f3o, v3, p3ic)
5.2.15
Advantages of concatenation
The trade-off in deciding how to define the macro can be stated generally as
follows: Without the concatenation feature, argument lists become long and
complicated, but argument lists have the advantage of flexibility in naming; in
addition, arguments can be expressions. Using the concatenation feature, the
argument list is simple: one argument (usually a literal constant, but can an
alphanumeric variable name). An alternative TANK macro could have the output
flow and downstream pressure specified in the argument list since these are
likely to be expressions; e.g.,
MACRO tank(n, pi, fo)
f#n#i = (pi – p#n#)/r#n#i
p#n# = INTEG((f#n#i - (fo))/v#n#, p#n#ic)
MACRO END
The invocation of this macro could, for example, substitute a variable name for
inlet pressure PI and an expression for the outlet flow FO, as follows:
tank(1, psource, (p1 - p5)/r51)
The disadvantage of the concatenation approach is the inflexibility in naming
convention, but if you have control of the model design, you can use this to
advantage.
5.2.16
Matrix operations
Matrix operations such as addition, multiplication, negation, and transposition can
be defined by macros. Macros for these four operations are listed in Figure 5-2
through Figure 5-5 and the macro for matrix multiply (MMUL) is discussed in
detail.
Language Reference Manual
146
Note that matrix operations are usually characterized by an n-cubed operation
count and can be expensive for large matrices.
Figure 5-2: Matrix multiply macro
5.2.17
Matrix multiply macro
The MMUL operator (listed in Figure 5-2) uses the second type of macro
definition header, in which array dimensions Q and R are used in the definition
and are picked up automatically by the operator provided they have been defined
prior to the macro call. The arrays must be dimensioned before the macro call
because the acslX translator makes only one pass over the input source code to
generate text; the second pass is a sorting operation.
5.2.18
Dimensions
All matrices must be doubly dimensioned. Single dimension vectors may be
dimensioned either (1, n) for row vectors or (n, 1) for column vectors. Only
matrices input to the macro must be dimensioned. Output matrices have their
dimensions calculated and defined appropriately. In the following example, input
matrices a and b are dimensioned in a DIMENSION statement; x, which is input
in the third line, has been dimensioned because it is the output from the macro in
the previous line. Reversing the order of the calls for x and y would not work.
DIMENSION a(3, 2), b(2, 3)
MMUL(x = a, b)
MMUL(y = x, a)
5.2.19
Invocation
The calling sequence for MMUL is defined as follows:
MMUL(C = A, B)
Language Reference Manual
147
which performs the matrix multiplication expressed mathematically as:
[C] = [A][B]
The macro definition includes a test that the row dimension of [A] is equal to the
column dimension of [C]; if not, a message is written out to you.
Figure 5-3: Matrix add macro
Language Reference Manual
148
Three matrices can be multiplied together with a call such as:
MMUL(y = a, MMUL(b, c))
which can be expressed mathematically, in the given order:
Y = [A][B][C]
Figure 5-4: Matrix negate macro
Figure 5-5: Matrix transpose macro
5.3 Macro invocation
Once a macro has been defined, it must be invoked with specific arguments
listed for substitution.
5.3.1
Single output
One form of call is to embed the macro name in an arithmetic expression. For
this form, only one output (a single number) should be produced by the macro.
An example of this form is:
x = 5.0*SIN(DOT(a, b)/4.0)
where the DOT product macro is embedded in the argument of the SIN function.
a and b in this case correspond to the second and third argument of the macro,
respectively; the output is the (understood) first argument.
Language Reference Manual
149
5.3.2
Standalone forms
An alternative form of the call is as a standalone statement, which has two forms
as follows:
DOT(x = a, b)
DOT(x, a, b)
The equal sign in the first form is to indicate to the reader that x is an output. The
program determines the actual inputs and outputs as it processes the statements
produced by the macro; i.e., no error would result if the operator were invoked as
follows:
DOT(x, a = b)
but it would be misleading to the user. Note especially that
x = DOT(a, b)
is an assignment statement and the name x is not substituted for the first
argument. Only a single numerical value can be passed across the equal sign of
an assignment statement.
On the other hand, consider a matrix integration operator which might be invoked
as follows:
matint(x, xd = a, xic)
In this call, two entire vectors are the output of the operator and have their values
effectively passed across the equal sign. Passing more than one value across an
equal sign is possible only in macro and subroutine calls.
5.3.3
Argument substitution
The substitution of macro arguments is by replacement of the character string
forming the argument with the substitutable name. Where expressions are used,
the wrong answer can be obtained if parentheses are not placed around the
argument. For example, consider a macro to integrate a difference in flow rate as
follows:
MACRO accum(tot, w1, w2, ic)
tot = INTEG(w1 - w2, ic)
MACRO END
At invocation, an expression for net flow out becomes:
accum(mass = win, wp1 + wp2, massic)
which produces the line of code:
MASS = INTEG(WIN - WP1 + WP2, MASSIC)
5.3.4
Use of parentheses
This result is not exactly right, since the second flow WP2 has been made
positive. The solution, when the operator precedence can cause a problem, is to
Language Reference Manual
150
surround the substitutable name with parentheses. The macro above should
have been defined as follows:
MACRO accum(tot, w1, w2, ic)
tot = INTEG(w1 - (w2), ic)
MACRO END
Now at substitution the executed statement is:
MASS = INTEG(WIN - (WP1 + WP2), MASSIC)
It is not necessary to enclose the first parameter, W1, in parentheses since any
expression substitution gives the correct answer. Trouble usually arises when
arguments are negated, multiplied, divided by other variables, or used as a
divisor in the macro division.
Language Reference Manual
151
Chapter 6
Standard Block Libraries
The Block Library window contains libraries. When opened, each library contains
related building blocks that can be used to build simulation models in the Block
Diagram Window. Each library and the related building blocks are described in
this section. Custom libraries can be created, to customize the workspace for
specific applications.
Figure 6-1: Block Libraries Window
Language Reference Manual
152
6.1 Boolean
The Boolean library provides the blocks for logical operations.
AND
Returns a logical value of the logical AND of the two inputs i1 and i2.
Y = i1 .and. i2
EQ
(==)
Returns a logical value when the first input is equal to the second
input. Testing for equality between two real numbers can be a
problem.
Y = i1 .eq. i2
GE(>=)
Returns a logical value of whether the first input i1 is greater than, or
equal to, the second input i2.
Y = i1 .ge. i2
GT (>)
Returns a logical value of whether the first input i1 is greater than the
second input i2.
Y = i1 .gt. i2
LE (<=) Returns a logical value of whether the first input i1 is less than, or
equal to, the second input i2.
Y = i1 .le. i2
LT (<)
Returns a logical value of whether the first input i1 is less than the
second input i2.
Y = i1 .lt. i2
NE (!=)
Returns a logical value of whether the first input i1 is not equal to the
second input i2.
Y = i1 .ne. i2
NOT
Returns a logical value of the logical negation of the two inputs, i1
and i2.
Y = i1 .not. i2
OR
Returns a logical value which is the logical OR of the two inputs i1
and i2.
Y = i1 .or. i2
Language Reference Manual
153
XOR
Returns a logical value which is the logical exclusive OR of the two
inputs i1 and i2.
Y = i1 .xor. i2
6.2 Controls Operations
The Control library contains various PI controller PowerBlocks.
PI
Constant K = 1.0
Constant Tau = 1.0
Constant Ic = 0.0
Y = K*(X + INTEG(X/Tau, Ic)).
PID
Constant K
= 1.0
Constant TI = 1.0
Constant TF = 1.0
Constant TD = 1.0
Constant Ic1= 0.0
Constant Ic2= 0.0
!-----Proportional, Integral,
Differential Controller
Y = K*(X + INTEG(X/TI, Ic1) + TD*Xd)
!-----Estimated X dot
Xd
PIV
= (X - INTEG(Xd, Ic2))/TF
Constant VMax = 1.0
Constant Rfb
= 1.0
Constant Rin
= 1.0
Constant C
= 1.0
Constant Ic
= 0.0
Y = BOUND(-VMax, VMax, Rfb*X/Rin + V)
V = INTEG((Y - V)/(Rfb*C), Ic)
Language Reference Manual
154
6.3 Filters Operations
Complex
The Complex Pole Transfer is represented by the Laplace
Pole Transfer transform:
Function
1/(p*s**2 + q*s + 1)
(cmpxpl)
constant p = 1.0
constant q = 1.0
constant ic1 = 0.0
constant ic2 = 0.0
o1 = cmpxpl(p, q, i1, ic1, ic2)
Single Step
Delay
(delayd)
This function acts as a single step delay upon an input signal.
For vectors and matrices, it is an element by element
operation. For example:
y1/u1 = z^(-1)
where z is the Z transform delay operator. u2 is the initial
value of the state and output. u2 is optional; if not provided,
the initial value will be zero (FALSE).
INPUTS: u1, u2 = any matching types
OUTPUT: y1 = same type as u1
y1 =
Fixed Rate
Integration
(integ)
delayd(u1 [, u2])
This function performs fixed rate integration on an input signal.
For vectors and matrices, it is an element by element
operation. u1 is the signal being integrated and u2 defines the
initial value of the state of the operator. u2 is optional; if the
port is deleted, the initial value is zero. This operator has a
source-sink decomposition which may prove useful when
resolving feedback loops.
INPUTS: u1, u2 = floats with the same dimensions
OUTPUT: y1 = same type and dimensions as u1
y1 = integ(u1, u2)
Resetable
Fixed Rate
Integration
(integr)
Language Reference Manual
This function performs fixed rate, resetable integration on an
input signal. For vectors and matrices, it is an element by
element operation. u1 is the signal being integrated and u2
defines the initial value of the state of the operator. u3 should
be set to true to reset the state and output of the integrator.
The u4 input is optional; if provided, the state and output are
reset to the value of the input u4. If not provided, the state and
155
output are reset to the value of u2.
INPUTS: u1, u2, u4 = floats of the same dimensions
u3 = logical
OUTPUT: y1 = same type and dimensions as u1
y1 = integr(u1, u2, u3 [, u4])
Lead Lag
constant ic = 0.0
constant P = 1.0
constant Q = 1.0
o1 = ledlag(P, Q, i1, ic)
Real Pole
Transfer
constant ic = 0.0
constant P = 1.0
o1 = realpl(P, i1, ic)
Continuous
State Space
Filter
Discrete
Space Filter
Transfer (S)
Transfer
(Ratio)
Transfer (Z)
Language Reference Manual
156
6.4 Linear Operations
Complex pole
(cmpxpl)
Output o1 is the second order transfer function (complex
pole) of input i1 with initial conditions ic1 and ic2. Arguments
p and q are time constants for the first and second
expressions in the denominator.
o1 = cmpxpl (p, q, i1, ic1,
ic2)
Delay
(delay)
Output o1 is the transport delay of input i1 with initial
condition ic, delay
time tdl, workspace nmx (a literal integer), and (optional)
minimum interval in buffer delmin.
o1 = delay (i, ic, tdl, nmx,
delmin)
Gain
Output o1 is input i1 multiplied by a gain k.
constant k = 1
o1 = k * I1
Inverse Gain
Inverse gain, multiplies the input i1 by reciprocal gain.
constant k = 1.0
o1 = i1/k
Implicit
(implc)
Output z is adjusted to drive the input residual r to zero with
first guess zic.
constant zic = 0.0
z = implc (r, zic)
Implicit Scalar
Integration
(impvc)
Implicit scalar integrator operator adjusts an output variable to
drive a residual to zero, as part of an implicit or algebraic
loop, a loop without an integrator.
z - a simple variable
r - an arithmetic expression of arbitrary complexity
zic - a real constant.
z = impvc (r, zic)
Language Reference Manual
157
Integrator
(integ)
Output state o1 is the integration of input derivative i1 with
initial condition ic.
constant ic = 0.0
o1 = integ (i1, ic)
Lead Lag
(ledlag)
Output o1 is the lead-lag compensation of input i1 with initial
condition ic and time constants t1 (numerator) and t2
(denominator).
constant ic = 0.0
constant t1 = 1.0
constant t2 = 1.0
o1 = ledlag (t1, t2, i1, ic).
Real Pole
(realpl)
The REALPL operator produces a first order lag where output
o1 is related to input i1 through the transfer function:
o1
1
-- = ------ where o1(0) = ic
i1
Summation
Transfer
function (tran)
ps + 1
Adds an unlimited number of inputs to produce output o. The
default sign for input ports is positive (+). The Port Info dialog
box lets you specify that a port should be negative (-).
Transfer functions in the form of a ratio of polynomials in the
Laplace operator, may be directly implemented in acslX by
the transfer function simulation operator.
The simple first order transfer functions REALPL and
LEDLAG and second order CMPXPL should be used when
possible since the code generated is more efficient than that
for TRAN. TRAN is appropriate for higher order operators.
NOTE: to change the dimension of num or den:
•
Make local copy (check Embed Code box in the
Block Details dialog box)
•
Double-click on block; edit code for dimensions
and constants. Save.
•
Right-click for menu, choose Constants; click on
Reset all constants to GSL values.
dimension num(10), den(10)
Language Reference Manual
158
constant num = 10*1
constant den = 10*1
o1 = TRAN(1, 1, num, den, i1)
6.5 Math Operations
Add
Output o1 is determined by the addition of i1 with i2.
o1 = i1 + i2
Subtract
Output o1 is determined by thesubtraction i1 from i2.
o1 = i1 - i2
Absolute
(abs)
Output o1 is the absolute value of i1 where i1 is an expression.
Divide
Output o1 is determined by the division of i1 by i2.
o1 = abs (i1)
o1 = i1/i2
Exponential
(exp)
Output o1 is exponential of the floating point argument of i1.
Logarithm
(log)
Output o1 is the natural logarithm of i1 where i1 is a floating
point variable or expression.
o1 = exp(i1)
o1 = log(i1)
Base 10
Logarithm
(log10)
Output o1 is the base 10 logarithm of i1 where i1 is a floating
point variable or expression.
Modulus
(mod)
Output o1 is the remainder of i1 divided by i2.
Minimum
(min)
Output o1 is smaller value of inputs i1 and i2.
Language Reference Manual
o1 = log10(i1)
o1 = mod(i1, i2)
o1 = min(i1, i2)
159
Output o1 is determined by multiplying i1 times i2.
Multiply
o1 = i1 * i2
Maximum
(max)
Output o1 is larger value of inputs i1 and i2.
Positive
(dim)
Output o1 is the positive difference of inputs i1 and i2. If i1 is
greater than i2 then the result is i1 - i2, otherwise the result is
zero.
o1 = max(i1, i2)
o1 = dim(i1, i2)
Output o1 is the result of raising i1 to the power of i2. This
function raises a scalar, vector, or matrix to a scalar, vector, or
matrix power, element by element. In the case of a scalar
raised to a vector or matrix power, the resulting output is a
vector or matrix respectively.
Power
o1 = i1**i2
Transfer of
Sign
(sign)
Output o1 is the sign of i2 times the absolute value of i1.
Sign
(sgn)
Output o1 is +1 if the input is greater than or equal to 0. It is -1
if the input is less than 0.
o1 = sign(i1, i2)
o1 = sgn(i1)
Square Root Output o1 is the square root of i1.
(sqr)
o1 = sqrt(i1)
6.6 Nonlinear Operations
Backlash
(bcklsh)
Output o1 is the backlash (or hysteresis) of input expression i1
with initial condition ic. Argument d1 is half the width of the
backlash.
o1 = bcklsh (ic, dl, i1)
Bound
Output o1 is the bound of input expression i1 where bb is the
bottom bound and tb is the top bound. Use limint rather than
bound to limit the output of an integrator.
Language Reference Manual
160
o1 = bound (bb, tb, i1)
Dead Zone
(dead)
Output o1 is zero when input i1 lies between bottom bound bb
and top bound tb; it is equal to i1 otherwise.
o1 = dead (bb, tb, i1)
Function
Switch
(fcnsw)
Output o1 is determined by the input function p (the bottom
input port), to be one of the other three inputs, i1, i2, and i3,
such that:
o1 = i1 if p < 0.0
o1 = i2 if p = 0.0
o1 = i3 if p > 0.0
o1 = fcnsw (p, i1, i2, i3)
Function
Switch
(limint)
Output o1 is the limited integration of input i1 with initial
condition ic, bottom bound bb, and top bound tb.
Quantizer
(qntzer)
Output o1 is the quantization of input i1 at resolution p.
Real Switch
(rsw)
Output o1 is the output of a real (floating point) switch. If logical
input p (bottom input port) is TRUE, the output takes the value
of input expression i2 (middle input port); if p is FALSE, the
output takes the value of input expression i1 (top input port).
o1 = limint (i1, ic, bb, tb)
o1 = qntzr(p, i1)
o1 = rsw (p, i2, i1)
Cross
Detection
The CrossDetect block produces a +1 output when the input
crosses a threshold in a positive direction. It produces a -1
output when the input crosses in a negative direction. This
output is held for one timestep. It produces a 0 otherwise.
6.7 Plots Operations
Plot Block
Plot blocks plot the value of variables. To use a plot block,
wire variables to it, run the model, and double-click on the
plot block. To change the plot's parameters, right-click on
the plot block and choose Plot Block Details. Also use the
Details Plot Into dialog to add a description of the plot in the
"center text" field, so your description will appear below the
Language Reference Manual
161
icon. To add or delete input ports on the plot block (so you
can add or delete variables on the plot), right-click on the
plot block.
Strip Plot
Strip Plot plots the variable values in strip plot form. To use
Block
a strip plot block, wire 2 or more variables to it, run the
model, and double-click on the block. Each variable plotted
needs an input port (>).To change the plot's parameters,
right-click on the plot block and choose Plot Block details.
Also use the details dialog to add a description of the plot in
the "center text" field, so your description will appear below
the icon. To add or delete ports on the plot block, right-click
on it. Strip plots are normally drawn with one variable per
axis and stacked from the bottom up.
3D Bar Plot Plot blocks plot the value of variables. To use a plot block,
wire variables to it, run the model, and double-click on the
plot block. To change the plot's parameters, right-click on
the plot block and choose Plot Block Details. Also use the
Details Plot Into dialog to add a description of the plot in the
"center text" field, so your description will appear below the
icon. To add or delete input ports on the plot block (so you
can add or delete variables on the plot), right-click on the
plot block.
Bar Plot
Standard time-history bar graph of the input ports.
bar($_i1$,$PLOT_SETTINGS_FILE
_NAME$).
Contour 3D Standard time-history contour3 of the input ports
Plot
contour3($_i1$,$PLOT_SETTINGS
_FILE_NAME$)
Contour
Plot
Standard time-history contour of the input ports
Plot X vs Y
.Standard time-history line plot of the input ports
contour($_i1$,$PLOT_SETTINGS_
FILE_NAME$).
Logarithmic Standard time-history loglog of the input ports
Axes
loglog($_INDEPENDENT_VAR$,$_i
1$,$PLOT_SETTINGS_FILE_NAME$
).
Language Reference Manual
162
6.8 Sources Operations
Constant
Output o1 is set to the value of the constant. Constants can be
set using a block's Constant Info box.
constant o1 = 1.0
Random
Number
(Gaussian)
Returns a random number drawn from a gaussian distribution.
Random seed is ZZSEED .
WARNING: Not intended for use in a Derivative section.
constant Mean = 0.0
constant Sigma = 1.0
Y = gauss(Mean, Sigma)
Gaussian
Seed
This function sets the gaussian seed for the random number
generator. The input i1 should be a large, positive, odd number
for a maximal length sequence. The default seed is 55555555.
call gausi(= i1)
Harmonic
Drive
Output o1 is the harmonic drive or sinsoidal function with the
results of
o1 = 0.0 for T < tz
o1 = sin(w*(T - tz) + p) for T >= tz
where tz is the delay in seconds, w is the frequency, and p is
the phase shift.
o1 = pulse(tz, p, w)
Pulse
Output o1 is a pulse that starts at the first integration step after
tz with period p and width w.
o1 = pulse(tz, p, w)
Ramp
Output o1 is a linear ramp of unit slope starting at the first
integration step after tz.
o1 = ramp(tz)
Step
Language Reference Manual
Output o1 changes from zero to one starting at the first
integration step
after tz.
163
o1 = step(tz)
Uniform
The output of the uniform noise function is a random variable
uniformly distributed between a bottom bound bb and a top
bound tb. Random number generator seed is ZZSEED.
WARNING: Not intended for use in a Derivative section.
constant bb = 0.0
constant tb = 1.0
o1 = unif(bb, tb)
Uniform
Seed
The Uniform Seed function sets the seed for the random
number generator. The input should be a large, positive, odd
number for a maximal length sequence. The default seed is
55555555.
call unifi(= i1)
White Noise
(ou)
Output o1 is band limited white noise, implemented by the
Ornstein- Uhlenbeck function. The Ornstein-Uhlenbeck
process maintains a constant source of power over a specified
frequency band, thus eliminating any problem of having to
include the current integration step size in the standard
deviation of the random variable. ta is the low-pass filter time
constant, m is the mean value of the output, and s is the
standard deviation of the output.
o1 = ou(ta, m, s) .
6.9 Trigonometry Operations
Arc Cosine
(acos)
Output o1 is the arc cosine of i1 where i1is an expression or
floating point variable.
o1 = acos(x)
ArcSine
Output o1 is the arc sine of i1 where i1 is an expression or
floating point variable. Output is in radians.
o1 = sin(x)
Arc Tangent
(atan)
Language Reference Manual
Output o1 is the arc tangent of the floating point argument i1
where i1 is unlimited except for infinity and the result is in
radians in the range (-p/2 < y < +p/2) an expression or floating
164
point variable.
o1 = atan(x)
Arc Tangent
- angle
(atan2)
Output o1 is the arc tangent of an angle formed by the point
with floating point coordinates x, y, and the positive x-axis; x
and y can be both positive and negative, defining the full circle
of revolution. The result is in radians in the range (-p/2 < y <
+p/2).
o1 = atan2(x)
Cosine (cos)
Output o1 is the cosine of i1 where i1 is an expression or
floating point variable.
o1 = cos(x)
CosineHyperbolic
(cosh)
Output o1 is the hyperbolic cosine of i1 where i1 is an
expression or floating point variable.
sin
Output o1 is the sine of i1 where i1 is an expression or floating
point variable.
o1 = cosh(i1)
o1 = sin(x)
sinh
Output o1 is the hyperbolic sine of i1 where i1 is an expression
or floating point variable.
o1 = sinh(i1)
tan
Output o1 is the tangent of i1 where i1 is an expression or
floating point variable.
o1 = tan(x)
(tanh)
Output o1 is the hyperbolic tangent of i1 where i1 is an
expression or floating point variable.
o1 = tanh(i1)
Language Reference Manual
165
Appendix A General Purpose Utilities
This appendix describes the general purpose subroutines from the system
library.
A.1 DEBUG
Form:
CALL DEBUG
Description:
A call to this routine produces a debug dump of all variables, excluding arrays
greater than MALPRN (maximum array limit for print), on the print (PRN) unit. If
HVDPRN (high volume display) is set TRUE, the dump also appears on the
display (DIS) unit. The simplest way to get debug dumps is to set NDBUG to a
positive integer at runtime so that a debug list is produced at the end of every
DERIVATIVE, DISCRETE, and Jacobian evaluation; for example:
> NDBUG=20
> start
While useful as a checkout tool, with large programs this approach can result in
an overwhelming amount of output. A more restricted selection of dumps can be
obtained by using the ACTION command (see Chapter 5) or by including a call to
DEBUG at the end of the DERIVATIVE or DISCRETE sections as follows:
IF(logical condition) CALL DEBUG
NOTE: Sorted sections of a program are not always translated in the order given.
Reviewing the resulting FORTRAN listing will show the order of execution and
the placement of the DEBUG call.
Including the following call in the DYNAMIC section produces the dump at every
communication interval and is synonymous with OUTPUT /ALL:
CALL DEBUG
Calling DEBUG from the TERMINAL section gives all final values plus initial
conditions, a useful set of data. Putting the call on a logical switch as follows
allows you to suppress the listing when you don't want it, such as during
interactive runs.
LOGICAL dump
CONSTANT dump = .TRUE.
IF(dump) CALL DEBUG
Language Reference Manual
166
A.2 DISSTR
Form:
CHARACTER buffer*nn
CONSTANT buffer = `place string here`
CALL DISSTR(buffer)
Description:
In window environments it is not possible to use Fortran WRITE and PRINT
statements to write to screen, so the DISSTR (display string) utility is provided.
To use DISSTR, an internal file is declared as a character buffer with enough
space for a message (*80 for an 80-column line, for example). Then a call to
DISSTR(buffer) prints the buffer.
Example:
CHARACTER buffer*80;
CONSTANT buffer = `Entering the discrete section
`
CALL DISSTR(` `)
CALL DISSTR(` `)
CALL DISSTR(buffer)
! write two blank lines
! write the message
A.3 XFERBR, XFERBI
Form:
CALL XFERBR(y = x, n)
CALL XFERBI(j = i, n)
Description:
Where x and y are floating point arrays of the same length, i and j are integer
arrays of the same length, and n is an integer specifying the number of elements
in the arrays. If n is a variable, it must be declared as an INTEGER. The XFERB(transfer block) subroutines move arrays from one place to another without
requiring DO loops. The n elements in array x are moved into array y. No check
is made to see whether these elements actually exist. XFERBR is single or
double precision, depending on its arguments. XFERB- might be used, for
example, to transfer the three elements VM(1), VM(2), and VM(3) into the first
three elements of the array RMD as follows:
CALL XFERBR(rmd = vm, 3)
Language Reference Manual
167
A.4 RSTART
Form:
RSTART(blockname, newstep)
Description:
Where blockname refers to the DERIVATIVE section (default is currently the
only derivative section allowed) and newstep is an integration step size. A call
to RSTART routine restarts the step size and history of the variable step, variable
order integration algorithms. It has no effect on the fixed-step Runge-Kutta
algorithms and also cannot be used with the Runge-Kutta-Fehlberg algorithms.
The call is usually used within a DISCRETE section that may be changing
conditions discontinuously, thus invalidating the history data used by the
integration routine in the continuous section.
Language Reference Manual
168