universidade estadual de campinas …lotavio/tgs/2012_estudo do método...fluidos, na qual o custo...

85
UNIVERSIDADE ESTADUAL DE CAMPINAS FACULDADE DE ENGENHARIA MECÂNICA Relatório Final Trabalho Final de Graduação II Estudo do Método Lattice Boltzmann aplicado à Fluidodinâmica: Uso de Simulador em GPU e Desenvolvimento de um Simulador em Linguagem C Autor: Fabíola Martins Campos de Oliveira Orientador: Prof. Dr. Luiz Otávio S. Ferreira Campinas, novembro de 2012.

Upload: others

Post on 11-Mar-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

UNIVERSIDADE ESTADUAL DE CAMPINAS

FACULDADE DE ENGENHARIA MECÂNICA

Relatório Final

Trabalho Final de Graduação II

Estudo do Método Lattice Boltzmann aplicado à

Fluidodinâmica: Uso de Simulador em GPU e

Desenvolvimento de um Simulador em Linguagem C

Autor: Fabíola Martins Campos de Oliveira

Orientador: Prof. Dr. Luiz Otávio S. Ferreira

Campinas, novembro de 2012.

Page 2: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

UNIVERSIDADE ESTADUAL DE CAMPINAS

FACULDADE DE ENGENHARIA MECÂNICA

Relatório Final

Trabalho Final de Graduação II

Estudo do Método Lattice Boltzmann aplicado à

Fluidodinâmica: Uso de Simulador em GPU e

Desenvolvimento de um Simulador em Linguagem C

Autor: Fabíola Martins Campos de Oliveira

Orientador: Prof. Dr. Luiz Otávio Saraiva Ferreira

Curso: Engenharia de Controle e Automação

Trabalho Final de Graduação apresentado à Comissão de Graduação da Faculdade

de Engenharia Mecânica, como requisito para a obtenção do título de Engenheiro de

Automação e Controle.

Campinas, 2012

S.P. – Brasil

Page 3: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

i

Dedico este trabalho à minha família e ao meu namorado pelo apoio e incentivo.

Page 4: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

ii

Agradecimentos

Este trabalho não poderia ser realizado sem a ajuda de diversas pessoas às quais

presto minha homenagem:

Ao Prof. Dr. Luiz Otávio Saraiva Ferreira, pela orientação e valiosos conhecimentos

passados.

À minha família, que sempre me apoiou e também é responsável por minhas

realizações.

Ao meu namorado, Helói Genari, que sempre me ajudou e incentivou.

A todos os professores que contribuíram para minha formação.

Aos funcionários e colegas.

À Unicamp pela infraestrutura disponibilizada.

À FAPESP, pelo financiamento do Laboratório de Simulações Multifísicas.

E à população brasileira pelo financiamento das instituições Unicamp e FAPESP.

Page 5: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

iii

Resumo

O recente uso de unidades de processamento gráfico de propósito geral (GPGPUs)

tem contribuído para a aceleração de cálculos complexos, diminuindo assim o custo

computacional. Essa ferramenta vem sendo aplicada com êxito na área de mecânica dos

fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância

econômica, há um grande interesse nessa área, com potencial aumento de eficiência,

dado que os algoritmos atuais experimentam bastante lentidão. Nesse contexto, este

trabalho objetiva estudar e simular o escoamento de fluidos bifásicos com o método Lattice

Boltzmann. Para isso, inicialmente se utilizou o simulador Sailfish, baseado na linguagem

CUDA C – para unidades de processamento gráfico (GPUs) NVIDIA – com scripts para a

simulação na linguagem Python. Esse simulador se baseia no método Lattice Boltzmann,

que simplifica a modelagem através da abordagem de partículas de fluido, satisfazendo as

equações de Navier-Stokes no nível macroscópico. Além de o método aumentar a

eficiência da simulação, o uso de GPUs também o faz, através da paralelização. Alguns

exemplos de autômatos celulares, que originaram o método, foram implementados em

CUDA C e os escoamentos monofásicos mais fundamentais foram simulados no Sailfish, a

fim de validar o simulador. Em seguida, realizaram-se simulações de escoamentos

bifásicos passando por dois tipos de micromisturadores: o ômega e o tesla, também no

Sailfish. O trabalho até essa etapa rendeu um artigo publicado no 14th Brazilian Congress

of Thermal Sciences and Engineering, em anexo (Saraiva Ferreira & Martins Campos de

Oliveira, 2012). Apesar de o Sailfish atender a algumas necessidades, avaliou-se a

construção de um simulador próprio, que cumprisse bem seu papel em todos os requisitos.

Dessa forma, em um primeiro passo, é desenvolvido um simulador em linguagem C,

visando à sua tradução para a linguagem CUDA C e um alto desempenho no

processamento.

Palavras-Chave: Simulação, Microfluídica, Método Lattice Boltzmann

Page 6: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

iv

Lista de Figuras

Figura 2.1. Rede quadrada do modelo HPP. Fonte: (Wolf-Gladrow, 2000). 6

Figura 2.2. Única configuração que gera colisão e seu resultado final. Pode ser

representado por células (a) ou por vetores (b). Fonte: (Wolf-Gladrow, 2000). 6

Figura 2.3. Ângulo de contato de 90º entre fluido e superfície sólida. Fonte:

(Sukop, 2007). 11

Figura 4.1. Autômato Celular 1D, regra 2 e raio 2. 19

Figura 4.2. Autômato Celular 1D, regra 20 e raio 1. 21

Figura 4.3. Autômato Celular 1D, regra 52 e raio 1. 22

Figura 4.4. Vizinhança von Neumann raio 1. Fonte: (Wolf-Gladrow, 2000). 23

Figura 4.5. Jogo de Fredkin com a letra F como padrão a ser replicado. 24

Figura 4.6. Vizinhança de Moore de raio um. Fonte: (Wolf-Gladrow, 2000). 25

Figura 4.7. Jogo Life. 26

Figura 4.8. Escoamento de Poiseuille; x é o tamanho da rede no eixo x. Fonte:

(Sukop, 2007). 27

Figura 4.9. Escoamento de Poiseuille: resultado da simulação no Sailfish. 27

Figura 4.10. Visão simplificada do efeito do comprimento de entrada; u é a

velocidade, uavg é a velocidade média, r é a distância medida a partir do centro

do tubo e a é o raio do tubo. Fonte: (Sukop, 2007). 28

Figura 4.11. Efeito do comprimento de entrada simulado no Sailfish. 28

Figura 4.12. Escoamento laminar passando por cilindro. Fonte: (Sukop, 2007). 29

Figura 4.13. Escoamento laminar passando por cilindro – simulação em Sailfish. 29

Figura 4.14. Escoamento turbulento simulado (acima) e fotografado (abaixo).

Fonte: (Sukop, 2007). 30

Figura 4.15. Escoamento turbulento simulado no Sailfish. 30

Figura 4.16. Foto da formação de vórtices (acima) e simulação (abaixo). Fonte:

(Sukop, 2007). 31

Figura 4.17. Simulação do Sailfish; a primeira imagem mostra a magnitude da

Page 7: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

v

velocidade e as quatro imagens abaixo representam diferentes visualizações

para a vorticidade. 31

Figura 4.18. Vetores de velocidade no escoamento. 31

Figura 4.19. Linhas de fluxo. 31

Figura 4.20. Separação da camada limite. Fonte: (Sukop, 2007). 32

Figura 4.21. Separação da camada limite no simulador. 32

Figura 4.22. Escoamento bifásico entre placas paralelas no Sailfish (a flecha

aponta o obstáculo). 33

Figura 4.24. Dimensões do microrreator Ômega. Fonte: (Arias, 2010) 34

Figura 4.25. Escoamento de etanol e óleo de mamona em microrreator Ômega;

seis instantes de tempo distintos e não adjacentes. 36

Figura 4.26. Escoamento de etanol e óleo de mamona passando por três

microrreatores Ômega em cascata; seis instantes de tempo distintos e não

adjacentes. 36

Figura 4.27. Dimensões do microrreator Tesla. Fonte: (Arias, 2010) 37

Figura 4.28. Escoamento de etanol e óleo de mamona em microrreator Tesla;

oito instantes de tempo distintos e não adjacentes. 37

Figura 4.29. Escoamento de etanol e óleo de mamona passando por três

microrreatores Tesla em cascata; quatro instantes de tempo distintos e não

adjacentes. 38

Page 8: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

vi

Lista de Tabelas

Tabela 4.1. Tabela verdade para autômato celular 1D, regra 2 e raio 2. 17

Tabela 4.2. Tabela verdade para autômato celular 1D, regra 20 e raio 1. 20

Tabela 4.3. Tabela verdade para autômato celular 1D, regra 52 e raio 1. 22

Tabela 4.4. Parâmetros dos fluidos. 35

Tabela 4.5. Parâmetros da simulação. 35

Page 9: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

vii

Nomenclatura

Letras Latinas

a estado da célula do autômato

c velocidade da rede

D diâmetro do obstáculo [m]

e velocidade

f função de distribuição de probabilidade

F força no fluido

G força de interação

j quantidade de movimento

k número de estados possíveis para a célula de um autômato

L altura do canal [m]

n número de ocupação

N número de ocupação média

P pressão cinemática [m²/s²]

p pressão [N/m²]

r raio da regra do autômato

R número de nós da rede

s coordenadas de cada nó

u velocidade do escoamento [m/s]

u’ velocidade macroscópica composta

w peso

x vetor posição

Letras Gregas

viscosidade cinemática [kg/ms]

α constante inteira que determina o estado atual de uma célula

de um autômato

Δ variação

θ ângulo de contato

ρ massa

Page 10: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

viii

ρ0 densidade de massa constante [kg/m³]

σ12 tensão interfacial entre dois fluidos

σS1 tensão interfacial entre fluido 1 e superfície

σS2 tensão interfacial entre fluido 2 e superfície

τ tempo de relaxamento

ψ densidade

operador gradiente

viscosidade de cisalhamento cinemática [m²/s]

Superescritos

(1) partícula única

A fluido 1

B fluido 2

eq equilíbrio

t tempo atual

t-1 tempo anterior

Subscritos

a direção na rede

A fluido 1

avg média

B fluido 2

fís física

i posição da célula no autômato

i+r célula à direita por r posições da posição i

i-r célula à esquerda por r posições da posição i

i-r+1 célula à esquerda por r posições da posição i+1

j incremento de uma célula

k direção do vetor da rede

lb lattice-Boltzmann

máx máxima

σ fluido 1

fluido 2

Page 11: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

ix

Abreviações

lt lattice time

lu lattice unit

Re Número de Reynolds

Siglas

CFD Fluidodinâmica computacional

CPU Unidade de processamento central

CUDA Arquitetura de dispositivo unificado para cálculos

FHP Frisch, Hasslacher e Pomeau

GB Gigabyte

GPGPU Unidade de processamento gráfico de propósito geral

GPU Unidade de processamento gráfico

HPP Hardy, de Pazzis e Pomeau

LB Método de Boltzmann em Rede

LGCA Autômatos celulares em rede de gases

RAM Memória de acesso aleatório

Page 12: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

x

Índice

1 Introdução .................................................................................................................. 1

2 Revisão Bibliográfica .................................................................................................. 3

2.1 A Equação de Navier-Stokes ...................................................................................... 3

2.2 Autômatos Celulares ................................................................................................... 4

2.3 Lattice-Gas Cellular Automata (LGCA) ....................................................................... 5

2.4 O Método Lattice Boltzmann (LB) ............................................................................... 8

2.4.1 O Método Lattice Boltzmann em escoamentos multicomponentes multifásicos .....10

2.4.2 Parâmetros da simulação .......................................................................................12

3 Procedimento Experimental ......................................................................................14

3.1 Autômatos celulares em linguagem CUDA C ............................................................14

3.2 Escoamentos no programa Sailfish............................................................................14

3.3 Implementação de simulador em linguagem C ..........................................................15

4 Resultados e Discussões ..........................................................................................16

4.1 Autômatos Celulares em linguagem CUDA C ............................................................16

4.1.1 Autômato Celular 1D, regra 2 e raio 2 .....................................................................16

4.1.2 Autômato Celular 1D, regra 20 e raio 1 ...................................................................19

4.1.3 Autômato Celular 1D, regra 52 e raio 1 ...................................................................21

4.1.4 Jogo de Fredkin ......................................................................................................23

4.1.5 Jogo Life .................................................................................................................24

4.2 Aplicação do método Lattice Boltzmann em escoamentos monofásicos no Sailfish .26

4.2.1 Escoamento de Poiseuille .......................................................................................27

4.2.2 Efeito do Comprimento de Entrada .........................................................................28

4.2.3 Escoamento Passando por Cilindro ........................................................................29

4.2.4 Escoamento Instável em Altos Números de Reynolds ............................................30

4.2.5 Separação da Camada Limite .................................................................................32

Page 13: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

xi

4.3 Aplicação do método Lattice Boltzmann em escoamentos bifásicos no Sailfish ........32

4.3.1 Escoamento bifásico entre placas paralelas ...........................................................33

4.3.2 Escoamento de álcool e óleo em microrreator Ômega ...........................................34

4.3.3 Escoamento de álcool e óleo em microrreator Tesla ..............................................37

4.4 Implementação de Simulador em Linguagem C ........................................................38

5 Conclusões e Perspectivas .......................................................................................44

5.1 Perspectivas ..............................................................................................................44

Referências Bibliográficas 46

