 |
Example - Heat Simulation
* The "\" symbol has been used at the end of lines to indicate that the line was too long for the display and has been
wrapped to the line below in order to fit within the width of the web page. These lines would need to be joined in the normal
program editor.
I. Introduction
This program models the transfer of heat by conduction. Before the simulation is run, the user is presented with an empty grid that can then be used to create a block of solid material. Clicking on ‘cells' in the grid will fill that cell with heat-conducting material. The program uses finite element arrays to perform the simulation.

II. Mathematics and Physics Involved
Heat is conducted between each filled cell and its filled neighbours. The rate of conduction is proportional to the temperature difference between the cells and inversely proportional to the distance between them. That is the rate of conduction depends only on the local temperature gradient.
III. How the Program Works
1) Initialisation
First the colour palette is set up to contain the colours necessary to display the temperatures of the cells (which can range from 0 to 1):
forms.add("frm")
IF FN sys(26) > 532 THEN superbase.form.controls.\ DefFontStrikeOut = 0
frm.scalemode = 2
frm.autoredraw = 0
window.viewmode = 3
'window.windowstate = 2
selectionbar = 0
'SET MENU OFF
SET DISPLAY 0
SET mypage = frm.Pages(1)
mypage.BackVisible = - 1
mypage.BackColor = 4
mypage.Width = 800
mypage.Height = 600
mypage.Name = "Page1"
mypage.RefreshStyle = 1
mypage.AbsolutePosition = 0
FOR i%% = 128 TO 255
frm.page.setpalette(i%%, IF (i%% <= 191,4 * (i%% - 128),252)\ , IF (i%% <= 191,0,4 * (i%% - 192)),0)
NEXT i%%
The form is then set up: xy rectangles are added to the form so that when they are clicked, they change colour to represent their state (empty or filled).
FOR i%% = 1 TO x%%
FOR j%% = 1 TO y%%
SET fc = frm.add(cellname$(i%%,j%%),"Rectangle")
fc.stepwidth = 1
fc.viewstyle = 1
fc.forecolor = 8
fc.forevisible = - 1
fc.bordercolor = 9
fc.bordervisible = 0
fc.onclick = "togglestate"
fc.onclick.mode = 2
fc.move(d%% * i%% + xs%%,d%% * (j%% + 1) + ys%%,d%%,d%%)
NEXT j%%
NEXT i%%
The subroutine togglestate() contains the following commands to make the cell change colour, and change its view style (raised or recessed):
SUB togglestate()
viewstyle = 1 - viewstyle
forecolor = IF (forecolor = 8,128,8)
parent.refresh()
END SUB
The screenshot below shows the display before the simulation is run.

2) The dosim() Procedure
When the Simulate button is clicked, the main simulation procedure is called, where the finite element array temp is initialised. The array f$ contains the string for each cell which,when executed, will display the temperature for that cell, for example temp(0,1,2) for cell index (1,2). The first subscript value of zero signifies that it is the actual value of the temperature we require, not a derivative. The heat source is given a temperature of 1, and the sink of 0. The formula for each cell is built using string concatenation, dependent on the values of the surrounding cells. If they are filled then formula1$ holds a string representing the sum of the temperatures of the filled cells to the immediate left, right, top and bottom of the cell, and formula2$ holds a string representing the sum of the temperatures of the filled cells diagonally adjacent to the cell. The eventual formula is assigned as below:
fea.dimensions(1) = x%%
fea.dimensions(2) = y%%
fea.add("temp"):REM as in 'temperature' not 'temporary'
fea.temp.order = 1
fea.temp.allowableerrorfactor = 0.05
fea.temp.allowableerrormin = 0.05
FOR i%% = 1 TO x%%
f$(i%%,0) = "1"
f$(i%%,y%% + 1) = "0":REM mustn't be ""
FOR j%% = 1 TO y%%
SET fc = frm(cellname$(i%%,j%%))
fc.onclick = ""
IF (fc.forecolor <> 8) THEN
f$(i%%,j%%) = "temp(0," + STR$ (i%%,".") + "," + STR$ \ (j%%,".") + ")"
END IF
NEXT j%%
NEXT i%%
FOR i%% = 1 TO x%%
FOR j%% = 1 TO y%%
IF (f$(i%%,j%%) <> "") THEN
formula1$ = ""
formula2$ = ""
count1%% = 0
count2%% = 0
IF (f$(i%% - 1,j%%) <> "") THEN
formula1$ = formula1$ + "+" + f$(i%% - 1,j%%)
count1%% = count1%% + 1
END IF
IF (f$(i%%,j%% - 1) <> "") THEN
formula1$ = formula1$ + "+" + f$(i%%,j%% - 1)
count1%% = count1%% + 1
END IF
IF (f$(i%%,j%% + 1) <> "") THEN
formula1$ = formula1$ + "+" + f$(i%%,j%% + 1)
count1%% = count1%% + 1
END IF
IF (f$(i%% + 1,j%%) <> "") THEN
formula1$ = formula1$ + "+" + f$(i%% + 1,j%%)
count1%% = count1%% + 1
END IF
IF (f$(i%% - 1,j%% - 1) <> "") THEN
formula2$ = formula2$ + "+" + f$(i%% - 1,j%% - 1)
count2%% = count2%% + 1
END IF
IF (f$(i%% + 1,j%% - 1) <> "") THEN
formula2$ = formula2$ + "+" + f$(i%% + 1,j%% - 1)
count2%% = count2%% + 1
END IF
IF (f$(i%% - 1,j%% + 1) <> "") THEN
formula2$ = formula2$ + "+" + f$(i%% - 1,j%% + 1)
count2%% = count2%% + 1
END IF
IF (f$(i%% + 1,j%% + 1) <> "") THEN
formula2$ = formula2$ + "+" + f$(i%% + 1,j%% + 1)
count2%% = count2%% + 1
END IF
IF ((count1%% > 0) OR (count2%% > 0)) THEN
IF (count2%% > 0) THEN
formula1$ = formula1$ + "+(0.707107*(" + formula2$ \ + "))"
END IF
formula1$ = formula1$ + "-("
formula1$ = formula1$ + TRIM$ ( STR$ (count1%% + ( \ SQR (0.5) * count2%%),"0.999999"))
formula1$ = formula1$ + "*" + f$(i%%,j%%) + ")"
fea.temp.setformula(formula1$,1,i%%,i%%,j%%,j%%)
END IF
END IF
NEXT j%%
NEXT i%%
The simulation is then performed. Each time the finite element array is advanced the cells are repainted according to their temperature. Every 10 time units in the simulation the user is asked whether or not to continue.
fea.advanceto(0.0)
doloop%% = 1
WHILE (doloop%% <> 0)
FOR t% = fea.t TO fea.t + 10.025 STEP 0.1
fea.advanceto(t%)
FOR i%% = 1 TO x%%
FOR j%% = 1 TO y%%
IF (f$(i%%,j%%) <> "") THEN
frm(cellname$(i%%,j%%)).forecolor = 128 + (127 * \ fea.temp (0,i%%,j%%))
END IF
NEXT j%%
NEXT i%%
frm.refresh()
SET STATUS "Time: " + STR$ (t%,"999.000")
NEXT t%
REQUEST "Continue for another 10 units?","(Click OK to \ continue,Cancel to stop)",1,doloop%%
WEND
Below are the results of a typical simulation after 40 seconds.

|