« Classical elements in… « || Inicio || » Programming Mathemati… »

Classical elements in NetLogo: Fire

Última modificación: 25 de Noviembre de 2016, y ha tenido 203 vistas

Etiquetas utilizadas: || || || || ||

Following with the simulation of Classical Elements in NetLogo, and after Earth and Water, we will address in this post how to simulate some fire features, but taking into account the same goals of decentralized and as simple as possible models.

According to Science Learning Website, fire is the visible effect of the process of combustion, a special type of chemical reaction. It occurs between oxygen in the air and some sort of fuel, and the products from the chemical reaction are completely different from the starting material.

Combustion is when fuel reacts with oxygen to release heat energy. It can be slow or fast depending on the amount of oxygen available. Combustion that results in a flame is very fast and is called burning.

The fuel must be heated to its ignition temperature for combustion to occur, and this temperature depends on the type of fuel. The reaction will keep going as long as there is enough heat, fuel and oxygen. If any of them finishes, the combustion will stop. This is known as the fire triangle.

Fire is formed by a set of incandescent particles or molecules of combustible material capable of emitting visible light. The flames are the parts of the fire that emit visible light, while smoke are physically the same but that no longer emit. Because the most common and graphical picture of fire is the flame, we will be interested in this post in simulate flame productions.

In the models presented here we will separate the incandescent particles from the air (with oxygen) around them. For the particles we will make use of turtles, while the air will be modeled with patches.

All the elements (incandescent particles and air) have a property to store their individual temperature (Temp-part and Temp-air, respectivelly) as the followin code suggests.

breed [particles particle]
    
patches-own [ Temp-air ; Temperature of every patch (air cell) ]
particles-own [ Temp-Part ; Heat of every particle ]

As in the other cases, we are not interested in replicate the physical processes ocurring during the fire production, but in creating some conditions where we can recognize its effects.

The process we use works as follows:

  1. In every step, each particle moves, preferably upwards, towards the neighbour air cell with more similar temperature to it. In this way we get something like flows of ascending particles.
  2. Once there, the air cell increments its temperature because of the presence of an incandescent particle in it.
  3. Simultaneously, every air cell diffuse its temperature to neighbours cells (according to a Heat Conductivity parameter) and all of them get a little bit cooler.
  4. Only particles with positive temperature will survive, it is not worth to keep alive particles that will not produce new fire.

All these ideas are implemented in the next procedure:

to go
  ; Temp Diffussion of patches
  diffuse Temp-air Heat-Conductivity
  ; Reduce Air Temperature by natural cooling.
  ask patches
    [ set Temp-air Temp-air * (1 - Cooling-rate) ]
  ; Every Particle gets cooler, ascend and heat the air cell
  ask particles [
    ; The cooling depends on the temp of the cell it occupies
    set Temp-Part Temp-Part - ifelse-value (Temp-Part > Temp-air) [1] [0.1]
  
    ; If it is totally cold, it dies
    if Temp-Part < 0 [die]             
    let MyTemp Temp-Part
    
    ; It moves up, to one of the cells with higher difference in temperature
    ifelse pycor < max-pycor
      [ face min-one-of patches-to-move [abs (Temp-air - MyTemp)]   ]
      [ die ] ; if location is out of the world, the particle is removed
    fd Y-Speed
    
    ; It modifies the Temperature of the air patch
    set Temp-air Temp-air + Temp-Part
  ]
end
    
; Patch Report: Returns the patches above it
to-report patches-to-move
  report (patch-set patch-at 0 1 patch-at -1 1 patch-at 1 1)
end

patches-to-move is a report that returns only the patches above the particle... In this way, flames tend to go upwards.

That's all the important to get very realistic flame effects. All we need now is to color the patches in order to show the flames (by default, the particles will be hidden), and add some extra functionalities to create ignitors with the mouse (places where the incandescent particles born) or wind effect (some horizontal movement to the particles). The Boxed? option will make vertical borders to act as walls, so, once the particles are there, they only can move upwards. You can set up a value for the wind (negative values blowing to the left, and positive ones to the right), and switching on the Varying-Wind? variable, the wind will automatically change its strength and, possibly , direction. Y-speed value controls the velocity of the particles, and the density slider will control the amount of incandescent particles that a particular ignitor will produce (in fact, it is a probability of production). The Visible-Particles? switch will change between seeing the incandescent particles moving or seeing the flame effect on the air patches.

You can use it in the following web version of the model (press go button, and then click whenever you want to add ignitors).

Take into account that, because of the diffuse process, the model demands for high consuming resources and, when using on the browser (with NetLogo Web), it runs very slowly.

The complete code can be found bellow, and you can download the model here.

breed [particles particle]
    
globals
[
  ignitors      ; Set of patches producing fire
]
    
patches-own
[
  Temp-air ; Temperature of every patch (air cell)
]
   
particles-own
[
  Temp-Part ; Heat of every particle
]
    
; Startup and Reset procedure
to startup
  ca
  set ignitors no-patches