Anexos .............................................................................................................................47

1) Artigo publicado no 14th Brazilian Congress of Thermal Sciences and Engineering 47

2) Código em linguagem C de simulador multicomponente ..........................................54

Page 14: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

1

1 Introdução

O advento da computação trouxe consigo uma grande inovação tecnológica no

setor de pesquisa e desenvolvimento acadêmico e industrial: a possibilidade de

simular problemas físicos, cortando assim custos com materiais, construção de

protótipos e/ou modelos, além de a redução do tempo necessário para se atingir um

mesmo resultado. Além disso, com este aumento na velocidade de processamento

de dados, pode-se atingir uma maior produção de conhecimento, recentemente

potencializada com o surgimento do primeiro processador gráfico (GPU) de

propósito geral (GPGPU), da NVIDIA.

A simulação de escoamento de fluidos em geral é muito importante, dado que

grande parte do conhecimento nessa área é empírica (Fox, 2006). Um tópico de

grande interesse se mostra na mistura de fluidos em microrreatores para produção

de biodiesel. Há diversas abordagens para simular esse problema, dentre os

métodos conhecidos como CFD (Computational Fluid Dynamics) tradicionais,

encontram-se: métodos das diferenças finitas, dos elementos finitos, dos elementos

de contorno, do volume finito e o método do elemento espectral (Nourgaliev, 2003).

O método Lattice Boltzmann (LB), ou método de Boltzmann em Rede, é

baseado em um algoritmo CFD não tradicional e vem ganhando grande destaque na

comunidade científica nos últimos anos ( (Nourgaliev, 2003), (Chen, 1998) e (Zhao,

2008)). Esse método é derivado do método Lattice-Gas Cellular Automata (LGCA),

que por sua vez deriva da teoria dos autômatos celulares. Os autômatos celulares

são arranjos periódicos de células individuais, podendo ser de uma ou de duas

dimensões (Wolf-Gladrow, 2000). O LGCA mais simples é o HPP, cujo nome é dado

pelas iniciais de seus criadores, Hardy, de Pazzis e Pomeau, e surgiu em 1973. Sua

importância é histórica, dado que esse autômato não obedece à equação de Navier-

Stokes no limite macroscópico. Em 1986, Frisch, Hasslacher e Pomeau propuseram

um jogo com bolas que colidiam e conservavam massa e quantidade de movimento

– o LGCA FHP. Esse jogo, no limite macroscópico, levou à equação de Navier-

Stokes, quando aplicado sob simetrias apropriadas da rede (Wolf-Gladrow, 2000).

A ideia básica por trás desses métodos é que interações microscópicas

podem ter o mesmo resultado de equações macroscópicas e, assim, podem-se

simular corretamente os escoamentos. O computador realiza cálculos baseados nas

Page 15: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

2

interações microscópicas, que devem ser simples para garantir uma boa eficiência

da simulação. Essas interações devem conservar massa e quantidade de

movimento localmente, envolvendo partículas de um único nó, e podem ser dividas

em duas etapas: colisão e propagação. A colisão realiza a troca de quantidade de

movimento, enquanto a propagação realiza o movimento propriamente dito, de

acordo com o sentido associado a essa partícula.

O método LB possui duas grandes características: simplificação da modelagem

e boa representação do comportamento de fluidos. Como um gás ou um líquido é

composto por partículas que interagem e podem ser descritas pela mecânica

clássica, e há um número muito grande dessas partículas, necessitam-se tratar os

problemas envolvendo fluidos como problemas estatísticos (Sukop, 2007). Essa é a

grande diferença entre o LGCA e o LB: o método Lattice Boltzmann lida com

funções de distribuição contínuas ao invés de lidar com partículas.

Inicialmente, esse trabalho aborda as questões relativas ao método LB, para,

em seguida, realizar simulações da mistura álcool-óleo em dois micromisturadores

em um simulador que utiliza o método LB: o Sailfish (Saraiva Ferreira & Martins

Campos de Oliveira, 2012). O Sailfish é um simulador de código aberto otimizado

para sistemas modernos de vários núcleos, principalmente GPUs, e foi

implementado em linguagem Python e CUDA C (Januszewski), sendo esta a

linguagem de programação utilizada pela NVIDIA em suas GPUs (Randima, 2004).

Como exemplo, pode-se comparar o tempo de simulação em microprocessadores

comuns (CPUs – Central Processing Units), da ordem de horas, com o tempo de

simulação deste trabalho, praticamente em tempo real (Zhao, 2008). O trabalho

envolvendo simulações no software Sailfish foi publicado no 14th Brazilian Congress

of Thermal Sciences and Engineering, anexado a este trabalho (Saraiva Ferreira &

Martins Campos de Oliveira, 2012).

Após verificar que o Sailfish não atenderia a todos os requisitos de simulação,

considerou-se como segunda parte do trabalho a construção de um simulador de

fluidos em linguagem C, baseado em outro muito simples que implementa apenas

um fluido, porém com funcionalidades escassas. Ainda, a implementação em

linguagem C visa a ser apenas uma etapa do processo para construção de um

simulador em linguagem CUDA C, cuja execução terá um desempenho muito maior.

Page 16: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

3

2 Revisão Bibliográfica

Para o desenvolvimento deste trabalho, foi realizado um estudo sobre o

método Lattice Boltzmann e as técnicas que deram origem a ele. Inicialmente, é

apresentada a equação de Navier-Stokes, em seguida é discutida a teoria de

autômatos celulares e LGCAs e, finalmente, é apresentado o método Lattice

Boltzmann e suas peculiaridades.

2.1 A Equação de Navier-Stokes

A equação de Navier-Stokes descreve o escoamento de fluidos

incompressíveis e pode ser escrita como:

( )

Equação 2.1

junto com a equação de continuidade:

Equação 2.2

em que é o operador gradiente, u é a velocidade do escoamento, P = p/ρ0 é a

pressão cinemática, p é a pressão, ρ0, a densidade de massa constante e é a

viscosidade de cisalhamento cinemática, ou viscosidade cinemática (Wolf-Gladrow,

2000). A Equação 2.1 é não linear em u, o que requer métodos numéricos para

simular escoamentos de fluidos. Deve-se ressaltar que os métodos citados aqui têm

uma abordagem de baixo para cima, ou seja, através de interações microscópicas

chega-se ao mesmo resultado das equações de Navier-Stokes, em contraposição a

uma abordagem de cima para baixo, em que as equações de Navier-Stokes são

resolvidas analiticamente no método. Essa característica simplifica

consideravelmente o problema, já que a solução de equações não lineares aumenta

muito o custo computacional.

Page 17: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

4

Para que seja possível simular corretamente escoamentos incompressíveis

com os métodos mencionados anteriormente, deve haver similaridade dinâmica das

simulações com os escoamentos reais. O número de Reynolds, descrito por:

Equação 2.3

é útil na explicação da similaridade dinâmica, que significa que escoamentos com

mesmo número de Reynolds, mas com diferentes velocidades de escoamento u,

diâmetros do obstáculo D e viscosidades cinemáticas , possuem a mesma solução

e, assim, um mesmo escoamento pode ser estudado em escala diferente, como

acontece quando se realiza uma simulação ou se constrói um modelo.

2.2 Autômatos Celulares

Autômatos Celulares são arranjos regulares de células individuais do mesmo

tipo. Cada célula possui um número finito de estados discretos, e esses estados são

atualizados simultaneamente a cada passo de tempo. As regras para essa

atualização dependem somente dos estados da célula e da vizinhança local de

células ao redor dela (Wolf-Gladrow, 2000).

O autômato celular de uma dimensão consiste em células que podem estar

ocupadas ou vazias ao longo de uma linha. É circular, ou seja, após a última célula

da linha segue-se a primeira célula dessa mesma linha. O estado atual de uma

célula pode ser determinado através da equação:

( )

( )

( )

( )

( )

Equação 2.4

com sendo o estado da célula no tempo , e como função dos estados anteriores

( ) das células num raio de a , de forma alternativa:

( )

[∑ ( )

]

Equação 2.5

Page 18: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

5

tendo como argumento um único inteiro, e j sendo constantes inteiras. Um

autômato desse tipo pode ter até ( ) combinações diferentes de regras de

atualização – com k sendo o número de estados possíveis e r o raio de alcance dos

vizinhos. Esse autômato é denominado autômato celular elementar. As regras de

atualização para um autômato podem ser divididas em regras aditivas, totalísticas,

simétricas, com memória e legais.

Autômatos celulares de duas dimensões possuem mais liberdade para arranjar

as células, definir seus vizinhos e regras de atualização. Como exemplos de

vizinhos, tem-se a vizinhança von Neumann e a vizinhança de Moore, que serão

mostradas mais adiante. Dois jogos importantes também são autômatos de duas

dimensões: o jogo de Fredkin, que leva à autorreplicação da imagem inicial, e o jogo

Life, que simula a evolução de uma sociedade de organismos vivos (mais detalhes

em (Wolf-Gladrow, 2000)).

Em suma, autômatos celulares podem simular comportamentos complexos,

como escoamento de fluidos, com regras de atualização simples, as quais são fáceis

de implementar e se adaptam bem à computação paralela massiva. Porém, há

certas características que devem ser obedecidas antes de simular satisfatoriamente

um fenômeno físico, como exemplos: a ocorrência da conservação de certas

quantidades que não são físicas, a maioria das regras não permitir a propagação de

informações no autômato e a microdinâmica do sistema dever ser reversível. Há

considerável dificuldade em se reproduzir as leis dos fluidos com os autômatos

celulares.

2.3 Lattice-Gas Cellular Automata (LGCA)

O LGCA simplifica o problema da construção de autômatos celulares para a

simulação de fenômenos físicos, dividindo a regra de atualização em duas partes:

colisão e propagação.

Começando pelo mais simples, o HPP é um LGCA de duas dimensões numa

rede (lattice) quadrada. Sua importância é histórica, dado que esse autômato não

obedece à equação de Navier-Stokes no limite macroscópico. Possui quatro vetores

de rede, que apontam para cada nó adjacente, conforme vetores a, b, c e d na

Figura 2.1. Em cada nó há quatro células, cada uma associada ao seu respectivo

Page 19: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

6

vetor de rede. Essas células podem estar vazias ou ocupadas por no máximo uma

partícula, cuja massa é igual para todas as partículas.

Figura 2.1. Rede quadrada do modelo HPP. Fonte: (Wolf-Gladrow, 2000).

A evolução no tempo é determinística e alterna colisões – entre partículas de

um mesmo nó – com propagações. A colisão conserva massa e quantidade de

movimento enquanto muda a ocupação das células. Quando duas partículas entram

em um nó por direções opostas e as outras células desse nó estão vazias, uma

colisão frontal acontece e rotaciona ambas as partículas em 90º no mesmo sentido

(Figura 2.2). Qualquer outra configuração não sofre mutação. A aplicação dupla do

operador de colisão retorna à configuração inicial, como mostra Figura 2.2.

Figura 2.2. Única configuração que gera colisão e seu resultado final. Pode ser

representado por células (a) ou por vetores (b). Fonte: (Wolf-Gladrow, 2000).

Page 20: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

7

Pode-se ver, na Figura 2.1, que há duas populações de partículas

desacopladas na rede, formando duas sub-redes (branca e preta), características da

rede quadrada. O HPP não obedece à equação de Navier-Stokes porque o grau de

simetria rotacional na rede é insuficiente. Assim, certos tensores compostos de

produtos das velocidades da rede – os tensores da rede – não são isotrópicos na

rede quadrada. Essa anisotropia se manifesta, por exemplo, no escoamento

passando por um obstáculo simétrico não rotacional, no qual o arrasto depende da

orientação relativa do obstáculo com respeito à rede. Nesse autômato, também há

conservações adicionais indesejáveis que não ocorrem no mundo físico. Como

consequência, elas restringem a dinâmica do modelo.

No LGCA HPP, o estado das células é descrito por campos booleanos

( ), em que indica o número de ocupação – 0 ou 1 –, é a direção do vetor

da rede, , o tempo discreto e s, as coordenadas de cada nó. O número de ocupação

média, que pode variar de zero a um, é descrito por:

( ) ( )

Equação 2.6

Assim, a massa é dada por:

( ) ( ) Equação 2.7

e a quantidade de movimento:

( ) ( ) Equação 2.8

em que u é a velocidade do escoamento e ck são as velocidades da rede, dadas por:

√ ( ) Equação 2.9

√ ( )

Equação 2.10

Page 21: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

8

√ ( ) Equação 2.11

√ ( )

Equação 2.12

que obedecem a condição de simetria da rede, ou seja, a somatória dessas

velocidades é igual a zero.

Outro LGCA de destaque é o FHP, que trouxe a terceira condição essencial

além de a conservação da massa e da quantidade de movimento: a condição de

simetria suficiente que garante isotropia de um certo tensor de posto quatro formado

pelas velocidades da rede, cuja simetria é hexagonal.

2.4 O Método Lattice Boltzmann (LB)

Como mencionado anteriormente, a grande diferença entre o LGCA e o Lattice

Boltzmann é que este lida com funções de distribuição de probabilidade contínuas

ao invés de partículas. A mecânica é simples e pode ser descrita como propagações

no espaço e interações de colisão, assim como no LGCA. Os modelos de Rede de

Boltzmann simplificam a modelagem e representam bem o comportamento de

fluidos (Chirila, 2010).

As interações podem ser consideradas colisões elásticas, conservando massa

