From df52fc7d553487e1bc45db68736ff3ad33b63dc5 Mon Sep 17 00:00:00 2001 From: Pedro Andrade Date: Fri, 5 Feb 2016 15:15:41 -0200 Subject: [PATCH] CAModels replaced by Models. #12. --- examples/excitable.lua | 45 ----- examples/growth.lua | 36 ---- examples/oscillator.lua | 36 ---- examples/parasit.lua | 37 ---- examples/parity.lua | 36 ---- examples/snow.lua | 39 ----- load.lua | 8 + lua/Anneal.lua | 69 +++++--- lua/CellularAutomataModel.lua | 2 + lua/DaisyWorld.lua | 206 +++++++++++++++++++++++ lua/Excitable.lua | 58 +++++++ lua/Fire.lua | 80 ++++----- lua/Growth.lua | 50 ++++++ lua/Life.lua | 83 ++++----- lua/Oscillator.lua | 49 ++++++ lua/Parasit.lua | 52 ++++++ lua/Parity.lua | 51 ++++++ lua/Snow.lua | 50 ++++++ lua/SolidDiffusion.lua | 63 +++++++ snapshots/DaisyWorld-chart-1.bmp | Bin 0 -> 900054 bytes snapshots/DaisyWorld-map-1-begin.bmp | Bin 0 -> 279434 bytes snapshots/DaisyWorld-map-1-end.bmp | Bin 0 -> 279434 bytes snapshots/DaisyWorld-map-2-begin.bmp | Bin 0 -> 279434 bytes snapshots/DaisyWorld-map-2-end.bmp | Bin 0 -> 279434 bytes snapshots/Excitable-map-1-begin.bmp | Bin 0 -> 279434 bytes snapshots/Excitable-map-1-end.bmp | Bin 0 -> 279434 bytes snapshots/Growth-map-1-begin.bmp | Bin 0 -> 279434 bytes snapshots/Growth-map-1-end.bmp | Bin 0 -> 279434 bytes snapshots/Oscillator-map-1-begin.bmp | Bin 0 -> 279434 bytes snapshots/Oscillator-map-1-end.bmp | Bin 0 -> 279434 bytes snapshots/Parasit-map-1-begin.bmp | Bin 0 -> 279434 bytes snapshots/SolidDiffusion-map-1-begin.bmp | Bin 0 -> 279434 bytes snapshots/SolidDiffusion-map-1-end.bmp | Bin 0 -> 279434 bytes tests/DaisyWorld.lua | 18 ++ tests/Excitable.lua | 15 ++ tests/Growth.lua | 15 ++ tests/Oscillator.lua | 15 ++ tests/Parasit.lua | 15 ++ tests/Parity.lua | 15 ++ tests/Snow.lua | 12 ++ tests/SolidDiffusion.lua | 15 ++ 41 files changed, 835 insertions(+), 335 deletions(-) delete mode 100644 examples/excitable.lua delete mode 100644 examples/growth.lua delete mode 100644 examples/oscillator.lua delete mode 100644 examples/parasit.lua delete mode 100644 examples/parity.lua delete mode 100644 examples/snow.lua create mode 100644 lua/DaisyWorld.lua create mode 100644 lua/Excitable.lua create mode 100644 lua/Growth.lua create mode 100644 lua/Oscillator.lua create mode 100644 lua/Parasit.lua create mode 100644 lua/Parity.lua create mode 100644 lua/Snow.lua create mode 100644 lua/SolidDiffusion.lua create mode 100644 snapshots/DaisyWorld-chart-1.bmp create mode 100644 snapshots/DaisyWorld-map-1-begin.bmp create mode 100644 snapshots/DaisyWorld-map-1-end.bmp create mode 100644 snapshots/DaisyWorld-map-2-begin.bmp create mode 100644 snapshots/DaisyWorld-map-2-end.bmp create mode 100644 snapshots/Excitable-map-1-begin.bmp create mode 100644 snapshots/Excitable-map-1-end.bmp create mode 100644 snapshots/Growth-map-1-begin.bmp create mode 100644 snapshots/Growth-map-1-end.bmp create mode 100644 snapshots/Oscillator-map-1-begin.bmp create mode 100644 snapshots/Oscillator-map-1-end.bmp create mode 100644 snapshots/Parasit-map-1-begin.bmp create mode 100644 snapshots/SolidDiffusion-map-1-begin.bmp create mode 100644 snapshots/SolidDiffusion-map-1-end.bmp create mode 100644 tests/DaisyWorld.lua create mode 100644 tests/Excitable.lua create mode 100644 tests/Growth.lua create mode 100644 tests/Oscillator.lua create mode 100644 tests/Parasit.lua create mode 100644 tests/Parity.lua create mode 100644 tests/Snow.lua create mode 100644 tests/SolidDiffusion.lua diff --git a/examples/excitable.lua b/examples/excitable.lua deleted file mode 100644 index e40ea3b..0000000 --- a/examples/excitable.lua +++ /dev/null @@ -1,45 +0,0 @@ - --- @example Excitable model from Wiener & Rosenbleuth (1946). --- Arch. Inst. Cardiol. Mexico 16, 202-265. --- Reffered in Ermentrout & Edelstein-Keshet (1993). --- Cellular Automata Approaches to Biological Modeling. --- Jornal of Theoretical Biology, 160, 97-133. --- @image excitable.bmp - -import("ca") - -Excitable = CellularAutomataModel{ - finalTime = 500, - dim = 50, - neighborhood = "vonneumann", - init = function(cell) - if (cell.x == 20 and cell.y == 25) or (cell.x == 30 and cell.y == 25) then - cell.state = 1 - else - cell.state = 0 - end - end, - changes = function(cell) - if cell.past.state == 0 then - forEachNeighbor(cell, function(cell, neigh) - if neigh.past.state > 0 then - cell.state = 1 - end - end) - elseif cell.past.state == 1 then cell.state = 2 - elseif cell.past.state == 2 then cell.state = 3 - elseif cell.past.state == 3 then cell.state = 4 - elseif cell.past.state == 4 then cell.state = 5 - elseif cell.past.state == 5 then cell.state = 0 end - end, - map = { - select = "state", - min = 0, - max = 5, - slices = 6, - color = "Blues" - } -} - -Excitable:execute() - diff --git a/examples/growth.lua b/examples/growth.lua deleted file mode 100644 index 8b7af27..0000000 --- a/examples/growth.lua +++ /dev/null @@ -1,36 +0,0 @@ - --- @example Simple growth model. --- @image growth.bmp - -import("ca") - -DIM = 100 -FINAL = 250 -PROB = 0.05 - -Growth = CellularAutomataModel{ - finalTime = FINAL, - dim = DIM, - init = function(cell) - if cell.x == DIM / 2 and cell.y == DIM / 2 then - cell.state = "alive" - else - cell.state = "empty" - end - end, - changes = function(cell, ev) - local count = countNeighbors(cell, "alive") - - if cell.past.state == "empty" and count > 0 and Random():number() < PROB then - cell.state = "alive" - end - end, - map = { - select = "state", - value = {"alive", "empty"}, - color = {"white", "black"} - } -} - -Growth:execute() - diff --git a/examples/oscillator.lua b/examples/oscillator.lua deleted file mode 100644 index 0896aaa..0000000 --- a/examples/oscillator.lua +++ /dev/null @@ -1,36 +0,0 @@ - --- @example Oscillator model from Ermentrout & Edelstein-Keshet (1993). --- Cellular Automata Approaches to Biological Modeling. --- Jornal of Theoretical Biology, 160, 97-133. --- @image oscillator.bmp - -import("ca") - -local amount = {0, -1, -2, -2, -3, -2, -2, -1, 0, 1, 2, 2, 3, 2, 2, 1} - -Oscillator = CellularAutomataModel{ - finalTime = 400, - dim = 50, - init = function(cell) - cell.state = Random():integer(0, 15) - end, - changes = function(cell) - local count = countNeighbors(cell, 0) - - if count > 0 then - cell.state = (cell.past.state + amount[cell.past.state + 1] + 1) % 16 - else - cell.state = (cell.state + 1) % 16 - end - end, - map = { - select = "state", - min = 0, - max = 15, - slices = 16, - color = "Blues" - } -} - -Oscillator:execute() - diff --git a/examples/parasit.lua b/examples/parasit.lua deleted file mode 100644 index 9f3df4b..0000000 --- a/examples/parasit.lua +++ /dev/null @@ -1,37 +0,0 @@ - --- @example Parasit model from Hassell et al. (1991). --- Spatial structure and chaos in insect population --- dynamics. Nature, Lond. 353, 255-258. --- @image parasit.bmp - -import("ca") - -Parasit = CellularAutomataModel{ - finalTime = 500, - dim = 50, - neighborhood = "vonneumann", - init = function(cell) - cell.state = Random():integer(0, 8) - end, - changes = function(cell) - if cell.past.state == 0 and countNeighbors(cell, 1) > 0 then cell.state = 1 - elseif cell.past.state == 1 then cell.state = 2 - elseif cell.past.state == 2 then cell.state = 3 - elseif cell.past.state == 3 and countNeighbors(cell, 5) > 0 then cell.state = 4 - elseif cell.past.state == 4 then cell.state = 5 - elseif cell.past.state == 5 then cell.state = 6 - elseif cell.past.state == 6 then cell.state = 7 - elseif cell.past.state == 7 then cell.state = 8 - elseif cell.past.state == 8 then cell.state = 0 end - end, - map = { - select = "state", - min = 0, - max = 8, - slices = 9, - color = "Blues" - } -} - -Parasit:execute() - diff --git a/examples/parity.lua b/examples/parity.lua deleted file mode 100644 index a5ca521..0000000 --- a/examples/parity.lua +++ /dev/null @@ -1,36 +0,0 @@ - --- @example Parity model, by Nigel Gilbert. See --- modelingcommons.org/browse/one_model/3381. --- @image parity.bmp - -import("ca") - -Parity = CellularAutomataModel{ - finalTime = 500, - dim = 50, - neighborhood = "vonneumann", - init = function(cell) - if (cell.x == 10 and cell.y == 25) or (cell.x == 40 and cell.y == 25) then - cell.state = "on" - else - cell.state = "off" - end - end, - changes = function(cell) - local count = countNeighbors(cell, "on") - - if count == 1 or count == 3 then - cell.state = "on" - else - cell.state = "off" - end - end, - map = { - select = "state", - value = {"on", "off"}, - color = {"black", "white"} - } -} - -Parity:execute() - diff --git a/examples/snow.lua b/examples/snow.lua deleted file mode 100644 index 4154e62..0000000 --- a/examples/snow.lua +++ /dev/null @@ -1,39 +0,0 @@ - --- @example Snow falling from the sky. --- @image snow.bmp - -import("ca") - -DIM = 50 -FINAL = 600 -PROB = 0.02 - -Snow = CellularAutomataModel{ - finalTime = FINAL, - dim = DIM, - neighborhood = "vonneumann", - init = function(cell) - cell.state = "empty" - end, - changes = function(cell, ev) - if cell.y == 0 then - if cell.past.state == "empty" and ev:getTime() < FINAL - DIM and Random():number() < PROB then - cell.state = "snow" - else - cell.state = "empty" - end - elseif cell.past.state == "snow" and cell.y < DIM - 1 and cell.parent:get(cell.x, cell.y + 1).past.state == "empty" then - cell.state = "empty" - elseif cell.parent:get(cell.x, cell.y - 1).past.state == "snow" then - cell.state = "snow" - end - end, - map = { - select = "state", - value = {"snow", "empty"}, - color = {"white", "black"} - } -} - -Snow:execute() - diff --git a/load.lua b/load.lua index fd4fc89..c51f8f1 100644 --- a/load.lua +++ b/load.lua @@ -3,9 +3,17 @@ files = { "CellularAutomataModel.lua", "Utils.lua", "Anneal.lua", + "DaisyWorld.lua", + "Excitable.lua", "Fire.lua", + "Growth.lua", "LifePatterns.lua", "Life.lua", + "Oscillator.lua", + "Parasit.lua", + "Parity.lua", + "Snow.lua", + "SolidDiffusion.lua", "Wolfram.lua" } diff --git a/lua/Anneal.lua b/lua/Anneal.lua index eec357d..ec11e73 100644 --- a/lua/Anneal.lua +++ b/lua/Anneal.lua @@ -4,35 +4,52 @@ -- @arg data.dim The x and y dimensions of space. -- @arg data.finalTime A number with the final time of the simulation. -- @image anneal.bmp -Anneal = CellularAutomataModel{ +Anneal = Model{ finalTime = 100, dim = 80, - init = function(cell) - if Random():number() > 0.5 then - cell.state = "L" - else - cell.state = "R" - end - end, - changes = function(cell) - local alive = countNeighbors(cell, "L") + init = function(model) + model.cell = Cell{ + init = function(cell) + if Random():number() > 0.5 then + cell.state = "L" + else + cell.state = "R" + end + end, + execute = function(cell) + local alive = countNeighbors(cell, "L") - if cell.state == "L" then alive = alive + 1 end + if cell.state == "L" then alive = alive + 1 end - if alive <= 3 then - cell.state = "R" - elseif alive >= 6 then - cell.state = "L" - elseif alive == 4 then - cell.state = "L" - elseif alive == 5 then - cell.state = "R" - end - end, - map = { - select = "state", - value = {"L", "R"}, - color = {"black", "white"} - } + if alive <= 3 then + cell.state = "R" + elseif alive >= 6 then + cell.state = "L" + elseif alive == 4 then + cell.state = "L" + elseif alive == 5 then + cell.state = "R" + end + end + } + + model.cs = CellularSpace{ + xdim = model.dim, + instance = model.cell + } + + model.cs:createNeighborhood() + + model.map = Map{ + target = model.cs, + select = "state", + value = {"L", "R"}, + color = {"black", "white"} + } + + model.timer = Timer{ + Event{action = model.cs} + } + end } diff --git a/lua/CellularAutomataModel.lua b/lua/CellularAutomataModel.lua index cf805a9..75609f3 100644 --- a/lua/CellularAutomataModel.lua +++ b/lua/CellularAutomataModel.lua @@ -10,6 +10,8 @@ -- "color" & A table with the colors for the respective values. -- @arg data.init A function that describes how a Cell will be initialized. -- @arg data.changes A function that describes how each Cell is updated. +-- @arg data.space An optional function to create space. It gets the +-- model as argument and must return a CellularSpace. -- @usage import("ca") -- -- Anneal = CellularAutomataModel{ diff --git a/lua/DaisyWorld.lua b/lua/DaisyWorld.lua new file mode 100644 index 0000000..61d63bb --- /dev/null +++ b/lua/DaisyWorld.lua @@ -0,0 +1,206 @@ +---------------------------------- +-- 2D Daisyworld +-- Environmental Modelling +-- Nourhan, Shahin and Aida. +---------------------------------- + +-- It calculates the probability to reproduce based on the temperature of the soil +local function calculateProbRepro(cell) + local diff = math.abs(cell.temperature.reproducePerfect - cell.past.SoilHeat) + return 100 - diff +end + +-- A daisy dies because of old age +local killDaisy = function(cell) + if cell.past.daisy == "black" then -- one daisy dies, one empty space increment + cell.lifeSpan = 0 + cell.daisy = "empty" + elseif cell.past.daisy == "white" then + cell.lifeSpan = 0 + cell.daisy = "empty" + end +end + +-- It calculates the soil heat based on the neigbours, the mean between neighbours mean and itself +local calculateSoilHeat = function(cell) + local selfHeat = 0 + + if cell.past.daisy == "white" then --increment or decrement temperature depending on the daisy + selfHeat = cell.past.SoilHeat - cell.past.SoilHeat * cell.albedo.white + elseif cell.past.daisy == "black" then + selfHeat = cell.past.SoilHeat + cell.past.SoilHeat * cell.albedo.black + else + selfHeat = cell.past.SoilHeat + end + + local neigbourHeat = 0 -- change temperature to make it similar to the neigbours + local neighbourCount = 0 + + forEachNeighbor(cell, function(cell, neigh) + neighbourCount = neighbourCount + 1 + neigbourHeat = neigbourHeat + neigh.past.SoilHeat + end) + + local neigbourHeat = neigbourHeat / neighbourCount -- calculate the mean of the neighbours + local heat = (selfHeat + neigbourHeat) / 2 + + heat = math.min(heat, cell.temperature.max) --make heat value inside the valid range + heat = math.max(heat, cell.temperature.min) + + return heat +end + +-- New daisy is born same color as the neigbour, and with age 0 +local function bornNewDaisy(cell) + local blackDaisyCounter = countNeighbors(cell, "black") + local whiteDaisyCounter = countNeighbors(cell, "white") + + cell.lifeSpan = 0 + + if whiteDaisyCounter > blackDaisyCounter then + cell.daisy = "white" + elseif whiteDaisyCounter < blackDaisyCounter then + cell.daisy = "black" + elseif whiteDaisyCounter > 0 then -- equal + if Random():number(0, 1) < 0.5 then + cell.daisy = "white" + else + cell.daisy = "black" + end + end +end + +local update = function(cell) + if cell.past.daisy ~= "empty" then + cell.lifeSpan = cell.lifeSpan + 1 --incrementing one day in the life of the daisy if it is not empty + end + + if cell.past.lifeSpan >= cell.maxLifeSpan then + cell:killDaisy() + end + + cell.SoilHeat = cell:calculateSoilHeat() + + if cell.past.daisy == "empty" and cell.past.SoilHeat > cell.temperature.reproduceMin and cell.past.SoilHeat < cell.temperature.reproduceMax then + local probabilityReproduce = cell:calculateProbRepro() + if Random():number() * 100 < probabilityReproduce then --new daisy is born + cell:bornNewDaisy() + end + end +end + +--- Implementation of a 2D Daisy World model. +-- We have three type of cells: White daisies, Black daisies and soil, with a given albedo for each of them. +-- The cells are placed randomly in the cellular space depending on the given percentage of soil and white daisies, in the remaining there are placed black daisies. Each of them is given with a random initial age, to control the population of daisies, because when they are old (given age) they die. +-- Each cell is also given a random initial value for soil heat between the range of possible values of temperature. +-- Each time step for CA, the temperature will be calculated as follows: Each cell temperature will be calculated according to the daisy albedo and the previous temperature, also the mean neighbours temperature is calculated and this value is used to calculate the mean between the temperature from the cell itself and the mean of the neighbours. +-- If there is an empty cell with a daisy as neighbour, and the conditions for reproduction are fulfilled, a new daisy will be born in the empty cell. +-- The conditions for reproduction are that the daisy's ground has to be inside the range of temperatures, and if it is in the given perfect temperature to reproduce it will have 100 % of chances to reproduce, and less chances the further it is from the perfect temperature. The new born daisy will be the same type as the maximum neighbourhood type (black or white). +-- The daisies will die on a certain (given) age. +-- The first version of this implementation was developed by Nourhan, Shahin and Aida, as final work for Environmental Modeling course in +-- Erasmus Mundus program, Munster University, 2014. It still needs further development. +-- @arg data.proportions A table with two indexes, empty and white, describing the initial proportions of empty and white cells. +-- @arg data.temperature A table with the temperatures: max for maximum temperature, min for minimum temperature, reproduceMin for the minimum +-- temperature that makes the daisies reproductible, reproducePerfect for the temperature daisies will reproduce with a probability of 100%, +-- and reproduceMax for the maximum temperature where daisies can reproduce. +-- @arg data.finalTime The final simulation time. +-- @arg data.lifeSpan How long does a daisy live? +-- @arg data.dim The x and y dimensions of space. +-- @arg data.albedo A table with white and black albedos. +DaisyWorld = Model{ + proportions = { + empty = Choice{min = 0.1, max = 0.5, default = 0.5}, + white = Choice{min = 0.1, max = 0.45, default = 0.2} + }, + temperature = { + min = Choice{min = 0, max = 100}, + max = Choice{max = 100}, + reproduceMin = Choice{min = 0, max = 100}, + reproducePerfect = Choice{min = 0, max = 100, default = 50}, + reproduceMax = Choice{max = 100} + }, + finalTime = Choice{min = 100, default = 200}, + albedo = { + white = Choice{min = 0, max = 1, default = 0.2}, + black = Choice{min = 0, max = 1, default = 0.7} -- 0-1 How much energy hey absorb as heat from sunlight + }, + lifeSpan = Choice{min = 2, max = 20, step = 1, default = 10}, -- in time stamps + dim = 10, + init = function(model) + model.cell = Cell{ + init = function(cell) + cell.SoilHeat = 50 --rand:number() * 100 + cell.lifeSpan = Random():number(0, 4) -- we give random number to the age at the first moment + + if Random():number() > model.proportions.empty then + if Random():number() > model.proportions.white then + cell.daisy = "black" + else + cell.daisy = "white" + end + else + cell.daisy = "empty" + end + end, + execute = update, + temperature = model.temperature, + albedo = model.albedo, + maxLifeSpan = model.lifeSpan, + bornNewDaisy = bornNewDaisy, + calculateSoilHeat = calculateSoilHeat, + killDaisy = killDaisy, + calculateProbRepro = calculateProbRepro + } + + model.cs = CellularSpace{ + xdim = model.dim, + instance = model.cell, + emptySpace = function(cs) + local traj = Trajectory{target = cs, select = function(cell) return cell.daisy == "empty" end} + return #traj + end, + whiteDaisy = function(cs) + local traj = Trajectory{target = cs, select = function(cell) return cell.daisy == "white" end} + return #traj + end, + blackDaisy = function(cs) + local traj = Trajectory{target = cs, select = function(cell) return cell.daisy == "black" end} + return #traj + end + } + + model.cs:createNeighborhood{ + strategy = "vonneumann" + } + + model.chart = Chart{ + target = model.cs, + select = {"blackDaisy", "whiteDaisy", "emptySpace"}, + title = "Population x Time", + yLabel = "#individual" + } + + model.cs:notify(0) + + model.map1 = Map{ + target = model.cs, + select = "SoilHeat", + max = model.temperature.max, + min = model.temperature.min, + slices = 6, + color = "OrRd" + } + + model.map2 = Map{ + target = model.cs, + select = "daisy", + value = {"black", "white", "empty"}, + color = {"black", "white", "green"} + } + + model.timer = Timer{ + Event{action = model.cs} + } + end +} + diff --git a/lua/Excitable.lua b/lua/Excitable.lua new file mode 100644 index 0000000..d9d97bf --- /dev/null +++ b/lua/Excitable.lua @@ -0,0 +1,58 @@ + +--- Excitable model from Wiener & Rosenbleuth (1946). +-- Arch. Inst. Cardiol. Mexico 16, 202-265. +-- Reffered in Ermentrout & Edelstein-Keshet (1993). +-- Cellular Automata Approaches to Biological Modeling. +-- Jornal of Theoretical Biology, 160, 97-133. +-- @arg data.dim The x and y dimensions of space. +-- @arg data.finalTime A number with the final time of the simulation. +-- @image excitable.bmp +Excitable = Model{ + finalTime = 500, + dim = 50, + init = function(model) + model.cell = Cell{ + init = function(cell) + if (cell.x == 20 and cell.y == 25) or (cell.x == 30 and cell.y == 25) then + cell.state = 1 + else + cell.state = 0 + end + end, + execute = function(cell) + if cell.past.state == 0 then + forEachNeighbor(cell, function(cell, neigh) + if neigh.past.state > 0 then + cell.state = 1 + end + end) + elseif cell.past.state == 1 then cell.state = 2 + elseif cell.past.state == 2 then cell.state = 3 + elseif cell.past.state == 3 then cell.state = 4 + elseif cell.past.state == 4 then cell.state = 5 + elseif cell.past.state == 5 then cell.state = 0 end + end + } + + model.cs = CellularSpace{ + xdim = model.dim, + instance = model.cell + } + + model.cs:createNeighborhood{strategy = "vonneumann"} + + model.timer = Timer{ + Event{action = model.cs} + } + + model.map = Map{ + target = model.cs, + select = "state", + min = 0, + max = 5, + slices = 6, + color = "Blues" + } + end +} + diff --git a/lua/Fire.lua b/lua/Fire.lua index e40f6e4..267cbde 100644 --- a/lua/Fire.lua +++ b/lua/Fire.lua @@ -1,66 +1,68 @@ - --- A Model to simulate fire in the forest. --- @arg data.finalTime A number with the final time of the simulation. +-- @arg data.finalTime A number with the final simulation time. -- @arg data.dim A number with the x and y size of space. -- @arg data.empty The percentage of empty cells in the beginning of the -- simulation. It must be a value between 0 and 1, with default 0.1. -- @image fire.bmp -Fire = CellularAutomataModel{ +Fire = Model{ finalTime = 100, empty = Choice{min = 0, max = 1, default = 0.1}, dim = 60, - space = function(model) - local cell = Cell{ + init = function(model) + model.cell = Cell{ init = function(cell) if Random():number() > model.empty then cell.state = "forest" else cell.state = "empty" end + end, + execute = function(cell) + if cell.past.state == "burning" then + cell.state = "burned" + elseif cell.past.state == "forest" then + local burning = countNeighbors(cell, "burning") + + if burning > 0 then + cell.state = "burning" + end + end end } - local cs = CellularSpace{ + model.cs = CellularSpace{ xdim = model.dim, - instance = cell + instance = model.cell, + burned = function(self) + return #Trajectory{target = self, select = function(cell) + return cell.state == "burned" + end} + end, + forest = function(self) + return #Trajectory{target = self, select = function(cell) + return cell.state == "forest" + end} + end } - cs:sample().state = "burning" - cs:createNeighborhood{strategy = "vonneumann"} - - cs.burned = function() - return #Trajectory{target = cs, select = function(cell) - return cell.state == "burned" - end} - end - - cs.forest = function() - return #Trajectory{target = cs, select = function(cell) - return cell.state == "forest" - end} - end + model.cs:sample().state = "burning" + model.cs:createNeighborhood{strategy = "vonneumann"} model.chart = Chart{ - target = cs, + target = model.cs, select = {"burned", "forest"} } - return cs - end, - changes = function(cell) - if cell.past.state == "burning" then - cell.state = "burned" - elseif cell.past.state == "forest" then - local burning = countNeighbors(cell, "burning") - if burning > 0 then - cell.state = "burning" - end - end - end, - map = { - select = "state", - value = {"forest", "burning", "burned", "empty"}, - color = {"green", "red", "brown", "white"} - } + model.map = Map{ + target = model.cs, + select = "state", + value = {"forest", "burning", "burned", "empty"}, + color = {"green", "red", "brown", "white"} + } + + model.timer = Timer{ + Event{action = model.cs} + } + end } diff --git a/lua/Growth.lua b/lua/Growth.lua new file mode 100644 index 0000000..dde3021 --- /dev/null +++ b/lua/Growth.lua @@ -0,0 +1,50 @@ + +--- Simple growth model. A given population starts from the center of space +-- and grows randomly. +-- @arg data.dim The x and y dimensions of space. +-- @arg data.finalTime A number with the final time of the simulation. +-- @arg data.probability The probability of a cell to become alive once +-- it has an alive neighbor. +-- @image growth.bmp +Growth = Model{ + finalTime = 250, + dim = 100, + probability = 0.05, + init = function(model) + model.cell = Cell{ + init = function(cell) + if cell.x == model.dim / 2 and cell.y == model.dim / 2 then + cell.state = "alive" + else + cell.state = "empty" + end + end, + execute = function(cell, ev) + local count = countNeighbors(cell, "alive") + + if cell.past.state == "empty" and count > 0 and Random():number() < model.probability then + cell.state = "alive" + end + end + } + + model.cs = CellularSpace{ + xdim = model.dim, + instance = model.cell, + } + + model.cs:createNeighborhood{strategy = "vonneumann"} + + model.map = Map{ + target = model.cs, + select = "state", + value = {"alive", "empty"}, + color = {"white", "black"} + } + + model.timer = Timer{ + Event{action = model.cs} + } + end +} + diff --git a/lua/Life.lua b/lua/Life.lua index b98ae02..c3bd5df 100644 --- a/lua/Life.lua +++ b/lua/Life.lua @@ -21,69 +21,70 @@ patterns.default = "random" -- They should be used without ".life" extension. The default pattern is -- "random", with half alive cells randomly distributed in space. -- @image life.bmp -Life = CellularAutomataModel{ +Life = Model{ finalTime = 100, dim = 30, pattern = Choice(patterns), - space = function(model) - local cell + init = function(model) + model.cell = Cell{ + init = function(cell) + cell.state = "dead" + end, + execute = function(cell) + local alive = countNeighbors(cell, "alive") - if model.pattern ~= "random" then - cell = Cell{ - init = function(cell) + if alive < 2 then + cell.state = "dead" + elseif alive > 3 then cell.state = "dead" + elseif alive == 3 and cell.past.state == "dead" then + cell.state = "alive" end - } - else - cell = Cell{ - init = function(cell) - if Random():number() > 0.5 then - cell.state = "alive" - else - cell.state = "dead" - end + end + } + + if model.pattern == "random" then + model.cell.init = function(cell) + if Random():number() > 0.5 then + cell.state = "alive" + else + cell.state = "dead" end - } + end end - local cs = CellularSpace{ + model.cs = CellularSpace{ xdim = model.dim, - instance = cell + instance = model.cell } if model.pattern ~= "random" then local pattern = getLife(model.pattern) - if cs.xdim < pattern.xdim then + if model.cs.xdim < pattern.xdim then customError("CellularSpace should have dim at least "..pattern.xdim..".") - elseif cs.ydim < pattern.ydim then + elseif model.cs.ydim < pattern.ydim then customError("CellularSpace should have dim at least "..pattern.ydim..".") end - local xloc = math.floor(cs.xdim/2 - pattern.xdim/2) - local yloc = math.floor(cs.ydim/2 - pattern.ydim/2) + local xloc = math.floor(model.cs.xdim/2 - pattern.xdim/2) + local yloc = math.floor(model.cs.ydim/2 - pattern.ydim/2) - insertPattern(cs, pattern, xloc, yloc) + insertPattern(model.cs, pattern, xloc, yloc) end - cs:createNeighborhood{wrap = true} + model.cs:createNeighborhood{wrap = true} - return cs - end, - changes = function(cell) - local alive = countNeighbors(cell, "alive") - if alive < 2 then - cell.state = "dead" - elseif alive > 3 then - cell.state = "dead" - elseif alive == 3 and cell.past.state == "dead" then - cell.state = "alive" - end - end, - map = { - select = "state", - value = {"dead", "alive"}, - color = {"black", "white"} - } + model.map = Map{ + target = model.cs, + select = "state", + value = {"dead", "alive"}, + color = {"black", "white"} + } + + model.timer = Timer{ + Event{action = model.cs} + } + end } diff --git a/lua/Oscillator.lua b/lua/Oscillator.lua new file mode 100644 index 0000000..6deadc0 --- /dev/null +++ b/lua/Oscillator.lua @@ -0,0 +1,49 @@ +local amount = {0, -1, -2, -2, -3, -2, -2, -1, 0, 1, 2, 2, 3, 2, 2, 1} + +--- Oscillator model from Ermentrout & Edelstein-Keshet (1993). +-- Cellular Automata Approaches to Biological Modeling. +-- Jornal of Theoretical Biology, 160, 97-133. +-- @arg data.dim The x and y dimensions of space. +-- @arg data.finalTime A number with the final time of the simulation. +-- @image oscillator.bmp +Oscillator = Model{ + finalTime = 400, + dim = 50, + init = function(model) + model.cell = Cell{ + init = function(cell) + cell.state = Random():integer(0, 15) + end, + execute = function(cell) + local count = countNeighbors(cell, 0) + + if count > 0 then + cell.state = (cell.past.state + amount[cell.past.state + 1] + 1) % 16 + else + cell.state = (cell.state + 1) % 16 + end + end + } + + model.cs = CellularSpace{ + xdim = model.dim, + instance = model.cell + } + + model.cs:createNeighborhood() + + model.map = Map{ + target = model.cs, + select = "state", + min = 0, + max = 15, + slices = 16, + color = "Blues" + } + + model.timer = Timer{ + Event{action = model.cs} + } + end +} + diff --git a/lua/Parasit.lua b/lua/Parasit.lua new file mode 100644 index 0000000..5a23be4 --- /dev/null +++ b/lua/Parasit.lua @@ -0,0 +1,52 @@ +--- Parasit model from Hassell et al. (1991). +-- Spatial structure and chaos in insect population +-- dynamics. Nature, Lond. 353, 255-258. +-- @arg data.dim The x and y dimensions of space. +-- @arg data.finalTime A number with the final time of the simulation. +-- @image parasit.bmp +Parasit = Model{ + finalTime = 500, + dim = 50, + init = function(model) + model.cell = Cell{ + init = function(cell) + cell.state = Random():integer(0, 8) + end, + execute = function(cell) + local count1 = countNeighbors(cell, 1) + local count5 = countNeighbors(cell, 5) + + if cell.past.state == 0 and count1 > 0 then cell.state = 1 + elseif cell.past.state == 1 then cell.state = 2 + elseif cell.past.state == 2 then cell.state = 3 + elseif cell.past.state == 3 and count5 > 0 then cell.state = 4 + elseif cell.past.state == 4 then cell.state = 5 + elseif cell.past.state == 5 then cell.state = 6 + elseif cell.past.state == 6 then cell.state = 7 + elseif cell.past.state == 7 then cell.state = 8 + elseif cell.past.state == 8 then cell.state = 0 end + end + } + + model.cs = CellularSpace{ + xdim = model.dim, + instance = model.cell, + } + + model.cs:createNeighborhood{strategy = "vonneumann"} + + model.map = Map{ + target = model.cs, + select = "state", + min = 0, + max = 8, + slices = 9, + color = "Blues" + } + + model.timer = Timer{ + Event{action = model.cs} + } + end +} + diff --git a/lua/Parity.lua b/lua/Parity.lua new file mode 100644 index 0000000..c292ad3 --- /dev/null +++ b/lua/Parity.lua @@ -0,0 +1,51 @@ +--- Parity model, by Nigel Gilbert. See +-- modelingcommons.org/browse/one_model/3381. +-- @arg data.dim The x and y dimensions of space. +-- @arg data.finalTime A number with the final time of the simulation. +-- @image parity.bmp +Parity = Model{ + finalTime = 500, + dim = 50, + init = function(model) + model.cell = Cell{ + init = function(cell) + if (cell.x == 10 and cell.y == 25) or (cell.x == 40 and cell.y == 25) then + cell.state = "on" + else + cell.state = "off" + end + end, + execute = function(cell) + local count = countNeighbors(cell, "on") + + if count == 1 or count == 3 then + cell.state = "on" + else + cell.state = "off" + end + end + } + + model.cs = CellularSpace{ + xdim = model.dim, + instance = model.cell + } + + model.cs:createNeighborhood{ + strategy = "vonneumann", + wrap = true + } + + model.map = Map{ + target = model.cs, + select = "state", + value = {"on", "off"}, + color = {"black", "white"} + } + + model.timer = Timer{ + Event{action = model.cs} + } + end +} + diff --git a/lua/Snow.lua b/lua/Snow.lua new file mode 100644 index 0000000..760d2f0 --- /dev/null +++ b/lua/Snow.lua @@ -0,0 +1,50 @@ +--- Snow falling from the sky. +-- @arg data.dim The x and y dimensions of space. +-- @arg data.finalTime A number with the final time of the simulation. +-- @arg data.probability The probability of a cell on the top of space +-- to change its state to snow. +-- @image snow.bmp +Snow = Model{ + finalTime = 600, + dim = 50, + probability = 0.02, + init = function(model) + model.cell = Cell{ + init = function(cell) + cell.state = "empty" + end, + execute = function(cell, ev) + if cell.y == 0 then + if cell.past.state == "empty" and ev:getTime() < model.finalTime - model.dim and Random():number() < model.probability then + cell.state = "snow" + else + cell.state = "empty" + end + elseif cell.past.state == "snow" and cell.y < model.dim - 1 and cell.parent:get(cell.x, cell.y + 1).past.state == "empty" then + cell.state = "empty" + elseif cell.parent:get(cell.x, cell.y - 1).past.state == "snow" then + cell.state = "snow" + end + end + } + + model.cs = CellularSpace{ + xdim = model.dim, + instance = model.cell, + } + + model.cs:createNeighborhood{strategy = "vonneumann"} + + map = Map{ + target = model.cs, + select = "state", + value = {"snow", "empty"}, + color = {"white", "black"} + } + + model.timer = Timer{ + Event{action = model.cs} + } + end +} + diff --git a/lua/SolidDiffusion.lua b/lua/SolidDiffusion.lua new file mode 100644 index 0000000..e8c1afd --- /dev/null +++ b/lua/SolidDiffusion.lua @@ -0,0 +1,63 @@ +--- This model describes how diffusion occurs between two adjacent solids. +-- It is based on NetLogo Solid Diffusion model http://ccl.northwestern.edu/netlogo/models/SolidDiffusion. +-- Solid diffusion is material transport by atomic motion, this phenomena is exhaustively studied in fields as materials science, physics, biology, geology, engineering and chemistry. +-- In this model we demonstrate that the Vacancy Diffusion Mechanism is caused by missing atoms in the metal crystal (Vacancies). These vacancies are occupied by atoms that move from areas of high concentration of Atom of type B to areas with low concentration, until the concentration is equal throughtout the sample. +-- The first version of this implementation was developed by Yasmine and John, as final work for Environmental Modeling course in +-- Erasmus Mundus program, Munster University, 2014. It still needs further development. +-- @arg data.finalTime The final simulation time. +-- @arg data.dim The x and y dimensions of space. +SolidDiffusion = Model{ + dim = 31, + finalTime = 400, + init = function(model) + model.cell = Cell{ + init = function(cell) + local middle = math.floor(cell.parent.xdim / 2) + + local a = cell.x + + if a < middle then + cell.cover = "atom1" + elseif a > middle then + cell.cover = "atom2" + else -- a == middle + cell.cover = "vacancy" + end + end, + execute = function(cell) + if cell.past.cover == "vacancy" then + local neighbor = cell:getNeighborhood():sample() + + -- not moving empty neighbors + if neighbor.past.cover ~= "vacancy" then + -- not moving twice the same atom + if neighbor.cover ~= "vacancy" then + -- move + cell.cover = neighbor.past.cover + neighbor.cover = "vacancy" + end + end + end + end + } + + model.cs = CellularSpace{ + xdim = model.dim, + instance = model.cell + } + + model.cs:createNeighborhood() + + model.map = Map{ + target = model.cs, + select = "cover", + value = {"vacancy", "atom1", "atom2"}, + color = {"black", "green", "blue"} + } + + model.timer = Timer{ + Event{action = model.cs} + } + end +} + diff --git a/snapshots/DaisyWorld-chart-1.bmp b/snapshots/DaisyWorld-chart-1.bmp new file mode 100644 index 0000000000000000000000000000000000000000..723951d0110c410bb06bceaab876bede88888c3a GIT binary patch literal 900054 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 literal 0 HcmV?d00001 diff --git a/snapshots/DaisyWorld-map-2-begin.bmp b/snapshots/DaisyWorld-map-2-begin.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3d830d12e7a49336430c6f2017e1bc60a4c82158 GIT binary patch literal 279434 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 literal 0 HcmV?d00001 diff --git a/snapshots/Growth-map-1-end.bmp b/snapshots/Growth-map-1-end.bmp new file mode 100644 index 0000000000000000000000000000000000000000..396a3b47c21da3fcc85a6c2852187e1470ccd817 GIT binary patch literal 279434 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 literal 0 HcmV?d00001 diff --git a/snapshots/Oscillator-map-1-begin.bmp b/snapshots/Oscillator-map-1-begin.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c19ea5b14be92944a9052a27fd1554cf7d36362c GIT binary patch literal 279434 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 ItKRj00W{Mw=>Px# literal 0 HcmV?d00001 diff --git a/snapshots/Oscillator-map-1-end.bmp b/snapshots/Oscillator-map-1-end.bmp new file mode 100644 index 0000000000000000000000000000000000000000..db759a4d17c0a400adbb38bfc92870c668ce0e8c GIT binary patch literal 279434 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 Sm`O9~Iyo^13KPM-GWq|z9b3@= literal 0 HcmV?d00001 diff --git a/snapshots/Parasit-map-1-begin.bmp b/snapshots/Parasit-map-1-begin.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3d1723c531e16c166244108f52774f11b00e637a GIT binary patch literal 279434 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 literal 0 HcmV?d00001 diff --git a/snapshots/SolidDiffusion-map-1-begin.bmp b/snapshots/SolidDiffusion-map-1-begin.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d47fa4e9e0ba644380fca5dfb809b6d3efb3967f GIT binary patch literal 279434 zcmeI#F>b;@07TKXM3<5#N1&z20YaTFr^=xNYez~GrT>ebWg}!7G|Xe*{p0I)8vF4! zugkoy+t0O)*ZubRoUfl>#&I1t_J_N3*#v$+#6M5Ix8Yngfo1FHt7Ind|FLKtz3rI* zlPf2{?vCYfv{z$BBcM%qaxnPjq+0Fz9%8fhn)WRl5N0!%X5YNVZHl1V08 z2{6fItC4n+NhXn1Wwi;?v zCYfv{z$BBcM%qaxnPjq+0Fz9%8fhn)WRl5N0!%X5YNVZHl1V082{6fItC4n+NhXn1Wwi;?vCYfv{z$BBcM%qax znPjq+0Fz9%8fhn)WRl5N0!%X5YNVZHl1V082{6fItC4n+NhXn1Wwi;?vCYfv{z$BBcM%qaxnPjq+0Fz9%8fhn) zWRl5N0!%X5YNVZHl1V082{6fItC4n+NhXn1Wwi;?vCYfv{z$BBcM%qaxnPjq+0Fz9%8fhn)WRl5N0!%X5YNVZH zl1V082{6fItC4n+NhXn1Wwi;?vCYfv{z$BBcM%qaxnPjq+0Fz9%8fhn)WRl5N0!%X5YNVZHl1V082{6fItC4n+ zNhXn1Wwi;?vCYfv{z$BBc zM%qaxnPjq+0Fz9%8fhn)WRl5N0!%X5YNVZHl1V082{6fItC4n+NhXn1Wwi;?vCYfv{z$BBcM%qaxnPjq+0Fz9% z8fhn)WRl5N0!%X5YNVZHl1V082{6fItC4n+NhXn1Wwi;?vCYfv{z$BBcM%qaxnPjq+0Fz9%8fhn)WRl5N0!%X5 zYNVZHl1V082{6fItC4n+NhXn1Wwi;?vCYfv{z$BBcM%qaxnPjq+0Fz9%8fhn)WRl5N0!%)o$p;+)Ui<(6 literal 0 HcmV?d00001 diff --git a/snapshots/SolidDiffusion-map-1-end.bmp b/snapshots/SolidDiffusion-map-1-end.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7e2ce8b4f68b7c551288ed2cad120052538edaaa GIT binary patch literal 279434 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