end
    
; Main procedure. It produces the dynamics
to go
  ; Temp Diffussion of patches
  diffuse Temp-air Heat-Conductivity
  ; Reduce Air Temperature by natural cooling.
  ; After that, we color them according their temperature
  ask patches [
    set Temp-air Temp-air * (1 - Cooling-rate)
    ifelse Visible-Particles?
      [set pcolor [0 0 0]]
      [set pcolor flame-color Temp-air]]
; Generate new burning particles in the base ask ignitors [ if random-float 1 < density [ sprout-particles 1 [ ifelse Visible-Particles? [st][ht] set shape "circle" set color red set Temp-Part random Max-Initial-Temp set color flame-color Temp-Part ] ] ] ; Every Particle gets cooler, ascend and heat the air cell ask particles [ ; The cooling depends on the temp of the cell it occupies set Temp-Part Temp-Part - ifelse-value (Temp-Part > Temp-air)[1][0.1] ; If it is totally cold, it dies ifelse Temp-Part < 0 [die] [set color flame-color Temp-Part] let MyTemp Temp-Part ; It moves up, to one of the cells with higher difference in temperature ifelse pycor < max-pycor [ face min-one-of patches-to-move [abs (Temp-air - MyTemp)] ] [ die ] fd Y-Speed ifelse abs (xcor + wind) < max-pxcor [ set xcor xcor + wind ] [ if not boxed? [die] ] ; It modifies the Temperature of the air patch set Temp-air Temp-air + Temp-Part] if Varying-Wind? [ [ set wind precision (wind + (random-float .01) - .005) 3 ] if wind > .5 [set wind .5 ] if wind < -.5 [set wind -.5 ] ; Add new burning particles under the mouse position if mouse-down? [ set ignitors (patch-set ignitors patch mouse-xcor mouse-ycor) wait .1 ] end ; Patch Report: Returns the patches above it to-report patches-to-move report (patch-set patch-at 0 1 patch-at -1 1 patch-at 1 1) end ; Assign the color for the flame in function of the Temperature to-report flame-color [t] report map [cut (t * ?) ] [31 17 13] end ; Bound function to 255 to-report cut [x] report ifelse-value (x > 255) [255][x] end

In a very similar way we can use the same approach to simulate 3D flames (although, because of the patches diffusion of heat, it's high resource consuming).

Playing around with the palette of colors to be used by patches, we can add some smoke looking feel by color lower temperatures with grey shades. For that, we will make use of the palette extension, that allows to associate a gradient of colors to a variable:

; Assign the color for the flame in function of the Temperature
to-report flame-color [t]
  report palette:scale-gradient [ [0 0 0] [120 120 120] [150 150 150]
                                 [255 170 130] [255 255 195] [255 255 255] ] t 0 20
end

With this function we trransform the value t (from 0 to 20) into a color following the gradient of colors provided by the RGB values in the list. If a t value is aout of this range, it will take the corresponding extreme value:

You can obtain very different lookings by changing the interpolated RGB colors in the list (of course, you will need at least 2 colors in it). Have in mind that the colors you set in the list will be uniformly distributed in the interpolation, hence if you use \((n+1)\) colors for a range of values in \([a,b]\), the first color will be obtained in the value \(a\), the second will be obtained for the value \(a + \frac{(b-a)}{n}\), the last one will be obtained for the value \(b\), and in between two contiguous colors the extension returns the linearly interpolated color of them. 

Also, if we want to have more smoke on the area, we can avoid to reduce particles temperature bellow some bound. In the go procedure, we can change the ask particles [ ... ] by:

ask particles [
  ; The cooling depends on the temp of the cell it occupies
  set Temp-Part Temp-Part -
                ifelse-value (Temp-Part > Temp-air)
                  [ (Temp-Part - Temp-air) * Heat-conductivity ]
                  [ Cooling-rate ]
    
  ; Decide with a switch control the presence of smoke:
  if smoke? [set temp-part max (list 2 temp-part)]
    
  ; If it is totally cold, it dies
  ifelse Temp-Part < 0 [die] [set color flame-color Temp-Part]
  let MyTemp Temp-Part
  ; It moves up, to one of the cells with higher difference in temperature
  ifelse pycor < max-pycor
    [ face min-one-of patches-to-move [abs (Temp-air - MyTemp)]   ]
    [ die  ]
  fd Y-Speed
  ifelse abs (xcor + wind) < max-pxcor
    [ set xcor xcor + wind ]
    [ if not boxed? [die] ]
  ; It modifies the Temperature of the air patch
  set Temp-air Temp-air + Temp-Part
  ]

Also, in this last version we have cooled the particles following the parameters of the environment (heat conductivity and cooling rate) in order to have more control of the whole process.

And don't forget to load the palette extension (bundled with NetLogo) at the beginning of the code:

extensions [palette]

You can find the model Fire & Smoke here.

To know more...

Fluid Fire Simulation

NetLogo Book

« Classical elements in… « || Inicio || » Programming Mathemati… »