e quantidade de movimento. Ao invés de se ter informações sobre cada partícula em

cada instante de tempo – o que tornaria possível prever todos os estados futuros,

mas aumentaria extraordinariamente os cálculos –, utilizam-se funções de

distribuição de probabilidades.

Essa função de distribuição indica a probabilidade de se encontrar uma

partícula numa dada posição com uma certa quantidade de movimento: essa é a

função de distribuição de partícula única, ( ). Ela é adequada para descrever todas

as propriedades de um gás que não dependem das posições relativas entre

moléculas.

O processo de propagação das partículas consiste em calcular as novas

funções de distribuição para o próximo passo de tempo, e o processo de colisão

rearranja as partículas que sofrem colisão (He, 1997).

Page 22: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

9

Os modelos de Rede de Boltzmann reduzem o número de posições espaciais

das partículas, a quantidade de movimento microscópica e o tempo a alguns valores

discretos. O modelo mais comum, o D2Q9, possui oito direções mais o estado de

repouso, três magnitudes para a velocidade, apenas um valor de massa e duas

dimensões (Nourgaliev, 2003). A medida de comprimento fundamental é a unidade

de rede ( ) e a medida de tempo fundamental é o passo de tempo ( ). A equação

para um passo de tempo fica:

( ) ( ) ( )

( )

Equação 2.13

com sendo a função de distribuição de probabilidade na direção , x sendo o vetor

posição, a velocidade na direção , Δ uma quantidade de passos de tempo, t o

tempo, τ o tempo de relaxamento, ou seja, o tempo para o sistema atingir o

equilíbrio, e a função de distribuição de equilíbrio é definida como:

( ) ( ) [

( )

] Equação 2.14

com sendo os pesos, que valem para partículas em descanso ( ),

para e para , ρ é a densidade do fluido e é a

velocidade básica na rede – o valor mais simples é 1 (Sukop, 2007). A viscosidade

cinemática do fluido é dada por:

) Equação 2.15

em que τ não deve se aproximar muito de ½ (Sukop, 2007).

Outro tema importante nos modelos de Rede de Boltzamnn são as condições

de contorno. Elas podem ser periódicas, quando o fim de uma dimensão da rede se

liga ao início dela, formando um cilindro, ou um toroide no caso de todas as

dimensões serem periódicas. Podem também ser condições de rebatimento, útil

quando se quer representar obstáculos ou paredes, porque as partículas voltarão ao

nó que estavam antes de colidirem com o obstáculo.

As condições de contorno von Neumann ou condições de fluxo mantêm o valor

da velocidade enquanto as condições de Dirichlet ou de pressão mantêm o valor da

Page 23: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

10

pressão ou densidade. Há ainda a possibilidade de se incluir a gravidade, somando-

se uma variação de velocidade causada pela ação de uma força.

2.4.1 O Método Lattice Boltzmann em escoamentos multicomponentes

multifásicos

O escoamento multicomponente multifásico é de grande interesse econômico

porque o petróleo geralmente é encontrado com água, e de grande preocupação

ambiental porque líquidos de fase não aquosa sob a superfície frequentemente

agem como fontes de contaminação das águas subterrâneas (Sukop, 2007).

O escoamento bifásico se mostra simples de ser implementado através da

adição de mais um fluido à simulação, junto com suas propriedades e um parâmetro

de interação entre os fluidos. Diferente do escoamento multifásico de um único

componente, no qual as forças de interação são atrativas, o escoamento multifásico

multicomponente possui forças de repulsão. No escoamento multifásico de um

componente, tem-se como exemplo a separação de fase, que acontece após

determinado tempo para esse tipo de escoamento. Já no escoamento

multicomponente, podem-se citar fluidos imiscíveis, como óleo e água.

A função de distribuição de equilíbrio é calculada através de uma velocidade

macroscópica composta:

Equação 2.16

em que σ é o fluido 1, 2,...,n e é a densidade do fluido 1,2,...,n. A densidade é

calculada como:

Equação 2.17

A velocidade macroscópica composta é a velocidade mais significativa para

análise (Sukop, 2007). Em relação à densidade, não é permitido que ambos os

fluidos tenham densidade zero no mesmo nó. A força no fluido σ é determinada por:

Page 24: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

11

( ) ( ) ∑ ( ) Equação 2.18

em que é a força de interação entre os fluidos, indica o outro fluido – em um

escoamento com dois fluidos – e comumente são as densidades ( ). A

magnitude de G e as densidades dos fluidos determinam a força .

Para distinguir um fluido do outro no domínio, deve-se definir qual a densidade

de corte para a fronteira do fluido. Há algumas opções, dentre elas quando houver

50% de cada fluido no nó, ou quando a densidade de um fluido for maior que a

densidade do outro fluido, ou ainda quando a densidade de um fluido for maior que a

densidade da vizinhança.

Há ainda a interação dos fluidos com a superfície sólida, na qual cada fluido

interage separadamente com o sólido. Para se determinar o ângulo de contato entre

um fluido e uma superfície, deve-se usar a equação de Young:

Equação 2.19

em que é a tensão interfacial entre os dois fluidos e σ σ são as tensões

interfaciais entre a superfície e cada fluido. As forças de superfícies são

incorporadas ao modelo da mesma forma que no modelo de um único componente:

apenas somando a força à respectiva força resultante de cada fluido, com a força de

interação sendo :

Equação 2.20

Equação 2.21

Por exemplo, quando as densidades de cada fluido são iguais,

, σ σ e o ângulo de contato entre o fluido e a superfície

sólida é 90º, como mostra a Figura 2.3.

Figura 2.3. Ângulo de contato de 90º entre fluido e superfície sólida. Fonte:

(Sukop, 2007).

Page 25: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

12

Assim, a equação de Young se torna:

, Equação 2.22

ou seja, é a diferença na força de adesão que determina o molhamento relativo, isto

é, o ângulo de contato.

2.4.2 Parâmetros da simulação

Para executar as simulações e interpretar corretamente seus resultados, é

necessário antes escolher apropriadamente os parâmetros de rede de Boltzmann,

tais como o tamanho da rede, a viscosidade numérica e a velocidade máxima

(Januszewski). Dado um escoamento físico com largura e altura do canal por onde o

fluido passa, sua velocidade e número de Reynolds, é possível calcular os

parâmetros da simulação.

Em unidades de rede, um passo de tempo da simulação é por definição 1 lt

(lattice time), e o espaço entre dois nós da rede é 1 lu (lattice unit). As Equações

2.23 a 2.25 são bastante úteis:

[

] Equação 2.23

em que é o espaçamento da rede, L é a altura do canal e R é o número de nós da

rede. O espaçamento da rede tem unidade em metros por unidade de rede. A

Equação 2.24 calcula a velocidade do escoamento da rede:

Equação 2.24

em que é o tamanho do passo de tempo da rede e é a velocidade do

escoamento real. A viscosidade da rede pode ser calculada com a Equação 2.25:

( )

Equação 2.25

Page 26: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

13

em que Re denota o número de Reynolds do escoamento real, que será igual ao

número de Reynolds da simulação.

Arbitrando-se um número de nós da rede, pode-se calcular o espaçamento da

rede com a Equação 2.23 e, escolhendo-se a velocidade máxima de escoamento da

rede , pode-se calcular o tamanho do passo de tempo da rede utilizando:

. Equação 2.26

A partir desse resultado, é possível calcular a viscosidade da rede. A dificuldade

nesse método está em se escolher corretamente a velocidade máxima de

escoamento da rede, porque, apesar de o valor ser relativamente seguro,

alguns escoamentos podem se tornar instáveis com esse parâmetro.

Outra forma de se realizar estes cálculos é começando com um valor de

viscosidade numérica. Essa abordagem se mostra bastante lógica, visto que há uma

pequena faixa de valores com os quais a simulação não se torna instável (

). Basta adotar um valor nessa faixa, uma velocidade máxima de escoamento da

rede compatível e usar as equações acima para calcular os outros parâmetros.

Page 27: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

14

3 Procedimento Experimental

A parte prática do presente trabalho foi dividida em algumas etapas, as quais

seguem: estudo de autômatos celulares em linguagem CUDA C, estudo e validação

do simulador Sailfish através de escoamentos monofásicos pelo método Lattice

Boltzmann, estudo de escoamentos bifásicos através do caso da interação entre

álcool e óleo de mamona em micromisturadores Ômega e Tesla e, finalmente,

implementação de simulador de fluidodinâmica em linguagem C, utilizando o método

Lattice Boltzmann.

3.1 Autômatos celulares em linguagem CUDA C

Cincos autômatos celulares foram implementados: três autômatos em uma

dimensão com três regras distintas e dois autômatos bastante conhecidos em duas

dimensões chamados jogo de Fredkin e jogo Life. Após completar o estudo sobre

autômatos celulares, o Sailfish passou a ser utilizado para a realização de

simulações no método Lattice Boltzmann, com a execução em placa de vídeo

(recursos da linguagem CUDA C).

3.2 Escoamentos no programa Sailfish

Os escoamentos monofásicos configurados em linguagem python no simulador

Sailfish também foram cinco: escoamento de Poiseuille, efeito do comprimento de

entrada, escoamentos laminar e turbulento passando por cilindro, escoamento

instável em altos números de Reynolds para visualização de vórtices e separação da

camada limite. Dessa forma, o simulador foi validado, com grande concordância em

relação a resultados da literatura (Sukop, 2007).

O estudo do escoamento bifásico consistiu no escoamento de dois fluidos entre

duas placas paralelas passando por obstáculo e no escoamento de álcool e óleo de

mamona passando por dois micromisturadores, o Ômega e o Tesla.

Nesta etapa do trabalho, houve a percepção de que o programa Sailfish não

atenderia a todos os casos de escoamentos, já que ele se encontra em um projeto

não concluído, no qual funções ainda serão acrescentadas. No mais, o programa e o

manual não deixam explícitos quais tipos de rede (lattice) e outros parâmetros

Page 28: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

15

bastante relevantes estão realmente sendo adotados em todos os tipos de

escoamentos, o que dificulta a simulação de novos escoamentos, o estudo e o

correto entendimento do algoritmo utilizado no programa. O fato de o programa não

ter sido escrito em apenas uma linguagem, sendo na verdade a adoção de três

linguagens que se mesclam, apresenta outra desvantagem. Devido a esses

contratempos, decidiu-se criar um simulador próprio, a princípio em linguagem C, de

modo que houvesse ciência de todos os parâmetros e teoria aplicados ao algoritmo.

3.3 Implementação de simulador em linguagem C

Após verificar a inviabilidade da continuação no programa Sailfish, devido ao

fato de ele não ser explícito o suficiente em relação à teoria adotada em cada

escoamento, a última etapa deste trabalho se deu com a implementação de um

simulador de fluidodinâmica em linguagem C usando o método Lattice Boltzmann,

em que um simulador bem simples para escoamentos monofásicos com poucas

condições de contorno foi tomado como base para a construção de um simulador

para escoamentos bifásicos.

O primeiro passo foi melhorar a implementação base, tornando o programa

mais robusto, através da verificação da execução de alguns passos do programa,

que não eram verificados originalmente e poderiam gerar erros. Após essa fase,

houve a inclusão de um segundo fluido à simulação, configurando-se as condições

iniciais, atualizando-se a etapa de propagação e reprogramando-se a etapa de

colisão, que muda drasticamente em simulações multicomponentes. Por fim,

ajustaram-se as condições de contorno, considerando a presença de dois fluidos.

Terminada a base da implementação para dois fluidos, buscaram-se possíveis

erros no código, o que comprometeria a simulação, além de condições específicas

inerentes ao método Lattice Boltzmann, para alguns parâmetros, que, se não

respeitadas, levam a instabilidades na simulação. A seguir, são detalhados os

resultados obtidos da sistematização descrita no presente capítulo.

Page 29: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

16

4 Resultados e Discussões

Na primeira parte do trabalho, foram implementados alguns autômatos

celulares de uma e de duas dimensões na linguagem CUDA C. Já no método Lattice

Boltzmann, o simulador Sailfish foi configurado a partir de scripts em linguagem

Python e foi utilizado em escoamentos monofásicos, o que possibilitou a validação

do simulador, e em escoamentos bifásicos, acrescentando posteriormente os

microrreatores necessários à simulação da mistura álcool-óleo. Por fim, iniciou-se o

desenvolvimento de um simulador de fluidodinâmica em linguagem C baseado no

método Lattice Boltzmann. Todas as simulações foram executadas em computador

com sistema operacional Ubuntu baseado em Linux com processador Intel Core i7

CPU 950 3,08 GHz, memória RAM de 6GB e placa de vídeo NVidia GeForce GTX

560 Ti com 386 núcleos CUDA e 1GB de memória.

4.1 Autômatos Celulares em linguagem CUDA C

4.1.1 Autômato Celular 1D, regra 2 e raio 2

Como explicado no capítulo 2, o autômato celular de uma dimensão consiste

em células que podem estar ocupadas ou vazias ao longo de uma linha e é circular,

ou seja, após a última célula da linha segue-se a primeira célula dessa mesma linha.

A linha seguinte representa o próximo estado da linha atual; ocorre uma atualização

da linha atual que depende do estado de cada célula e suas vizinhas num raio

determinado. Assim, cada célula é atualizada simultaneamente.

O raio igual a dois significa que os dois vizinhos à direita e os dois vizinhos à

esquerda de uma célula serão considerados na regra de atualização. Regra igual a

