Infiltração de óleos em solos porosos

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.

O modelo

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:

  1. O óleo é espalhado uniformemente na primeira linha de patches, a qual é interpretada como sendo a superfície do solo.
  2. Em cada iteração o óleo contido em cada patch contaminado pode infiltrar-se, com probabilidade p igual à percentagem de espaço livre (porosidade), para cada patch adjacente, na diagonal, para a esquerda ou para a direita.

Utilização

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.

Conclusões

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%.

Breve análise do código

O modelo está dividido nas seguintes secções:

Variáveis globais
linha-da-frentecontém os patches recém-contaminados
quantidade-de-oleocontém a quantidade de solo saturado com óleo desdo início da simulação
Rotinas principais
prepararlimpa e inicia todas as variáveis, cria uma linha de patches vermelhos representando a superfície contaminada do solo.
executaritera 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.
Rotinas auxiliares
percolarrotina responsável pelas regras de contaminação.
ecran-seguinterotina responsável pela passagem ao écran seguinte.
desenha-graficosrotina que desenha os gráficos.

O código

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:

Rotinas principais
preparar
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.

executar
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.

Rotinas auxiliares
percolar
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.

ecran-seguinte
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).

desenha-graficos
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.