Coding tips
User written subroutines usually contain local variables and arrays that store data
required during a solve. Arrays that contain unchanging data (e.g. list of elements)
should be defined once during the first call to USER1
and then used
later. In order to preserve the values between calls, a FORTRAN SAVE
statement is necessary. In practice, the cost of using a global SAVE
statement for all of the variables in the subroutine is minimal, usually all significant
arrays must be preserved between calls.
Array sizes should be defined with PARAMETER
statements and then the
limits checked when arrays are filled.
C Maxelem is the maximum number of elements this routine can handle
C
integer maxelem
parameter (maxelem = 10000)
..
integer elemlist(maxelem), numelem
real newelemprop(maxelem)
..
C
C Load arrays checking to see if array bounds are exceeded.
C
call getelem(elemlist, numelem)
if(numelem .gt. maxelem) then
C
C handle the error, tell user what numelem is so that
C maxelem can be changed
C
print *,'Fatal Error: Parameter MAXELEM be > ' numelem
..
end if
The use of the parameter MAXELEM
in the above code achieves the
following:
- The array size value is used in a number of places, by using a parameter, it is set in one place.
- The array limits are easily checked for overflow as they are filled.
The error handler informs the user what the minimum acceptable value of the parameter is.
Thermal solver is run with array bound checking turned off, as these checks are costly. If you assign values beyond the size of the array then you will be overwriting other variables. If this happens you must stop execution as all data is suspect.
In the above example, the array is filled by the routine getelem
. A better approach is to pass the value of maxelem
to the routine getelem
so that it can check the array limit as it is loaded, this will also keep the checking inside the code that could over fill the array. A better version (part of the code) would be the following providing getelem
does the appropriate checks:
C
C Load arrays
C
call getelem(elemlist, numelem, maxelem)
Always check array limits. It is easy to develop a routine and think that it will never be used on a model with more than 1000 elements. Some time later the code is reused, the models are bigger and the array overflows. If you are lucky the code will crash or give ridiculous answers, otherwise the answers may be significantly but not obviously wrong.
The following code provides a simple checking mechanism.
subroutine boundcheck(value, limit, arrayname)
C
C Checks array bounds
C
integer value, limit
character*40 arrayname
C
C
C
if(value .gt. limit) then
print ,' ** FATAL* Array size limit exceeded.'
print *,' Array name : ',arrayname
print *,'Requested size : ', value
print *,'Declared size : ', limit
end if
return
end