dois significa que somente a configuração correspondente à representação binária

desse número – 10 – mudará o estado da célula para ocupada, conforme Tabela

4.1.

Page 30: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

17

Tabela 4.1. Tabela verdade para autômato celular 1D, regra 2 e raio 2.

( )

( )

( )

( )

( )

( )

0 0 0 0 0 0

0 0 0 0 1 1

0 0 0 1 0 0

1 1 1 1 1 0

Na Tabela 4.1, pode-se ver que a única configuração em que a célula ficará no

estado ocupada é aquela em que somente a célula dois passos à direita está

ocupada, enquanto todas as outras – incluindo a célula em questão, estão vazias. O

número binário 10 – regra 2 – pode ser visto na última coluna, com o bit menos

significativo na primeira linha.

No código em CUDA C, que foi baseado no exemplo shared_bitmap.cu do

capítulo cinco do livro CUDA by Example (Sanders, 2010), foi gerada uma linha

aleatória – primeira linha do bitmap de 1024 x 1024 pixels – com o auxílio da função

rand(), incluindo-se a biblioteca stdlib.h. Essa linha tem probabilidade de 50% para

ter pixels pretos (representando células ocupadas) e 50% para ter pixels brancos

(células vazias). Foi alocado espaço para um bitmap de 1024 x 1024 pixels na CPU

dentro da função main(), dentro da qual a primeira linha foi preenchida da forma

mencionada acima, ainda que a indexação de um bitmap seja com o índice zero no

canto inferior esquerdo e o último índice referente ao último pixel no canto superior

direito do bitmap. Para contornar este fato, o loop for que preenche a primeira linha

inicia na célula com o índice ( ) até ( ) – DIM é igual a

1024 neste caso.

Depois disso, esse bitmap foi copiado para a GPU através do comando

“cudaMemcpy” e o ponteiro para esse bitmap na CPU foi desalocado. A seguir, outro

loop for, que vai de ( ) até , decrementando o contador de um a cada

iteração para contornar os índices do bitmap, invoca o kernel, função que é

processada na GPU, linha a linha do bitmap, realizando a atualização segundo a

regra mencionada acima.

Esse kernel constrói um bloco com DIM threads – tarefas executadas

paralelamente –, para não haver o problema de acesso aos vizinhos, já que threads

só podem acessar dados de outras threads do mesmo bloco. Esse kernel também

Page 31: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

18

recebe como parâmetro, além de um ponteiro para o bitmap na GPU, um índice que

indica qual linha do bitmap está se atualizando.

Para escrever na linha seguinte a que se está no bitmap – a atualização –,

deve-se calcular o índice que representa determinada célula na linha seguinte. Para

isso, utiliza-se a seguinte indexação:

int x = threadIdx.x;

int offset = x + i*blockDim.x;

int pto_prox_linha = offset - blockDim.x;

x indexa as threads no eixo x, offset indica a linha atual (i = linha atual) e

pto_prox_linha realiza o cálculo final, que é a linha atual subtraída da dimensão do

bloco no eixo x, que é igual à largura do bitmap. A subtração se dá por conta da

indexação do bitmap.

Também nesse kernel é realizada uma verificação que visa identificar quando o

vizinho está antes do início da linha ou após o fim da linha. Caso esteja uma posição

antes do início da linha, esse vizinho passa a ser a última célula da linha, se estiver

duas posições antes do início, o vizinho passará a ser a penúltima célula; caso

esteja uma posição após o fim da linha, o vizinho será a primeira célula da linha ou

se estiver duas posições após o fim, ele será a segunda célula – para satisfazer a

característica circular do autômato.

Comparações dentro de um if, para saber o estado de cada vizinho

considerado na regra e da célula cujo estado será definido, determina se a célula

será escrita com a cor preta, caso seja a segunda configuração da Tabela 4.1, ou

branca, para todos os outros casos.

A última linha deste kernel chama a função __syncthreads(), que garante que

todas as threads chegarão ao fim de sua execução antes que as linhas seguintes

sejam executadas, neste caso, o fim do kernel. A utilidade dessa função nesse

programa é justamente esperar que toda a próxima linha termine de se atualizar

antes que a linha seguinte a esta seja chamada para atualização. Se essa função

não fosse utilizada, poderia haver erros com threads verificando células com valores

errados. Um resultado desse programa pode ser visto na Figura 4.1.

Page 32: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

19

Figura 4.1. Autômato Celular 1D, regra 2 e raio 2.

4.1.2 Autômato Celular 1D, regra 20 e raio 1

A definição deste autômato é a mesma daquela da subseção anterior, porém,

com raio um, apenas são verificados os vizinhos uma posição à direita e uma

posição à esquerda de cada célula.

Regra 20, em representação binária igual a 10100, significa que agora há duas

configurações em que a célula atual pode mudar seu estado para 1 (ocupada), como

pode ser confirmado na Tabela 4.2.

Page 33: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

20

Tabela 4.2. Tabela verdade para autômato celular 1D, regra 20 e raio 1.

( )

( )

( )

( )

0 0 0 0

0 0 1 0

0 1 0 1

0 1 1 0

1 0 0 1

1 0 1 0

1 1 0 0

1 1 1 0

O programa em CUDA C segue o mesmo padrão daquele da seção anterior

(4.1.1), mudando apenas o raio verificado – um vizinho à direita e um à esquerda –,

e as comparações dentro do if com as configurações que mudarão o estado da

célula – nesta subseção, a terceira e quinta configurações da Tabela 4.2. Uma

imagem obtida pode ser vista na Figura 4.2.

Page 34: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

21

Figura 4.2. Autômato Celular 1D, regra 20 e raio 1.

4.1.3 Autômato Celular 1D, regra 52 e raio 1

Novamente, o mesmo autômato foi utilizado para satisfazer a regra 52, que é

110100 em binário, agora com três configurações em que o estado da célula torna-

se ocupado. Em relação à regra 20, a regra 52 apenas acrescenta uma configuração

que vai para o estado 1. A Tabela 4.3 mostra todas as configurações possíveis

desse autômato.

Page 35: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

22

Tabela 4.3. Tabela verdade para autômato celular 1D, regra 52 e raio 1.

( )

( )

( )

( )

0 0 0 0

0 0 1 0

0 1 0 1

0 1 1 0

1 0 0 1

1 0 1 1

1 1 0 0

1 1 1 0

Uma comparação também é acrescentada no código dentro do if que muda o

estado das células do autômato do programa da seção 4.2. Obteve-se a imagem da

Figura 4.3.

Figura 4.3. Autômato Celular 1D, regra 52 e raio 1.

Page 36: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

23

4.1.4 Jogo de Fredkin

O jogo de Fredkin é um tipo de autômato cujas células também possuem

apenas dois estados, viva (ocupada) ou morta (vazia). Porém, é um autômato de

duas dimensões e as células são atualizadas simultaneamente, utilizando uma

vizinhança do tipo von Neumann de raio 1 (Figura 4.4).

Figura 4.4. Vizinhança von Neumann raio 1. Fonte: (Wolf-Gladrow, 2000).

A atualização consiste na seguinte regra: caso o número de vizinhos seja par

(0, 2 ou 4), a célula estará morta na próxima atualização. Caso contrário, a célula

estará viva. O estado da célula central não é relevante.

O programa foi baseado no exemplo heat_2d.cu do capítulo sete do livro CUDA

by Example (Sanders, 2010), que anima um bitmap, assim, pode-se ver o

desenvolvimento do autômato no tempo. O kernel imagem_inicial escreve a letra F

no centro do bitmap. A partir disso, o kernel blend_kernel utiliza a memória de

texturas para acessar os vizinhos e contar o número de vizinhos vivos. A memória

de texturas é uma memória somente leitura da GPU que, em certos casos, pode

acelerar substancialmente o desempenho e reduzir o tráfego de memória (Sanders,

2010). Ela é útil para acessar diretamente células como as da Figura 4.4, que, de

outra forma, seria necessário percorrer toda a linha para acessar as células vizinhas

desejadas.

Todos os ponteiros para os bitmaps foram alterados para o tipo unsigned char

e, para diminuir a velocidade de atualização do bitmap, o for dentro da função

anim_gpu vai apenas de zero a um.

O jogo foi realizado com a letra F e uma iteração pode ser vista na Figura 4.5.

Page 37: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

24

Figura 4.5. Jogo de Fredkin com a letra F como padrão a ser replicado.

4.1.5 Jogo Life

O Jogo Life possui as mesmas características do jogo de Fredkin, mas utiliza

uma vizinhança do tipo Moore de raio um (Figura 4.6). A regra de atualização do

jogo Life também é de acordo com o número de vizinhos vivos: se uma célula tiver

três vizinhos vivos, estará viva no próximo passo de tempo e, se tiver menos que

dois vizinhos vivos ou mais do que três, estará morta.

Page 38: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

25

Figura 4.6. Vizinhança de Moore de raio um. Fonte: (Wolf-Gladrow, 2000).

Foi gerado um bitmap aleatório na CPU assim como nos autômatos de uma

dimensão, mas ocupando todo o bitmap (2D), através da função rand(). As mesmas

alterações do Jogo de Fredkin, como mudar o tipo dos ponteiros e diminuir a

duração do for, foram feitas aqui. Um instante de tempo obtido está mostrado na

Figura 4.7.

Page 39: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

26

Figura 4.7. Jogo Life.

4.2 Aplicação do método Lattice Boltzmann em escoamentos

monofásicos no Sailfish

Para validação do simulador Sailfish, alguns escoamentos clássicos foram

realizados, tais como: escoamento de Poiseuille, efeito do comprimento de entrada,

escoamento passando por um cilindro, escoamento instável em altos números de

Reynolds e separação da camada limite.

O Sailfish gera arquivos de dados com os resultados da simulação que

podem ser processados por outros programas (Januszewski). Os gráficos a seguir

foram plotados com o software MATLAB.

Page 40: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

27

4.2.1 Escoamento de Poiseuille

O escoamento de Poiseuille pode ser o tipo de escoamento mais simples de se

simular usando o método Lattice Boltzmann (LB) (Sukop, 2007). Ele consiste em um

fluido escoando dentro de um tubo circular, que no caso de duas dimensões pode

ser aproximado por uma fenda. Usando-se o método LB, é necessário colocar

condições de contorno de rebatimento (bounce-back) nas paredes da fenda – o que

é feito no simulador considerando a fenda como nós de parede –, e condições de

contorno periódicas ao longo do escoamento – que é o padrão do Sailfish. Assim, o

escoamento que sai pelo fim da fenda entra pelo início dela, tornando o sistema

infinito nessa direção (Sukop, 2007).

Para adquirir os dados de velocidade em cada ponto da rede, basta passar

para a rotina que simula o escoamento de Poiseuille os parâmetros do tamanho da

rede nos eixos x e y, indicar se o escoamento é incompressível, se o perfil de

velocidade já é desenvolvido e a viscosidade da rede. A Figura 4.8 mostra o perfil de

velocidade da literatura (Sukop, 2007) e a Figura 4.9 mostra o perfil da simulação. O

número de Reynolds utilizado foi 4,4.

Figura 4.8. Escoamento de

Poiseuille; x é o tamanho da rede no

eixo x. Fonte: (Sukop, 2007).

Figura 4.9. Escoamento de Poiseuille:

resultado da simulação no Sailfish.

Outra forma de se obter o mesmo gráfico é programando uma simulação cuja

geometria consiste em nós de parede nas fendas como citado antes e com

condições de contorno de velocidade nas extremidades esquerda e direita.

Page 41: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

28

4.2.2 Efeito do Comprimento de Entrada

Para números de Reynolds maiores que 30, aproximadamente, a teoria do

escoamento de Poiseuille só se aplica após uma certa distância do duto (Tritton,

1988). De acordo com as propriedades e velocidade do fluido e a geometria do duto,

o perfil de velocidade completamente desenvolvido demora a ser atingido, podendo

alcançar uma distância considerável desde a entrada. Dessa forma, o escoamento

de Poiseuille pode não ser o mais adequado para se tratar um escoamento, havendo

a necessidade de se estudar o efeito do comprimento de entrada.

No método LB, é possível verificar o comprimento de entrada através do uso de

condições de contorno de velocidade nas extremidades do escoamento. Então, a

rotina alternativa utilizada para se analisar o escoamento de Poiseuille também

serve para estudar o efeito do comprimento entrada. Para melhor visualização desse

efeito, pede-se um número de Reynolds mais alto, de outra forma o efeito é muito

pequeno e torna-se desprezível. As Figuras 4.10 e 4.11 ilustram esse efeito.

Figura 4.10. Visão simplificada do

efeito do comprimento de entrada; u é

a velocidade, uavg é a velocidade

média, r é a distância medida a partir

do centro do tubo e a é o raio do tubo.

Fonte: (Sukop, 2007).

Figura 4.11. Efeito do comprimento de

entrada simulado no Sailfish.

Page 42: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

29

4.2.3 Escoamento Passando por Cilindro

O escoamento passando por um cilindro há muito tempo interessa à dinâmica

dos fluidos (Sukop, 2007). Com ele, é possível visualizar as linhas de fluxo no

escoamento e analisar como o fluido se comporta com obstáculos. Pode-se também

comparar os efeitos para escoamento laminar e turbulento.

A rotina que simula o escoamento passando por um cilindro indica a posição do

cilindro, o tamanho da rede e o valor da viscosidade, para assim controlar o número

de Reynolds e o regime do escoamento – laminar ou turbulento. As Figuras 4.12 a

