Examples:
 

 

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 temper­ature 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.