Neste capítulo mostramos que além dos valores "normais" das variáveis (números, strings, true, false), os valores podem também ser agentes / conjuntos de agentes, característica esta que nos vai permitir escrever códigos computacionalmente mais eficientes. Mostraremos igualmente como se usa mais do que um gráfico em NetLogo.
Suponhamos que introduzimos uma pedra num balde com água. Qual é a probabilidade do centro da pedra ficar molhado? Esta probabilidade depende da porosidade da pedra e nuns casos a resposta é um (pedra-pomes) e noutros é zero (basalto). Apesar de existirem materiais com porosidades que variam de uma forma contínua, o seu comportamento é quase sempre semelhante ao da pedra-pomes ou ao do basalto, ou seja, a resposta é quase sempre um ou zero, i.e. os materiais são permeáveis ou impermeáveis.
Contudo, o comportamento de materiais com porosidades numa gama muito estreita pode ser bastante diferente. Nesses casos a água chega até ao centro da pedra, mas demora uma eternidade a fazê-lo. Esse valor da porosidade separa os materiais permeáveis dos impermeáveis. Como a mudança de comportamento é rápida, dizemos que existe uma transição a que chamamos transição de percolação.
Este programa segue de perto o modelo de percolação introduzido por Broadbent e Hammersley nos anos 50. O qual consiste no seguinte guião para os patches:
O óleo derramado é representado por patches vermelhos (gotas de óleo) que ocupam toda a largura no topo da caixa de simulação. As gotas de óleo aparecem alternadas, pois os espaços livres e ocupados do solo alternam-se.
Os patches castanhos representam o solo através do qual o óleo flúi sob a acção da gravidade. Os patches vermelhos representam os poros do solo recém-contaminados e os patches pretos representam os poros do solo contaminados em iterações anteriores. A porosidade caracteriza a maior ou menor resistência do solo ao fluxo de óleo: é nula nos solos impermeáveis e 100% no limite oposto. Esta pode ser alterada no cursor porosidade.
O NetLogo usa condições de fronteira periódicas na vertical (voltaremos a este ponto mais tarde), pelo que o óleo que chega ao fundo da caixa de simulação pode continuar a infiltrar-se a partir do topo. Contudo o programa pára automaticamente quando a frente de óleo deixa de avançar.
Os gráficos mostram a extensão da frente de óleo (vermelho) e a quantidade de solo saturado / contaminado (preto).
O leitor é convidado a experimentar este modelo no seguinte applet:
Para correr este modelo no ambiente NetLogo, basta seguir o link percolação, se tiver instalado o software.
O tipo de fluxo e a extensão do derrame dependem da porosidade do solo, que determina a probabilidade de percolação. O comportamento do sistema depende criticamente desta probabilidade. O modelo é caracterizado por dois regimes: fluxos contínuos (derrames extensos) para porosidades elevadas, onde o óleo se infiltra écran após écran, após écran:
e fluxos superficiais (derrames confinados) para porosidades baixas.
A transição entre os dois regimes é rápida e ocorre numa gama estreita de porosidades, na vizinhança dos 64.5%.
O modelo está dividido nas seguintes secções:
linha-da-frente | contém os patches recém-contaminados |
quantidade-de-oleo | contém a quantidade de solo saturado com óleo desdo início da simulação |
preparar | limpa e inicia todas as variáveis, cria uma linha de patches vermelhos representando a superfície contaminada do solo. |
executar | itera as regras de contaminação dos patches, actualiza as variáveis, desenha os gráficos, passa ao écran seguinte quando a frente de óleo chega ao fundo do écran, ou pára o programa se não houver patches recém-contaminados. |
percolar | rotina responsável pelas regras de contaminação. |
ecran-seguinte | rotina responsável pela passagem ao écran seguinte. |
desenha-graficos | rotina que desenha os gráficos. |
globals [ linha-da-frente quantidade-de-oleo ] to preparar ca set quantidade-de-oleo 0 ask patches [ set pcolor brown ] set linha-da-frente patches with [ pycor = max-pycor ] ask linha-da-frente [ if (pxcor mod 2 = 0) [ set pcolor red ] ] desenha-graficos end to executar if not any? linha-da-frente with [ pcolor = red ][ stop ] percolar desenha-graficos ecran-seguinte end to percolar ask linha-da-frente with [ pcolor = red ][ ask patches at-points [ [-1 -1] [1 -1] ][ if (pcolor = brown) and (random-float 100 < porosidade) [ set pcolor red ] ] set pcolor black set quantidade-de-oleo quantidade-de-oleo + 1 ] set linha-da-frente patches-from linha-da-frente [ patch-at 0 -1 ] end to ecran-seguinte if pycor-of one-of linha-da-frente = max-pycor [ display ask patches with [ pcolor = black ][ set pcolor brown ] ] end to desenha-graficos set-current-plot "Oleo Percolado" plot count linha-da-frente with [pcolor = red] set-current-plot "Terra contaminada" plot quantidade-de-oleo end
Vejamos em detalhe o que há de novo no código:
to preparar ca set quantidade-de-oleo 0 ask patches [ set pcolor brown ] set linha-da-frente patches with [ pycor = max-pycor ] ask linha-da-frente [ if (pxcor mod 2 = 0) [ set pcolor red ] ] desenha-graficos end
Em NetLogo as variáveis também podem ser conjuntos de agentes. Tal é o caso da variável linha-da-frente, que contém os patches recém-contaminados.
to executar if not any? linha-da-frente with [ pcolor = red ][ stop ] percolar desenha-graficos ecran-seguinte end
Esta rotina, assim como a rotina percolar, ilustram o interesse de que as variáveis possam ser conjuntos de agentes, pois permitem tornar o programa muito mais rápido. Por exemplo a instrução if not any? linha-da-frente with [ pcolor = red ][ stop ] é equivalente à instrução if not any? patches with [ pcolor = red ][ stop ], mas, no segundo caso, o NetLogo verifica linha a linha se há algum patch de cor vermelha, o que é computacionalmente muito ineficiente, principalmente quando a linha-da-frente está próxima do fundo do écran. A vantagem da instrução if not any? linha-da-frente with [ pcolor = red ][ stop ] é que os patches vermelhos só são procurados na única linha onde podem estar.
to percolar ask linha-da-frente with [ pcolor = red ][ ask patches at-points [ [-1 -1] [1 -1] ][ if (pcolor = brown) and (random-float 100 < porosidade) [ set pcolor red ] ] set pcolor black set quantidade-de-oleo quantidade-de-oleo + 1 ] set linha-da-frente patches-from linha-da-frente [ patch-at 0 -1 ] end
A rotina começa por procurar os patches de cor vermelha e contamina os patches adjacentes, abaixo de cada patch vermelho, na diagonal. Esses patches são referenciados através da instrução patches at-points [[-1 -1] [1 -1]], onde cada par [x y] referencia o patch à distância (x,y) do agente que o chamou, neste caso o patch de que a instrução ask linha-da-frente with [ pcolor = red ][ comandos ] agora se encarrega.
A instrução set linha-da-frente patches-from linha-da-frente [ patch-at 0 -1 ] actualiza a linha-da-frente para a única linha de patches que pode ter patches vermelhos. A instrução patches-from linha-da-frente [ patch-at 0 -1 ] referencia os patches referenciados pelo repórter linha-da-frente [ patch-at 0 -1 ], i.e. os patches que estão à frente de cada um dos patches da linha-da-frente.
Para tornar o modelo mais realista foi alterada a forma do mundo, este só enrola na vertical e os patches que na horizontal estão para lá dos bordos são ignorados. Tal é feito dando os seguintes parâmetros na caixa de diálogo do mundo que aparece quando se carrega no botão :
e seleccionando apenas a opção World wraps vertically.
to ecran-seguinte if pycor-of one-of linha-da-frente = max-pycor [ display ask patches with [ pcolor = black ][ set pcolor brown ] ] end
Força o display da linha-da-frente quando esta atinge o fundo do écran e de seguida limpa o écran, para que a simulação continue no topo (o mundo enrola na vertical).
to desenha-graficos set-current-plot "Oleo Percolado" plot count linha-da-frente with [pcolor = red] set-current-plot "Terra contaminada" plot quantidade-de-oleo end
Quando temos mais do que um gráfico para desenhar precisamos de dizer ao NetLogo em que gráfico devem ser desenhados os pontos. Para tal usamos a instrução set-current-plot "Titulo do grafico" e de seguida usamos as instruções plot ou plotxy.