4.15 demonstram esse exemplo.

Figura 4.12. Escoamento

laminar passando por cilindro.

Fonte: (Sukop, 2007).

Figura 4.13. Escoamento laminar passando por

cilindro – simulação em Sailfish.

Page 43: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

30

Figura 4.14. Escoamento

turbulento simulado (acima) e

fotografado (abaixo). Fonte:

(Sukop, 2007).

Figura 4.15. Escoamento turbulento simulado

no Sailfish.

4.2.4 Escoamento Instável em Altos Números de Reynolds

No escoamento passando por um cilindro, conforme se aumenta o número de

Reynolds, vórtices passam a se desprender do cilindro para lados opostos

alternadamente (Sukop, 2007). Esse tipo de escoamento também é de grande

interesse para a comunidade científica. As Figuras 4.16 e 4.17 mostram imagens da

simulação propriamente dita, em que é possível ver os vórtices ao longo do

escoamento. As Figuras 4.18 e 4.19 mostram os vetores de velocidade e as linhas

de fluxo, respectivamente.

Page 44: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

31

Figura 4.16. Foto da formação de

vórtices (acima) e simulação

(abaixo). Fonte: (Sukop, 2007).

Figura 4.17. Simulação do Sailfish; a

primeira imagem mostra a magnitude da

velocidade e as quatro imagens abaixo

representam diferentes visualizações para

a vorticidade.

Figura 4.18. Vetores de velocidade

no escoamento.

Figura 4.19. Linhas de fluxo.

Page 45: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

32

4.2.5 Separação da Camada Limite

Outro fenômeno interessante é a indução da separação da camada limite. Ele

pode ser observado na subseção 4.2.3 no escoamento turbulento, mas aqui o

mesmo exemplo foi alterado para conter como obstáculo um quadrado, como

mostram as Figuras 4.20 e 4.21.

Figura 4.20. Separação da

camada limite. Fonte: (Sukop,

2007).

Figura 4.21. Separação da camada limite no

simulador.

4.3 Aplicação do método Lattice Boltzmann em escoamentos

bifásicos no Sailfish

Após a verificação da coerência entre os resultados gerados pelo Sailfish com

a literatura (Sukop, 2007), passou-se para a realização de simulações em

escoamentos bifásicos. Foram simulados dois fluidos imiscíveis escoando

paralelamente entre placas paralelas livremente, depois com a adição de um

obstáculo e por fim álcool e óleo de mamona foram simulados escoando pelos

micromisturadores Ômega e Tesla.

Para adicionar um novo fluido à simulação, basta definir a densidade de cada

fluido separadamente, através dos índices rho e phi, e os tempos de relaxação,

Page 46: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

33

através dos parâmetros visc e tau_phi. Outro parâmetro a ser definido é a força de

interação G. Por último, deve-se adicionar uma condição para o fluido, como uma

força ao longo de todo domínio.

4.3.1 Escoamento bifásico entre placas paralelas

A Figura 4.22 apresenta o escoamento entre duas placas paralelas de dois

fluidos imiscíveis, com phi = 1 e rho = 0.4. Apesar de a imiscibilidade dos fluidos,

devido às suas velocidades, ao passarem por um obstáculo, ocorre um pequeno

grau de mistura entre eles.

Figura 4.22. Escoamento bifásico entre placas paralelas no Sailfish (a flecha aponta

o obstáculo).

Outro problema de interesse científico e econômico é simular a interação entre o

álcool e o óleo de mamona. A Figura 4.23 mostra o perfil de velocidade para os dois

fluidos escoando entre placas paralelas livremente. Essa simulação também

concorda com a teoria (Sukop, 2007), o que reforça a validação do simulador para

simulações multicomponentes.

Page 47: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

34

Figura 4.23. À esquerda, perfil de velocidade de dois fluidos imiscíveis escoando

entre placas paralelas. Fonte: (Sukop, 2007). À direita, mesmo perfil de velocidade

para álcool e óleo de mamona.

4.3.2 Escoamento de álcool e óleo em microrreator Ômega

O microrreator Ômega foi desenhado em programa CAD com as dimensões da

Figura 4.24, e a imagem bitmap extraída do desenho CAD em duas dimensões foi

aplicada à simulação.

Figura 4.24. Dimensões do microrreator Ômega. Fonte: (Arias, 2010)

A Tabela 4.4 mostra os parâmetros reais de cada fluido.

Page 48: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

35

Tabela 4.4. Parâmetros dos fluidos.

Óleo de Mamona Etanol

Densidade real [kg/m³] 957,3 789

Viscosidade dinâmica [Pa.s] 0,689 0,0012

Taxa Volumétrica [mL/h] 1 0,5

Velocidade real [m/s] 0,00111 0,000556

Número de Reynolds 0,0914

Altura do canal [m]

A partir desses parâmetros, devem-se calcular os parâmetros adimensionais

necessários à simulação – densidade, viscosidade, velocidade adimensionais. Com

as densidades da Tabela 4.4, pode-se calcular a densidade de simulação de cada

fluido: escolhendo a densidade do óleo como 1, a densidade relativa de simulação

do etanol é 0,824. Arbitrando-se o valor de viscosidade da rede como 0,16 – o valor

mais estável possível, de acordo com a seção 2.4.2 –, calculou-se a velocidade

máxima de escoamento da rede, igual a . A força de interação é obtida

experimentalmente através de testes até que os fluidos tenham comportamento igual

ao real (Sukop, 2007). A Tabela 4.5 mostra os parâmetros da simulação e as

Figuras 4.25 e 4.26 mostram a simulação com o microrreator Ômega e com três

microrreatores Ômega em cascata, respectivamente. Além disso, elas mostram seis

instantes de tempo distintos e não adjacentes.

Tabela 4.5. Parâmetros da simulação.

Óleo de Mamona Etanol

Densidade 1 0,824

Viscosidade cinemática 0,16 0,0402

Tempo de relaxação 0,98 0,62

Velocidade máxima

Força de interação -1,2

Espaçamento da rede

Tamanho do passo de tempo

Page 49: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

36

Figura 4.25. Escoamento de etanol e óleo de mamona em microrreator Ômega; seis

instantes de tempo distintos e não adjacentes.

Figura 4.26. Escoamento de etanol e óleo de mamona passando por três

microrreatores Ômega em cascata; seis instantes de tempo distintos e não

adjacentes.

Pode-se observar que o micromisturador Ômega não é eficiente para misturar

álcool e óleo de mamona, já que tanto um único misturador ou misturadores em

cascata possuem o mesmo resultado: em cada estágio (misturador), apenas uma

gota de óleo se desprende para escoar no álcool, porém, ao fim do estágio, essa

gota volta para a parte com óleo. A seguir é realizada a mesma análise para o

misturador Tesla.

Page 50: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

37

4.3.3 Escoamento de álcool e óleo em microrreator Tesla

O microrreator Tesla também foi desenhado em programa CAD com as

dimensões da Figura 4.27, e a imagem bitmap extraída do desenho CAD em duas

dimensões foi aplicada à simulação.

Figura 4.27. Dimensões do microrreator Tesla. Fonte: (Arias, 2010)

Os mesmos parâmetros reais dos fluidos da Tabela 4.4 foram utilizados para os

cálculos dos parâmetros da simulação da Tabela 4.5. As Figuras 4.28 e 4.29

mostram a simulação com o microrreator Tesla e com três microrreatores Tesla em

cascata, respectivamente. Além disso, A Figura 4.28 mostra oito instantes de tempo

distintos e não adjacentes, enquanto a Figura 4.29 mostra quatro instantes de tempo

distintos e não adjacentes.

Figura 4.28. Escoamento de etanol e óleo de mamona em microrreator Tesla; oito

instantes de tempo distintos e não adjacentes.

Page 51: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

38

Figura 4.29. Escoamento de etanol e óleo de mamona passando por três

microrreatores Tesla em cascata; quatro instantes de tempo distintos e não

adjacentes.

Já no micromisturador Tesla, observa-se formação de bolhas após um curto

período de tempo (instante número 4 da Figura 4.28 para um único misturador e

instante número 3 da Figura 4.29 para os misturadores em cascata). Esse resultado

indica que o microrreator Tesla é mais eficiente que o Ômega para misturar os dois

fluidos em questão, havendo ainda a necessidade de se acrescentar um reagente

catalisador para haver mistura completa (Saraiva Ferreira & Martins Campos de

Oliveira, 2012).

A seção seguinte explica a implementação de um simulador em linguagem C,

visto que, apesar de os bons resultados até a presente seção, muitos aspectos do

método e dos modelos Lattice Boltzmann ficaram obscuros e uma abordagem mais

profunda é requerida para se obter simulações robustas e fortemente fiéis à

realidade.

4.4 Implementação de Simulador em Linguagem C

A fim de satisfazer os requisitos não presentes no Sailfish, como a explicitação

do modelo, iniciou-se a implementação de um simulador de fluidodinâmica em

Page 52: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

39

linguagem C usando o método Lattice Boltzmann. Como base, tomou-se um

simulador bem simples para escoamentos monofásicos com poucas condições de

contorno e modificações foram realizadas de forma a se acrescentar um fluido à

simulação.

Como citado na seção de procedimentos experimentais, o primeiro passo foi

melhorar a implementação base, tornando o programa mais robusto, através da

verificação da execução de alguns passos do programa, que não eram verificados

originalmente e poderiam gerar erros. Como exemplo, a verificação da alocação

dinâmica de memória, checando se o ponteiro não apontou para vazio (NULL); a

escrita em arquivo de algumas variáveis críticas do programa; a verificação da

correta execução das funções em OpenGL originalmente implementas; teste de

mesa em todas as funções relativas ao método e verificação de divisões por zero e

prevenção dessas.

A segunda fase foi incluir o segundo fluido ao simulador, dobrando-se o

número de ponteiros existentes originalmente, acrescentando-se parâmetros do

segundo fluido, tais como: densidade, tempo de relaxação e velocidade de entrada

do fluido. O dobro de espaço também foi alocado e a velocidade composta inicial foi

calculada e aplicada a ambos os fluidos:

(

) ( )

(

)

Equação 4.1

A função de propagação foi atualizada para haver propagação também no

segundo fluido e, na função de colisão, cálculos de atualização de densidade e

velocidade foram realizados também para o outro fluido; a velocidade composta foi

calculada, como na configuração inicial (Equação 4.1), porém considerando

velocidades nos eixos x e y; a função de distribuição de probabilidade de equilíbrio

foi recalculada para ambos os fluidos considerando-se a velocidade composta;

segue o cálculo dessa função para as nove direções possíveis apenas para um

fluido:

f0eq = ro * faceq1 * (1.f - 1.5f*ulinha_2);

f1eq = ro * faceq2 * (1.f + 3.f*ulinha_x + 4.5f*ulinha_x*ulinha_x - 1.5f*ulinha_2);

Page 53: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

40

f2eq = ro * faceq2 * (1.f + 3.f*ulinha_y + 4.5f*ulinha_y*ulinha_y - 1.5f*ulinha_2);

f3eq = ro * faceq2 * (1.f - 3.f*ulinha_x + 4.5f*ulinha_x*ulinha_x - 1.5f*ulinha_2);

f4eq = ro * faceq2 * (1.f - 3.f*ulinha_y + 4.5f*ulinha_y*ulinha_y - 1.5f*ulinha_2);

f5eq = ro * faceq3 * (1.f + 3.f*(ulinha_x + ulinha_y) + 4.5f*(ulinha_x +

ulinha_y)*(ulinha_x + ulinha_y) - 1.5f*ulinha_2);

f6eq = ro * faceq3 * (1.f + 3.f*(-ulinha_x + ulinha_y) + 4.5f*(-ulinha_x +

ulinha_y)*(-ulinha_x + ulinha_y) - 1.5f*ulinha_2);

f7eq = ro * faceq3 * (1.f + 3.f*(-ulinha_x - ulinha_y) + 4.5f*(-ulinha_x -

ulinha_y)*(-ulinha_x - ulinha_y) - 1.5f*ulinha_2);

f8eq = ro * faceq3 * (1.f + 3.f*(ulinha_x - ulinha_y) + 4.5f*(ulinha_x -

ulinha_y)*(ulinha_x - ulinha_y) - 1.5f*ulinha_2);

Finalmente, a colisão é efetuada para ambos os fluidos:

f0[i0] = rtau1 * f0[i0] + rtau * f0eq;

f1[i0] = rtau1 * f1[i0] + rtau * f1eq;

f2[i0] = rtau1 * f2[i0] + rtau * f2eq;

f3[i0] = rtau1 * f3[i0] + rtau * f3eq;

f4[i0] = rtau1 * f4[i0] + rtau * f4eq;

f5[i0] = rtau1 * f5[i0] + rtau * f5eq;

f6[i0] = rtau1 * f6[i0] + rtau * f6eq;

f7[i0] = rtau1 * f7[i0] + rtau * f7eq;

f8[i0] = rtau1 * f8[i0] + rtau * f8eq;

g0[i0] = rtau3 * g0[i0] + rtau2 * g0eq;

g1[i0] = rtau3 * g1[i0] + rtau2 * g1eq;

g2[i0] = rtau3 * g2[i0] + rtau2 * g2eq;

g3[i0] = rtau3 * g3[i0] + rtau2 * g3eq;

g4[i0] = rtau3 * g4[i0] + rtau2 * g4eq;

g5[i0] = rtau3 * g5[i0] + rtau2 * g5eq;

g6[i0] = rtau3 * g6[i0] + rtau2 * g6eq;

g7[i0] = rtau3 * g7[i0] + rtau2 * g7eq;

g8[i0] = rtau3 * g8[i0] + rtau2 * g8eq;

Page 54: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

41

Por fim, as quatro funções de aplicação das condições de contorno foram ajustadas.

A função de condição periódica incluiu mais um fluido, a função de condição para

paredes bounce-back também incluiu o efeito da adição de outro fluido, a função

para condição de entrada de velocidade calculou parâmetros para o segundo fluido

e também aplicou esses parâmetros a ele. Por último, a condição de saída foi

atualizada para o segundo fluido. A condição periódica é implementada da seguinte

forma:

void per_BC(void){

int i0,i1,i;

for (i=0; i<ni; i++){

i0 = I2D(ni,i,0);

i1 = I2D(ni,i,nj-1);

f2[i0] = f2[i1];

f5[i0] = f5[i1];

f6[i0] = f6[i1];

f4[i1] = f4[i0];

f7[i1] = f7[i0];

f8[i1] = f8[i0];

g2[i0] = g2[i1];

g5[i0] = g5[i1];

g6[i0] = g6[i1];

g4[i1] = g4[i0];

g7[i1] = g7[i0];

g8[i1] = g8[i0];

}

}

A última etapa desse processo, para busca de erros, consistiu na verificação

dos valores dos parâmetros, e na inserção de uma condição de velocidade, a qual

deve ser no máximo igual a 0,1 lu/lt, para não haver instabilidades no sistema que

Page 55: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

42

inviabilizem a simulação. Também se evitaram nesta etapa divisões por zero,

limitando-se as velocidades individuais para cada fluido.

Duas imagens para a versão do simulador com um fluido podem ser vistas nas

Figuras 4.30 e 4.31. Nelas o fluido entra pelo lado esquerdo com velocidade

constante, sai pelo lado direito e é periódico nas bordas de cima e de baixo.

Obstáculos foram colocados para a geração de vórtices e mudança de velocidade.

Figura 4.30. Geração de vórtices em simulação monocomponente.

Figura 4.31. Velocidades diferentes em simulação monocomponente.

Na simulação multicomponente, é possível visualizar a entrada de fluidos pelo

lado esquerdo conforma mostram as Figuras 4.32 e 4.33. Apesar de parte da

visualização já poder ser vista, como é o caso da condição de entrada na primeira

figura e alguns pontos na segunda figura, o simulador está em fase de

desenvolvimento, pois a implementação da força de interação entre os fluidos ainda

precisa ser efetuada.

Page 56: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

43

Figura 4.32. Entrada de fluidos pelo lado esquerdo; simulação bifásica.

Figura 4.33. Alguns pontos mudam a velocidade na presença de obstáculos (pontos

pretos).

Page 57: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

44

5 Conclusões e Perspectivas

A teoria de autômatos celulares e o método Lattice Boltzmann foram estudados

e alguns escoamentos clássicos monofásicos foram simulados tanto para validação

quanto para aprendizado do simulador Sailfish. Também foram desenhados os

microrreatores e investigaram-se os parâmetros dos fluidos para simulação da

interação entre álcool e óleo de mamona em escoamentos bifásicos. Por fim, iniciou-

se a implementação de um simulador de fluidodinâmica utilizando o método Lattice

Boltzmann em linguagem C, visando o estudo de escoamentos multifásicos

multicomponentes.

Para a simulação de escoamentos bifásicos, a maior fonte de erro está no

ajuste da força de interação, que é empírica; apesar disso, as simulações no Sailfish

condizem com o esperado: o microrreator Ômega não é muito eficiente para misturar

os fluidos, enquanto o microrreator Tesla realiza melhor a tarefa. Contudo, para uma

mistura completa, é necessário utilizar um reagente químico que facilita o processo.

As simulações no Sailfish resultaram na publicação de um artigo em congresso

internacional, sendo um trabalho bastante satisfatório ao aluno e ao orientador

(Saraiva Ferreira & Martins Campos de Oliveira, 2012).

Além disso, a implementação do simulador em linguagem C para substituir o

Sailfish, que possui algumas deficiências já descritas ao longo do texto já está

adiantada e os próximos passos serão adicionar a força de interação entre os fluidos

para a simulação completa. O desenvolvimento do simulador trouxe maior

aprofundamento no método Lattice Boltzmann, que será bastante útil em trabalhos

futuros.

5.1 Perspectivas

Como trabalhos futuros, pretende-se terminar o desenvolvimento do

simulador em linguagem C e traduzi-lo para linguagem CUDA C no mestrado.

Terminando o desenvolvimento do simulador em C, espera-se deixar o programa

mais robusto, aceitando um número maior de fluidos e otimizando-o para maior

velocidade de execução.

Page 58: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

45

O objetivo final do simulador é executar em um cluster de GPUs no

Laboratório de Simulações Multifísicas do Departamento de Mecânica

Computacional (DMC) da Faculdade de Engenharia Mecânica (FEM). Através desse

alto ganho de desempenho, abordar-se-ão outros problemas de escoamento de

fluidos multicomponentes de grande interesse econômico, como os problemas

relacionados ao petróleo, no qual o método Lattice Boltzmann possui maior ganho

em relação a algortimos CFDs tradicionais. O cluster também possibilitará a

simulação de problemas em três dimensões.

Page 59: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

46

Referências Bibliográficas

Arias, E. L. (2010). Desenvolvimento e Avaliação de Microreatores: Aplicação para Produção

de Biodiesel.

Chen, S. e. (1998). Lattice Boltzmann Method for Fluid Flows. Annual Review of Fluid

Mechanics.

Chirila, D. B. (2010). Introduction to Lattice Boltzmann Methods.

Fox, R. W. (2006). Introdução à Mecânica dos Fluidos (6ª ed.). LTC.

He, X. e.-S. (1997). Theory of the lattice Boltzmann method: From the Boltzmann equation to

the lattice Boltzmann equation. Physical Review, 56.

Januszewski, M. (s.d.). Sailfish Manual Reference. Acesso em 18 de Janeiro de 2012,

disponível em http://sailfish.us.edu.pl/

Nourgaliev, R. D. (2003). The Lattice Boltzmann Equation Method: Theoretical

Interpretation, Numerics and Implications. International Journal of Multiphase Flow.

Randima, F. (2004). GPU Gems - Programming Techniques, Tips, and Tricks for Real-Time

Graphics.

Sanders, J. e. (2010). CUDA by Example - An Introduction General-Purpose GPU

Programming. Addison-Wesley.

Saraiva Ferreira, L. O., & Martins Campos de Oliveira, F. (2012). Simulation of the Alcohol-

Oil Mixture in a Micromixer Using the lattice Boltzmann Method on a GPU Device.

14th Brazilian Congress of Thermal Sciences and Engineering.

Sukop, M. e. (2007). Lattice Boltzmann Modeling – An Introduction for Geoscientists and

Engineers. Springer.

Tritton, D. (1988). Physical Fluid Dynamics. Oxford Science Publications.

Wolf-Gladrow, D. A. (2000). Lattice-Gas Cellular Automata and Lattice Boltzmann Models –

An Introduction. Springer.

Zhao, Y. (2008). Lattice Boltzmann based PDE solver on the GPU. The Visual Computer:

International Journal of Computer Graphics.

Page 60: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

47

Anexos

1) Artigo publicado no 14th Brazilian Congress of Thermal Sciences and

Engineering

Page 61: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

48

Page 62: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

49

Page 63: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

50

Page 64: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

51

Page 65: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

52

Page 66: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

53

Page 67: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

54

2) Código em linguagem C de simulador multicomponente

////////////////////////////////////////////////////////////////////////////////

// Crude 2D Lattice Boltzmann Demo program

// C version

// Graham Pullan - Oct 2008

// com alterações (Fabíola Martins) - Nov 2012

//

// f6 f2 f5

// \ | /

// \ | /

// \|/

// f3---|--- f1

// /|\

// / | \ and f0 for the rest (zero) velocity

// / | \

// f7 f4 f8

//

///////////////////////////////////////////////////////////////////////////////

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

#include <GL/glew.h>

#include <GL/glut.h>

#define I2D(ni,i,j) (((ni)*(j)) + i)

////////////////////////////////////////////////////////////////////////////////

// OpenGL pixel buffer object and texture //

GLuint gl_PBO, gl_Tex;

// arrays //

float *f0,*f1,*f2,*f3,*f4,*f5,*f6,*f7,*f8;

float *g0,*g1,*g2,*g3,*g4,*g5,*g6,*g7,*g8; // função f para o para segundo fluido

float *tmpf0,*tmpf1,*tmpf2,*tmpf3,*tmpf4,*tmpf5,*tmpf6,*tmpf7,*tmpf8;

float *tmpg0,*tmpg1,*tmpg2,*tmpg3,*tmpg4,*tmpg5,*tmpg6,*tmpg7,*tmpg8; // variaveis

temporarias p 2º fluido

float *cmap,*plotvar;

int *solid;

unsigned int *cmap_rgba, *plot_rgba; //rgba arrays for plotting

// scalars //

float tau,faceq1,faceq2,faceq3, tau1; // tau1 (tau fluido 2)

float vxin, roout, vxin1, roout1; // vxin1 e roout1 (fluido 2)

float width, height;

int ni,nj;

int ncol;

int ipos_old,jpos_old, draw_solid_flag;

Page 68: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

55

////////////////////////////////////////////////////////////////////////////////

//

// OpenGL function prototypes

//

void display(void);

void resize(int w, int h);

void mouse(int button, int state, int x, int y);

void mouse_motion(int x, int y);

void shutdown(void);

//

// Lattice Boltzmann function prototypes

//

//void display(void);

void stream(void);

void collide(void);

void solid_BC(void);

void per_BC(void);

void in_BC(void);

void ex_BC_crude(void);

void apply_BCs(void);

unsigned int get_col(float min, float max, float val);

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////

int main(int argc, char **argv)

{

int array_size_2d,totpoints,i, a;

float rcol,gcol,bcol, u_linha;

FILE *fp_col;

// The following parameters are usually read from a file, but

// hard code them for the demo:

ni=20;

nj=20;

vxin=0.04;

roout=1.0;

tau=0.62;

tau1=0.98; // parametros fluido 2

vxin1=0.08;

roout1=0.824;

// End of parameter list

// Write parameters to screen

Page 69: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

56

printf ("ni = %d\n", ni);

printf ("nj = %d\n", nj);

printf ("vxin = %f\n", vxin);

printf ("roout = %f\n", roout);

printf ("tau = %f\n", tau);

printf ("vxin1 = %f\n", vxin1); // print parametros fluido 2

printf ("roout1 = %f\n", roout1);

printf ("tau1 = %f\n", tau1);

totpoints=ni*nj;

array_size_2d=ni*nj*sizeof(float);

// Allocate memory for arrays

f0 = malloc(array_size_2d);

f1 = malloc(array_size_2d);

f2 = malloc(array_size_2d);

f3 = malloc(array_size_2d);

f4 = malloc(array_size_2d);

f5 = malloc(array_size_2d);

f6 = malloc(array_size_2d);

f7 = malloc(array_size_2d);

f8 = malloc(array_size_2d);

if(f0==NULL || f1==NULL || f2==NULL || f3==NULL || f4==NULL || f5==NULL ||

f6==NULL || f7==NULL || f8==NULL){

printf("Nao alocou!");

return 1;

}

tmpf0 = malloc(array_size_2d);

tmpf1 = malloc(array_size_2d);

tmpf2 = malloc(array_size_2d);

tmpf3 = malloc(array_size_2d);

tmpf4 = malloc(array_size_2d);

tmpf5 = malloc(array_size_2d);

tmpf6 = malloc(array_size_2d);

tmpf7 = malloc(array_size_2d);

tmpf8 = malloc(array_size_2d);

if(tmpf0==NULL || tmpf1==NULL || tmpf2==NULL || tmpf3==NULL || tmpf4==NULL ||

tmpf5==NULL || tmpf6==NULL || tmpf7==NULL || tmpf8==NULL){

printf("Nao alocou!");

return 1;

}

g0 = malloc(array_size_2d); //aloca memoria p fluido 2 (var temp abaixo)

g1 = malloc(array_size_2d);

g2 = malloc(array_size_2d);

Page 70: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

57

g3 = malloc(array_size_2d);

g4 = malloc(array_size_2d);

g5 = malloc(array_size_2d);

g6 = malloc(array_size_2d);

g7 = malloc(array_size_2d);

g8 = malloc(array_size_2d);

if(g0==NULL || g1==NULL || g2==NULL || g3==NULL || g4==NULL || g5==NULL ||

g6==NULL || g7==NULL || g8==NULL){

printf("Nao alocou!");

return 1;

}

tmpg0 = malloc(array_size_2d);

tmpg1 = malloc(array_size_2d);

tmpg2 = malloc(array_size_2d);

tmpg3 = malloc(array_size_2d);

tmpg4 = malloc(array_size_2d);

tmpg5 = malloc(array_size_2d);

tmpg6 = malloc(array_size_2d);

tmpg7 = malloc(array_size_2d);

tmpg8 = malloc(array_size_2d);

if(tmpg0==NULL || tmpg1==NULL || tmpg2==NULL || tmpg3==NULL || tmpg4==NULL

|| tmpg5==NULL || tmpg6==NULL || tmpg7==NULL || tmpg8==NULL){

printf("Nao alocou!");

return 1;

}

plotvar = malloc(array_size_2d);

plot_rgba = malloc(ni*nj*sizeof(unsigned int));

solid = malloc(ni*nj*sizeof(int));

if(plotvar==NULL || plot_rgba==NULL || solid==NULL) {

printf("Nao alocou!");

return 1;

}

//

// Some factors used to calculate the f_equilibrium values

//

faceq1 = 4.f/9.f;

faceq2 = 1.f/9.f;

faceq3 = 1.f/36.f;

// Cálculo da velocidade composta

u_linha=(1/tau+1/tau1)*(roout*vxin+roout1*vxin1)/(roout/tau+roout1/tau1);

Page 71: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

58

//

// Initialise f's by setting them to the f_equilibirum values assuming

// that the whole domain is at velocity vx=vxin vy=0 and density ro=roout

//

for (i=0; i<totpoints; i++) {

f0[i] = faceq1 * roout * (1.f - 1.5f*u_linha*u_linha);

f1[i] = faceq2 * roout * (1.f + 3.f*u_linha + 4.5f*u_linha*u_linha -

1.5f*u_linha*u_linha);

f2[i] = faceq2 * roout * (1.f - 1.5f*u_linha*u_linha);

f3[i] = faceq2 * roout * (1.f - 3.f*u_linha + 4.5f*u_linha*u_linha -

1.5f*u_linha*u_linha);

f4[i] = faceq2 * roout * (1.f - 1.5f*u_linha*u_linha);

f5[i] = faceq3 * roout * (1.f + 3.f*u_linha + 4.5f*u_linha*u_linha -

1.5f*u_linha*u_linha);

f6[i] = faceq3 * roout * (1.f - 3.f*u_linha + 4.5f*u_linha*u_linha -

1.5f*u_linha*u_linha);

f7[i] = faceq3 * roout * (1.f - 3.f*u_linha + 4.5f*u_linha*u_linha -

1.5f*u_linha*u_linha);

f8[i] = faceq3 * roout * (1.f + 3.f*u_linha + 4.5f*u_linha*u_linha -

1.5f*u_linha*u_linha);

plotvar[i] = u_linha;

solid[i] = 1;

g0[i] = faceq1 * roout1 * (1.f - 1.5f*u_linha*u_linha);

g1[i] = faceq2 * roout1 * (1.f + 3.f*u_linha + 4.5f*u_linha*u_linha -

1.5f*u_linha*u_linha);

g2[i] = faceq2 * roout1 * (1.f - 1.5f*u_linha*u_linha);

g3[i] = faceq2 * roout1 * (1.f - 3.f*u_linha + 4.5f*u_linha*u_linha -

1.5f*u_linha*u_linha);

g4[i] = faceq2 * roout1 * (1.f - 1.5f*u_linha*u_linha);

g5[i] = faceq3 * roout1 * (1.f + 3.f*u_linha + 4.5f*u_linha*u_linha -

1.5f*u_linha*u_linha);

g6[i] = faceq3 * roout1 * (1.f - 3.f*u_linha + 4.5f*u_linha*u_linha -

1.5f*u_linha*u_linha);

g7[i] = faceq3 * roout1 * (1.f - 3.f*u_linha + 4.5f*u_linha*u_linha -

1.5f*u_linha*u_linha);

g8[i] = faceq3 * roout1 * (1.f + 3.f*u_linha + 4.5f*u_linha*u_linha -

1.5f*u_linha*u_linha);

/*printf("f0=%f\tf1=%f\tf2=%f\tf3=%f\tf4=%f\tf5=%f\tf6=%f\tf7=%f\tf8=%f\ng0=%f

\tg1=%f\tg2=%f\tg3=%f\tg4=%f\tg5=%f\tg6=%f\tg7=%f\tg8=%f\nFIM DA MAIN", f0[i],

f1[i], f2[i], f3[i], f4[i], f5[i], f6[i], f7[i], f8[i], g0[i], g1[i], g2[i], g3[i], g4[i], g5[i], g6[i], g7[i],

g8[i]);*/

}

//

// Read in colourmap data for OpenGL display

//

fp_col = fopen("cmap.dat","r");

if (fp_col==NULL) {

Page 72: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

59

printf("Error: can't open cmap.dat \n");

return 1;

}

// allocate memory for colourmap (stored as a linear array of int's)

fscanf (fp_col, "%d", &ncol);

cmap_rgba = (unsigned int *)malloc(ncol*sizeof(unsigned int));

// read colourmap and store as int's

for (i=0;i<ncol;i++){

fscanf(fp_col, "%f%f%f", &rcol, &gcol, &bcol);

cmap_rgba[i]=((int)(255.0f) << 24) | // convert colourmap to int

((int)(bcol * 255.0f) << 16) |

((int)(gcol * 255.0f) << 8) |

((int)(rcol * 255.0f) << 0);

}

fclose(fp_col);

//

// Iinitialise OpenGL display - use glut

//

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

glutInitWindowSize(ni, nj); // Window of ni x nj pixels

glutInitWindowPosition(50, 50); // position

glutCreateWindow("2D LB"); // title

// Check for OpenGL extension support

printf("Loading extensions: %s\n", glewGetErrorString(glewInit()));

if(!glewIsSupported(

"GL_VERSION_2_0 "

"GL_ARB_pixel_buffer_object "

"GL_EXT_framebuffer_object "

)){

fprintf(stderr, "ERROR: Support for necessary OpenGL extensions missing.");

fflush(stderr);

return;

}

// Set up view

glClearColor(0.0, 0.0, 0.0, 0.0);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(0,ni,0.,nj, -200.0, 200.0);

// Create texture which we use to display the result and bind to gl_Tex

glEnable(GL_TEXTURE_2D);

glGenTextures(1, &gl_Tex); // Generate 2D texture

glBindTexture(GL_TEXTURE_2D, gl_Tex); // bind to gl_Tex

// texture properties:

Page 73: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

60

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ni, nj, 0,

GL_RGBA, GL_UNSIGNED_BYTE, NULL);

// Create pixel buffer object and bind to gl_PBO. We store the data we want to

// plot in memory on the graphics card - in a "pixel buffer". We can then

// copy this to the texture defined above and send it to the screen

glGenBuffers(1, &gl_PBO);

glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, gl_PBO);

printf("Buffer created.\n");

// Set the call-back functions and start the glut loop

printf("Starting GLUT main loop...\n");

glutDisplayFunc(display);

glutReshapeFunc(resize);

glutIdleFunc(display);

glutMouseFunc(mouse);

glutMotionFunc(mouse_motion);

glutMainLoop();

/* while(1){

display();

printf("OI");

}*/

free(f0);

free(f1);

free(f2);

free(f3);

free(f4);

free(f5);

free(f6);

free(f7);

free(f8);

free(tmpf0);

free(tmpf1);

free(tmpf2);

free(tmpf3);

free(tmpf4);

free(tmpf5);

free(tmpf6);

free(tmpf7);

free(tmpf8);

Page 74: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

61

free(g0);

free(g1);

free(g2);

free(g3);

free(g4);

free(g5);

free(g6);

free(g7);

free(g8);

free(tmpg0);

free(tmpg1);

free(tmpg2);

free(tmpg3);

free(tmpg4);

free(tmpg5);

free(tmpg6);

free(tmpg7);

free(tmpg8);

free(plotvar);

free(plot_rgba);

free(solid);

free(cmap_rgba);

return 0;

}

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////

void stream(void)

// Move the f values one grid spacing in the directions that they are pointing

// i.e. f1 is copied one location to the right, etc.

{

int i,j,im1,ip1,jm1,jp1,i0;

// Initially the f's are moved to temporary arrays

for (j=0; j<nj; j++) {

jm1=j-1;

jp1=j+1;

if (j==0) jm1=0;

if (j==(nj-1)) jp1=nj-1;

for (i=0; i<ni; i++) {

i0 = I2D(ni,i,j);

im1 = i-1;

ip1 = i+1;

if (i==0) im1=0;

Page 75: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

62

if (i==(ni-1)) ip1=ni-1;

tmpf1[i0] = f1[I2D(ni,im1,j)];

tmpf2[i0] = f2[I2D(ni,i,jm1)];

tmpf3[i0] = f3[I2D(ni,ip1,j)];

tmpf4[i0] = f4[I2D(ni,i,jp1)];

tmpf5[i0] = f5[I2D(ni,im1,jm1)];

tmpf6[i0] = f6[I2D(ni,ip1,jm1)];

tmpf7[i0] = f7[I2D(ni,ip1,jp1)];

tmpf8[i0] = f8[I2D(ni,im1,jp1)];

tmpg1[i0] = g1[I2D(ni,im1,j)];

tmpg2[i0] = g2[I2D(ni,i,jm1)];

tmpg3[i0] = g3[I2D(ni,ip1,j)];

tmpg4[i0] = g4[I2D(ni,i,jp1)];

tmpg5[i0] = g5[I2D(ni,im1,jm1)];

tmpg6[i0] = g6[I2D(ni,ip1,jm1)];

tmpg7[i0] = g7[I2D(ni,ip1,jp1)];

tmpg8[i0] = g8[I2D(ni,im1,jp1)];

}

}

// Now the temporary arrays are copied to the main f arrays

for (j=0; j<nj; j++) {

for (i=1; i<ni; i++) {

i0 = I2D(ni,i,j);

f1[i0] = tmpf1[i0];

f2[i0] = tmpf2[i0];

f3[i0] = tmpf3[i0];

f4[i0] = tmpf4[i0];

f5[i0] = tmpf5[i0];

f6[i0] = tmpf6[i0];

f7[i0] = tmpf7[i0];

f8[i0] = tmpf8[i0];

g1[i0] = tmpg1[i0];

g2[i0] = tmpg2[i0];

g3[i0] = tmpg3[i0];

g4[i0] = tmpg4[i0];

g5[i0] = tmpg5[i0];

g6[i0] = tmpg6[i0];

g7[i0] = tmpg7[i0];

g8[i0] = tmpg8[i0];

}

}

}

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////

Page 76: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

63

void collide(void)

// Collisions between the particles are modeled here. We use the very simplest

// model which assumes the f's change toward the local equlibrium value (based

// on density and velocity at that point) over a fixed timescale, tau

{

int i,j,i0;

float ro, rovx, rovy, vx, vy, v_sq_term;

float ro1, rovx1, rovy1, vx1, vy1, v_sq_term1, den_x, den_y;

float f0eq, f1eq, f2eq, f3eq, f4eq, f5eq, f6eq, f7eq, f8eq;

float g0eq, g1eq, g2eq, g3eq, g4eq, g5eq, g6eq, g7eq, g8eq;

float rtau, rtau1;

float rtau2, rtau3, ulinha_x, ulinha_y, ulinha_2;

// Some useful constants

rtau = 1.f/tau;

rtau1 = 1.f - rtau;

rtau2 = 1.f/tau1;

rtau3 = 1.f - rtau2;

for (j=0; j<nj; j++) {

for (i=0; i<ni; i++) {

i0 = I2D(ni,i,j);

// Do the summations needed to evaluate the density and components of velocity

ro = f0[i0] + f1[i0] + f2[i0] + f3[i0] + f4[i0] + f5[i0] + f6[i0] + f7[i0] + f8[i0];

rovx = f1[i0] - f3[i0] + f5[i0] - f6[i0] - f7[i0] + f8[i0];

rovy = f2[i0] - f4[i0] + f5[i0] + f6[i0] - f7[i0] - f8[i0];

if(ro==0){

vx = 0;

vy = 0;

}else{

vx = rovx/ro;

vy = rovy/ro;

}

ro1 = g0[i0] + g1[i0] + g2[i0] + g3[i0] + g4[i0] + g5[i0] + g6[i0] + g7[i0] + g8[i0];

rovx1 = g1[i0] - g3[i0] + g5[i0] - g6[i0] - g7[i0] + g8[i0];

rovy1 = g2[i0] - g4[i0] + g5[i0] + g6[i0] - g7[i0] - g8[i0];

if(ro1==0){

vx1 = 0;

vy1 = 0;

}else{

vx1 = rovx1/ro1;

vy1 = rovy1/ro1;

}

Page 77: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

64

den_x=(ro/tau + ro1/tau1) * (vx*ro + vx1*ro1);

if(den_x==0){

ulinha_x=0;

}else{

ulinha_x = (1/tau + 1/tau1) / den_x;

}

den_y=(ro/tau + ro1/tau1) * (vy*ro + vy1*ro1);

if(den_y==0){

ulinha_y=0;

}else{

ulinha_y = (1/tau + 1/tau1) / den_y;

}

ulinha_2 = ulinha_x * ulinha_x + ulinha_y * ulinha_y;

if(ulinha_2>0.1){

ulinha_2=0.1;

}

//v_sq_term = 1.5f*(vx*vx + vy*vy);

// Also load the velocity magnitude into plotvar - this is what we will

// display using OpenGL later

plotvar[i0] = sqrt(ulinha_2);

printf("ro=%f\n", ro);

/*printf("f0=%f\tf1=%f\tf2=%f\tf3=%f\tf4=%f\tf5=%f\tf6=%f\tf7=%f\tf8=%f\ng0=%f\tg1=%

f\tg2=%f\tg3=%f\tg4=%f\tg5=%f\tg6=%f\tg7=%f\tg8=%f\n", f0[i0], f1[i0], f2[i0], f3[i0],

f4[i0], f5[i0], f6[i0], f7[i0], f8[i0], g0[i0], g1[i0], g2[i0], g3[i0], g4[i0], g5[i0], g6[i0], g7[i0],

g8[i0]);*/

// Evaluate the local equilibrium f values in all directions

f0eq = ro * faceq1 * (1.f

- 1.5f*ulinha_2);

f1eq = ro * faceq2 * (1.f + 3.f*ulinha_x + 4.5f*ulinha_x*ulinha_x

- 1.5f*ulinha_2);

f2eq = ro * faceq2 * (1.f + 3.f*ulinha_y + 4.5f*ulinha_y*ulinha_y

- 1.5f*ulinha_2);

f3eq = ro * faceq2 * (1.f - 3.f*ulinha_x + 4.5f*ulinha_x*ulinha_x

- 1.5f*ulinha_2);

f4eq = ro * faceq2 * (1.f - 3.f*ulinha_y + 4.5f*ulinha_y*ulinha_y

- 1.5f*ulinha_2);

f5eq = ro * faceq3 * (1.f + 3.f*(ulinha_x + ulinha_y) + 4.5f*(ulinha_x +

ulinha_y)*(ulinha_x + ulinha_y) - 1.5f*ulinha_2);

f6eq = ro * faceq3 * (1.f + 3.f*(-ulinha_x + ulinha_y) + 4.5f*(-ulinha_x +

ulinha_y)*(-ulinha_x + ulinha_y) - 1.5f*ulinha_2);

f7eq = ro * faceq3 * (1.f + 3.f*(-ulinha_x - ulinha_y) + 4.5f*(-ulinha_x -

ulinha_y)*(-ulinha_x - ulinha_y) - 1.5f*ulinha_2);

Page 78: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

65

f8eq = ro * faceq3 * (1.f + 3.f*(ulinha_x - ulinha_y) + 4.5f*(ulinha_x -

ulinha_y)*(ulinha_x - ulinha_y) - 1.5f*ulinha_2);

g0eq = ro1 * faceq1 * (1.f

- 1.5f*ulinha_2);

g1eq = ro1 * faceq2 * (1.f + 3.f*ulinha_x +

4.5f*ulinha_x*ulinha_x - 1.5f*ulinha_2);

g2eq = ro1 * faceq2 * (1.f + 3.f*ulinha_y +

4.5f*ulinha_y*ulinha_y - 1.5f*ulinha_2);

g3eq = ro1 * faceq2 * (1.f - 3.f*ulinha_x + 4.5f*ulinha_x*ulinha_x

- 1.5f*ulinha_2);

g4eq = ro1 * faceq2 * (1.f - 3.f*ulinha_y + 4.5f*ulinha_y*ulinha_y

- 1.5f*ulinha_2);

g5eq = ro1 * faceq3 * (1.f + 3.f*(ulinha_x + ulinha_y) + 4.5f*(ulinha_x +

ulinha_y)*(ulinha_x + ulinha_y) - 1.5f*ulinha_2);

g6eq = ro1 * faceq3 * (1.f + 3.f*(-ulinha_x + ulinha_y) + 4.5f*(-ulinha_x +

ulinha_y)*(-ulinha_x + ulinha_y) - 1.5f*ulinha_2);

g7eq = ro1 * faceq3 * (1.f + 3.f*(-ulinha_x - ulinha_y) + 4.5f*(-ulinha_x -

ulinha_y)*(-ulinha_x - ulinha_y) - 1.5f*ulinha_2);

g8eq = ro1 * faceq3 * (1.f + 3.f*(ulinha_x - ulinha_y) + 4.5f*(ulinha_x -

ulinha_y)*(ulinha_x - ulinha_y) - 1.5f*ulinha_2);

// Simulate collisions by "relaxing" toward the local equilibrium

f0[i0] = rtau1 * f0[i0] + rtau * f0eq;

f1[i0] = rtau1 * f1[i0] + rtau * f1eq;

f2[i0] = rtau1 * f2[i0] + rtau * f2eq;

f3[i0] = rtau1 * f3[i0] + rtau * f3eq;

f4[i0] = rtau1 * f4[i0] + rtau * f4eq;

f5[i0] = rtau1 * f5[i0] + rtau * f5eq;

f6[i0] = rtau1 * f6[i0] + rtau * f6eq;

f7[i0] = rtau1 * f7[i0] + rtau * f7eq;

f8[i0] = rtau1 * f8[i0] + rtau * f8eq;

g0[i0] = rtau3 * g0[i0] + rtau2 * g0eq;

g1[i0] = rtau3 * g1[i0] + rtau2 * g1eq;

g2[i0] = rtau3 * g2[i0] + rtau2 * g2eq;

g3[i0] = rtau3 * g3[i0] + rtau2 * g3eq;

g4[i0] = rtau3 * g4[i0] + rtau2 * g4eq;

g5[i0] = rtau3 * g5[i0] + rtau2 * g5eq;

g6[i0] = rtau3 * g6[i0] + rtau2 * g6eq;

g7[i0] = rtau3 * g7[i0] + rtau2 * g7eq;

g8[i0] = rtau3 * g8[i0] + rtau2 * g8eq;

}

}

//printf("fim");

}

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////

Page 79: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

66

void solid_BC(void)

// This is the boundary condition for a solid node. All the f's are reversed -

// this is known as "bounce-back"

{

int i,j,i0;

float f1old,f2old,f3old,f4old,f5old,f6old,f7old,f8old;

float g1old,g2old,g3old,g4old,g5old,g6old,g7old,g8old;

for (j=0;j<nj;j++){

for (i=0;i<ni;i++){

i0=I2D(ni,i,j);

if (solid[i0]==0) {

f1old = f1[i0];

f2old = f2[i0];

f3old = f3[i0];

f4old = f4[i0];

f5old = f5[i0];

f6old = f6[i0];

f7old = f7[i0];

f8old = f8[i0];

f1[i0] = f3old;

f2[i0] = f4old;

f3[i0] = f1old;

f4[i0] = f2old;

f5[i0] = f7old;

f6[i0] = f8old;

f7[i0] = f5old;

f8[i0] = f6old;

g1old = g1[i0];

g2old = g2[i0];

g3old = g3[i0];

g4old = g4[i0];

g5old = g5[i0];

g6old = g6[i0];

g7old = g7[i0];

g8old = g8[i0];

g1[i0] = g3old;

g2[i0] = g4old;

g3[i0] = g1old;

g4[i0] = g2old;

g5[i0] = g7old;

g6[i0] = g8old;

g7[i0] = g5old;

g8[i0] = g6old;

}

Page 80: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

67

}

}

}

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////

void per_BC(void)

// All the f's leaving the bottom of the domain (j=0) enter at the top (j=nj-1),

// and vice-versa

{

int i0,i1,i;

for (i=0; i<ni; i++){

i0 = I2D(ni,i,0);

i1 = I2D(ni,i,nj-1);

f2[i0] = f2[i1];

f5[i0] = f5[i1];

f6[i0] = f6[i1];

f4[i1] = f4[i0];

f7[i1] = f7[i0];

f8[i1] = f8[i0];

g2[i0] = g2[i1];

g5[i0] = g5[i1];

g6[i0] = g6[i1];

g4[i1] = g4[i0];

g7[i1] = g7[i0];

g8[i1] = g8[i0];

}

}

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////

void in_BC(void)

// This inlet BC is extremely crude but is very stable

// We set the incoming f values to the equilibirum values assuming:

// ro=roout; vx=vxin; vy=0

{

int i0, j;

float f1new, f5new, f8new, vx_term;

float g1new, g5new, g8new, vx_termg;

vx_term = 1.f + 3.f*vxin + 3.f*vxin*vxin;

f1new = roout * faceq2 * vx_term;

Page 81: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

68

f5new = roout * faceq3 * vx_term;

f8new = f5new;

vx_termg = 1.f + 3.f*vxin1 + 3.f*vxin1*vxin1;

g1new = roout1 * faceq2 * vx_termg;

g5new = roout1 * faceq3 * vx_termg;

g8new = g5new;

for (j=0; j<nj; j++){

i0 = I2D(ni,0,j);

f1[i0] = f1new;

f5[i0] = f5new;

f8[i0] = f8new;

g1[i0] = g1new;

g5[i0] = g5new;

g8[i0] = g8new;

}

}

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////

void ex_BC_crude(void)

// This is the very simplest (and crudest) exit BC. All the f values pointing

// into the domain at the exit (ni-1) are set equal to those one node into

// the domain (ni-2)

{

int i0, i1, j;

for (j=0; j<nj; j++){

i0 = I2D(ni,ni-1,j);

i1 = i0 - 1;

f3[i0] = f3[i1];

f6[i0] = f6[i1];

f7[i0] = f7[i1];

g3[i0] = g3[i1];

g6[i0] = g6[i1];

g7[i0] = g7[i1];

}

}

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////

void apply_BCs(void)

Page 82: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

69

// Just calls the individual BC functions

{

per_BC();

solid_BC();

in_BC();

ex_BC_crude();

}

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////

void display(void)

// This function is called automatically, over and over again, by GLUT

{

int i,j,ip1,jp1,i0,icol,i1,i2,i3,i4,isol;

float minvar,maxvar,frac;

// set upper and lower limits for plotting

minvar=0.0;

maxvar=0.2;

// do one Lattice Boltzmann step: stream, BC, collide:

stream();

apply_BCs();

collide();

// convert the plotvar array into an array of colors to plot

// if the mesh point is solid, make it black

for (j=0;j<nj;j++){

for (i=0;i<ni;i++){

i0=I2D(ni,i,j);

frac=(plotvar[i0]-minvar)/(maxvar-minvar);

icol=frac*ncol;

isol=(int)solid[i0];

plot_rgba[i0] = isol*cmap_rgba[icol];

}

}

// Fill the pixel buffer with the plot_rgba array

glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB,ni*nj*sizeof(unsigned int),

(void **)plot_rgba,GL_STREAM_COPY);

// Copy the pixel buffer to the texture, ready to display

Page 83: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

70

glTexSubImage2D(GL_TEXTURE_2D,0,0,0,ni,nj,GL_RGBA,GL_UNSIGNED_BYTE,0);

// Render one quad to the screen and colour it using our texture

// i.e. plot our plotvar data to the screen

glClear(GL_COLOR_BUFFER_BIT);

glBegin(GL_QUADS);

glTexCoord2f (0.0, 0.0);

glVertex3f (0.0, 0.0, 0.0);

glTexCoord2f (1.0, 0.0);

glVertex3f (ni, 0.0, 0.0);

glTexCoord2f (1.0, 1.0);

glVertex3f (ni, nj, 0.0);

glTexCoord2f (0.0, 1.0);

glVertex3f (0.0, nj, 0.0);

glEnd();

glutSwapBuffers();

}

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////

void resize(int w, int h)

// GLUT resize callback to allow us to change the window size

{

width = w;

height = h;

glViewport (0, 0, w, h);

glMatrixMode (GL_PROJECTION);

glLoadIdentity ();

glOrtho (0., ni, 0., nj, -200. ,200.);

glMatrixMode (GL_MODELVIEW);

glLoadIdentity ();

}

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////

void mouse(int button, int state, int x, int y)

// GLUT mouse callback. Left button draws the solid, right button removes solid

{

float xx,yy;

if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN)) {

Page 84: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

71

draw_solid_flag = 0;

xx=x;

yy=y;

ipos_old=xx/width*ni;

jpos_old=(height-yy)/height*nj;

}

if ((button == GLUT_RIGHT_BUTTON) && (state == GLUT_DOWN)) {

draw_solid_flag = 1;

xx=x;

yy=y;

ipos_old=xx/width*ni;

jpos_old=(height-yy)/height*nj;

}

}

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////

void mouse_motion(int x, int y)

// GLUT call back for when the mouse is moving

// This sets the solid array to draw_solid_flag as set in the mouse callback

// It will draw a staircase line if we move more than one pixel since the

// last callback - that makes the coding a bit cumbersome:

{

float xx,yy,frac;

int ipos,jpos,i,j,i1,i2,j1,j2, jlast, jnext;

xx=x;

yy=y;

ipos=(int)(xx/width*(float)ni);

jpos=(int)((height-yy)/height*(float)nj);

if (ipos <= ipos_old){

i1 = ipos;

i2 = ipos_old;

j1 = jpos;

j2 = jpos_old;

}

else {

i1 = ipos_old;

i2 = ipos;

j1 = jpos_old;

j2 = jpos;

}

jlast=j1;

for (i=i1;i<=i2;i++){

Page 85: UNIVERSIDADE ESTADUAL DE CAMPINAS …lotavio/tgs/2012_Estudo do Método...fluidos, na qual o custo computacional é elevado. Em vista de sua grande importância econômica, há um

72

if (i1 != i2) {

frac=(float)(i-i1)/(float)(i2-i1);

jnext=(int)(frac*(j2-j1))+j1;

}

else {

jnext=j2;

}

if (jnext >= jlast) {

solid[I2D(ni,i,jlast)]=draw_solid_flag;

for (j=jlast; j<=jnext; j++){

solid[I2D(ni,i,j)]=draw_solid_flag;

}

}

else {

solid[I2D(ni,i,jlast)]=draw_solid_flag;

for (j=jnext; j<=jlast; j++){

solid[I2D(ni,i,j)]=draw_solid_flag;

}

}

jlast = jnext;

}

ipos_old=ipos;

jpos_old=jpos;

}

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////