Introdução

Esse tutorial irá descrever como pre-processar, executar e pós-processar um exemplo (caso) do escoamento isotérmico, incompressível em um domínio bidimensional quadrado. A geometria é mostrada na figura 1, em que todas as fronteiras são paredes quadradas. A parede superior move-se na direção x à velocidade de 1 m/s, enquanto as outras três são estacionárias. Inicialmente, o escoamento laminar é assumido e será resolvido em uma malha uniforme usando o solver icoFoam para escoamento laminar, isotérmico, incompressível. Ao longo do tutorial, o efeito do aumento da resolução de malha e o refino de malha próximo à parede será investigado. Finalmente, o número de Reynolds será aumentado e o solver pisoFoam é empregado para escoamento turbulento, isotérmico e incompressível.

Figura 1 - Geometria da cavidade quadrada

Pré-Processamento

Casos são configurados no OpenFOAM através da edição de arquivos de configuração. Para isso, é recomendável escolher um editor de texto como emacs, vi, gedit, nedit, etc. A edição é possível porque o I/O do OpenFOAM usa um formato de dicionário com palavras-chave que transmitem significado suficiente para serem entendidos pelos usuários.

O caso simulado compreende dados para a malha, campos, propriedades, parâmetros de controle, etc. Esses dados são armazenados em um conjunto de arquivos dentro do diretório do caso ao invés de estar dentro de um único arquivo, como acontece em outros pacotes de CFD. A esse diretório do caso é atribuído um nome suficientemente descritivo. Esse tutorial consiste de um conjunto de casos localizados no diretório $FOAM_TUTORIALS/incompressible/icoFoam/cavity, o primeiro sendo denominado apenas de cavity. No primeiro passo, o usuário deve copiar o diretório do caso cavity para seu diretório de execução.

cd $FOAM_RUN 
cp -r $FOAM_TUTORIALS/incompressible/icoFoam/cavity/cavity .  
cd cavity

Geração de malha

OpenFOAM sempre opera em um sistema de coordenadas tridimensional cartesiano e todas as geometrias são geradas em três dimensões. OpenFOAM soluciona o caso em três dimensões na sua configuração padrão, no entanto pode ser configurado para solucionar em duas dimensões ao especificar uma condição de contorno especial empty nas fronteiras normais à terceira dimensão, para a qual nenhuma solução é necessária.

O domínio cavity consiste de um quadrado de lado (d) no plano (x-y). Uma malha uniforme de 20 x 20 volumes é inicialmente usada. A estrutura de bloco é mostrada na figura 2.

Figura 2 - Estrutura de bloco para a cavidade quadrada

O gerador de malhas fornecido com OpenFOAM, blockMesh, gera malhas a partir da descrição especificada em um dicionário de entrada, blockMeshDict, localizado no diretório system (ou constant/polyMesh) para um dado caso. A entrada do blockMeshDict para esse caso é fornecido abaixo.

1  /*––––––––––––––––––––––––––––––--*- C++ -*–––––––––––––––––––––––––––––––––-*\\  
2  | =========  |  |  
3  | \\\\  /  F ield  | OpenFOAM: The Open Source CFD Toolbox  |  
4  |  \\\\  /  O peration  | Version:  6  |  
5  |  \\\\  /  A nd  | Website:  https://openfoam.org  |  
6  |  \\\\/  M anipulation  |  |  
7  \\*–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––*/  
8  FoamFile  
9  {  
10  version  2.0;  
11  format  ascii;  
12  class  dictionary;  
13  object  blockMeshDict;  
14  }  
15  // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //  
16  
17  convertToMeters 0.1;  
18  
19  vertices  
20  (  
21  (0 0 0)  
22  (1 0 0)  
23  (1 1 0)  
24  (0 1 0)  
25  (0 0 0.1)  
26  (1 0 0.1)  
27  (1 1 0.1)  
28  (0 1 0.1)  
29  );  
30  
31  blocks  
32  (  
33  hex (0 1 2 3 4 5 6 7) (20 20 1) simpleGrading (1 1 1)  
34  );  
35  
36  edges  
37  (  
38  );  
39  
40  boundary  
41  (  
42  movingWall  
43  {  
44  type wall;  
45  faces  
46  (  
47  (3 7 6 2)  
48  );  
49  }  
50  fixedWalls  
51  {  
52  type wall;  
53  faces  
54  (  
55  (0 4 7 3)  
56  (2 6 5 1)  
57  (1 5 4 0)  
58  );  
59  }  
60  frontAndBack  
61  {  
62  type empty;  
63  faces  
64  (  
65  (0 3 2 1)  
66  (4 5 6 7)  
67  );  
68  }  
69  );  
70  
71  mergePatchPairs  
72  (  
73  );  
74  
75  // ************************************************************************* //

O arquivo contém alguma informação no cabeçalho (linhas 1 a 7), seguido de informação contida no subdiretório FoamFile, delimitado por chaves ({…}). No restante desse tutorial os cabeçalhos dos arquivos de entrada serão omitidos para fins de clareza.

Primeiro o arquivo especifica as coordenadas dos vértices do bloco; então ele define os blocos (aqui no caso apenas um) a partir do número identificador dos vértices e de células dentro do bloco; e finalmente o arquivo define a posição das fronteiras.

A malha é gerada ao executar o commando blockMesh no arquivo blockMeshDict. Do diretório do caso, isso é feito ao digitar no terminal:

blockMesh

O status de execução do blockMesh é exibido na janela do terminal. Qualquer erro no arquivo blockMeshDict é identificado e a respectiva mensagem de erro direciona o usuário à linha do arquivo onde o problema foi detectado. Para prosseguir, não deve haver nenhuma mensagem de erro após a execução do comando.

Condições iniciais e de fronteira

Uma vez que a malha foi gerada, o usuário agora pode verificar os campos iniciais configurados para esse caso. O tempo inicial da simulação é (t=0) s, e por isso o campo inicial é armazenado no subdiretório 0 do diretório cavity. O subdiretório 0 contém dois arquivos, p e U, um para o campo de pressão p e outro para o campo de velocidade U, onde os valores iniciais e condições de contorno são especificadas. O conteúdo do arquivo p é mostrado abaixo.

17  dimensions  [0 2 -2 0 0 0 0];  
18  
19  internalField  uniform 0;  
20  
21  boundaryField  
22  {  
23  movingWall  
24  {  
25  type  zeroGradient;  
26  }  
27  
28  fixedWalls  
29  {  
30  type  zeroGradient;  
31  }  
32  
33  frontAndBack  
34  {  
35  type  empty;  
36  }  
37  }  
38  
39  // ************************************************************************* //

Há três entradas principais nos arquivos para campos:

dimensions
especifica as dimensões do campo, nesse caso, a pressão cinemática, i.e. m2s-1;

internalFields
o campo interno, que pode ser uniforme, descrito por apenas um valor; ou não-uniforme, onde todos os valores do campo devem ser especificados;

boundaryField
o dado de fronteira que inclui as condições de fronteira e dados para as fronteiras.

Para o caso cavity, a fronteira consiste apenas de paredes, divididas em 2 máscaras (patches): (1) fixedWalls para as paredes fixas laterais e a base da cavidade; (2) movingWall para a parede móvel superior da cavidade. Como paredes, em ambas as máscaras é especificada a condição de fronteira zeroGradient para p, o que significa que o gradiente de pressão normal é nulo. A máscara frontAndBack representa os planos anterior e posterior do caso 2D e por isso são configurados como empty.

Neste caso, assim como na maioria que encontramos, os campos iniciais são especificados como uniformes. Aqui a pressão é cinemática, e como é um caso incompressível, o seu valor absoluto não é relevante, e por conveniência é atribuído o valor uniform 0.

O usuário pode de forma semelhante examinar o campo no arquivo U. As dimensões são as esperadas para a velocidade, o campo interno é inicializado com o valor uniforme igual a 0, que no caso da velocidade deve ser expresso por os três componentes do vetor, i.e. uniform (0 0 0).

O campo de fronteira para a velocidade requer a mesma condição de fronteira para a máscara frontAndBack (ou seja, empty). As outras máscaras são paredes: uma condição de não-escorregamento é assumida nas paredes do tipo fixedWalls, portanto a condição noSlip. A superfície superior move-se com a velocidade de 1 m/s na direção x, portanto requer a condição fixedValue com o valor uniform (1 0 0).

Propriedades Físicas

As propriedades físicas para o caso são armazenadas em dicionários cujos nomes recebem o sufixo …Properties, localizado no diretório constant. Para o caso icoFoam, a única propriedade que deve ser especificada é a viscosidade cinemática, no dicionário transportProperties. O usuário pode conferir se esse valor é corretamente atribuído abrindo o dicionário transportProperties. A palavra chave para a viscosidade cinemática é nu, o registro fonético para o símbolo grego ν. Inicialmente o caso é simulado com um número de Reynolds igual a 10, onde Reynolds é definido como:

Re=dU/ν
onde d e U são o comprimento e velocidade característica, respectivamente e ν é a viscosidade cinemática. Aqui d=0.1 m e U=1 m/s, então para Re=10, ν=0.01 m2s-1. A entrada correta para a viscosidade cinemática no arquivo é especificada abaixo:
17  
18  nu  [0 2 -1 0 0 0 0] 0.01;  
19  
20  
21  // ************************************************************************* //

Controle

Dados de entrada relacionando o controle do tempo e operações de escrita e leitura dos dados de solução são obtidas no dicionário controlDict. O usuário deve visualizar esse arquivo. Sendo um arquivo de controle, está localizado no diretório system.

O tempo de início/fim e o passo de tempo da simulação devem ser configurados. OpenFOAM oferece grande flexibilidade para essa configuração. No nosso caso desejamos iniciar a simulação em t=0, o que significa que o OpenFOAM precisa fazer a leitura de um diretório chamado 0. Assim, configuramos a palavra-chave startFrom para o valor startTime e especificamos startTime para o valor 0.

Para o tempo final da simulação, desejamos alcançar a solução de regime permanente. Como regra geral, o fluido deve circular pelo domínio pelo menos 10 vezes para atingir regime permanente em escoamento laminar. Nesse caso específico, como não há entrada ou saída do domínio, estipulamos o tempo necessário para a parede superior transitar 10 vezes pela extensão da cavidade, i.e. 1 s. De fato, verifica-se que um tempo de 0.5 s é suficiente, então adotaremos esse valor. Para especificar esse valor damos à palavra chave stopAt o valor endTime e atribuímos o valor 0.5 a endTime.

Agora precisamos configurar o passo de tempo, representado pela palavra-chave deltaT. Para alcançar a acurácia temporal e estabilidade numérica ao executar icoFoam, um número de Courant menor que 1 é necessário. O número de Courant para uma célula é definido por:

Co=Uδt/δx,

onde δt é o passo de tempo, U é a magnitude da velocidade na célula e δx é o tamanho da célula na direção da velocidade. A velocidade do escoamento varia ao longo do domínio e devemos assegurar que Co<1 em todo o domínio. Assim, escolhemos o valor de δt baseado no pior cenário possível; o valor máximo de Co correspondente ao efeito combinado de uma elevada velocidade do escoamento e pequeno tamanho de célula. Aqui o tamanho de célula é fixo através do domínio então o valor máximo de Co ocorre próximo da parede superior, onde a velocidade aproxima-se de 1 ms-1. O tamanho da célula é

δx=d/n=0.1/20=0.005 m.

Portanto, para garantir que o número de Courant seja menor ou igual a 1, devemos escolher um passo de tempo δt igual a:

δt=δxCo/U=0.005x1/1=0.005 s.

Durante o progresso da simulação, gostaríamos de gravar os resultados em certos intervalos de tempo de modo que possamos tratar os dados posteriormente. A palavra-chave writeControl fornece várias opções para configurar o tempo no qual os resultados são gravados; aqui escolhemos a opção timeStep que especifica que os resultados são escritos a cada passo de tempo n, onde o valor de n é especificado sob a palavra-chave writeInterval. Suponhamos que decidimos escrever os resultados nos tempos 0.1, 0.2, …, 0.5 s. Como um passo de tempo de 0.005 s, precisamos portanto escrever os resultados a cada vigésimo passo de tempo, assim especificamos o valor 20 para writeInterval.

OpenFoam cria um novo diretório que é nomeado em função do tempo corrente, e.g. 0.1 s, em cada ocasião em que dados são escritos. No solver icoFoam, os campos para as variáveis p e U são escritas nos diretórios correspondentes aos tempos. Para esse caso, as entradas no dicionário controlDict são mostradas abaixo:

17  
18  application  icoFoam;  
19  
20  startFrom  startTime;  
21  
22  startTime  0;  
23  
24  stopAt  endTime;  
25  
26  endTime  0.5;  
27  
28  deltaT  0.005;  
29  
30  writeControl  timeStep;  
31  
32  writeInterval  20;  
33  
34  purgeWrite  0;  
35  
36  writeFormat  ascii;  
37  
38  writePrecision  6;  
39  
40  writeCompression off;  
41  
42  timeFormat  general;  
43  
44  timePrecision  6;  
45  
46  runTimeModifiable true;  
47  
48  
49  // ************************************************************************* //

Discretização e configurações do solver linear

O usuário especifica a escolha do esquema de discretização de volume finito no dicionário fvSchemes contido no diretório system. A especificação do solver de sistemas lineares e tolerâncias e outros controles de algoritmo é feita no dicionário fvSolution, também contido no diretório system. O usuário pode visualizar esse dicionários, mas aqui nós não entraremos nos pormenores desses arquivos nesse momento, com exceção dos valores pRefCell e pRefValue no sub-diretório PISO do dicionário fvSolution. Em um sistema fechado, incompressível como o da cavidade, pressão é relativa: é a faixa de pressão, não o valor absoluto que importa. Em casos como esse, o solver estipula um valor de referência pRefValue na célula pRefCell. Neste exemplo, ambos são configurados para o valor 0. Uma mudança em qualquer um desses valores alterará o valor absoluto do campo de pressão, mas não os valores relativos ou o campo de velocidades.

Visualização da malha

Antes de iniciar a simulação, é uma boa prática visualizar a malha e verificar se existem erros. A malha é visualizada no ParaView, uma ferramenta de pós-processamento fornecida com o OpenFOAM. O ParaView é convenientemente aberto no caso OpenFOAM ao executar o script paraFoam de dentro do diretório do caso.

Qualquer executável UNIX/Linux pode ser executado de duas formas: como um processo em primeiro plano, _i.e._um no qual o shell espera até o comando terminar antes de retornar ao prompt; como um processo em segundo-plano, que permite ao shell aceitar comandos adicionais enquanto o primeiro ainda é executado. Como é conveniente manter o ParaView aberto enquanto outros comandos são executados do terminal, podemos executar o programa em segundo-plano usando o operador & ao digitar

paraFoam &

Alternativamente, pode ser executado de outro diretório com o argumento opcional -case fornecendo o diretório do caso, e.g.

paraFoam -case $FOAM_RUN/cavity &

Isso lança a janela ParaVIew como mostrada na figura 3.

Figura 3 - Janela do ParaFoam

No Pipeline Browser, o usuário pode ver que ParaView abriu o caso cavity. Antes de clicar no botão Apply, o usuário precisa selecionar alguma geometria do painel Mesh Parts. Pelo fato do caso ser de pequenas dimensões, é mais fácil escolher todo os dados ao selecionar a caixa adjacente ao título do painel Mesh Parts ( ou Mesh Regions), que automaticamente seleciona todos os componentes individuais que fazem parte do respectivo painel. O usuário agora deve clicar no botão Apply para carregar a geometria no ParaView.

O usuário agora deve rolar a barra lateral até o painel Display que controla a representação visual do módulo selecionado. Dentro do painel Display os seguintes passos devem ser seguidos, como mostrados na figura 4.

  1. Na seção Coloring, selecione Solid Coloring;
  2. clique Edit (em Coloring) e selecione a cor apropriada, _e.g._preto (para um fundo branco);
  3. Selecione Wireframe do menu Representation. A cor de fundo pode ser especificada no pinel View Render abaixo do painel Display na janela Properties.

Figura 4 - Visualização da malha no ParaFoam

Especialmente na primeira vez em que o ParaView é usado, é recomendável que a vista seja manipulada como a opção Use Parallel Projection (ou Camera Parallel Projection) selecionada próximo à parte inferior do painel View Render, que é disponibilizada apenas quando o botão engrenagem Advanced Properties é selecionado no topo da janela Properties, ao lado da caixa de busca.

Execução do programa

Como qualquer executável UNIX/Linux, aplicações OpenFOAM podem ser executadas em primeiro ou segundo-plano. Nessa ocasião, executaremos OpenFOAM em primeiro plano. O solver icoFoam é executado ao entrar no diretório do caso e digitar

icoFoam

no prompt, ou com o argumento opcional -case fornecendo o diretório do caso, e.g.,

icoFoam -case $FOAM_RUN/cavity

O progresso do trabalho é escrito na janela do terminal. São exibidos o tempo atual, número máximo de Courant, e resíduos inicial e final para todos os campos.

Pós-processamento

Assim que os resultados são escritos para os diretórios de tempo, eles podem ser visualizados usando paraFoam. Retorne à janela paraFoam e selecione o painel Properties para o módulo cavity.OpenFOAM. Caso os painéis corretos para o módulo não estejam presentes, assegure-se de que cavity.OpenFOAMesteja realçado na cor azul, o botão eye ao seu lado seja ativado para mostrar que os gráficos estão habilitados.

Para preparar a visualização dos dados de interesse pelo paraFoam, nós devemos primeiro carregar os dados no tempo de execução requerido de 0.5 s. Caso o exemplo tenha sido executado enquanto ParaView estivesse aberto, os dados de saída nos diretórios de tempo não serão automaticamente carregados dentro do ParaView. Para carregar os dados o usuário deve clicar Refresh Times no topo da janela Properties (suba a barra de rolagem se necessário). Os dados do tempo serão carregados no ParaView.

Para visualizar a solução no tempo t= 0.5 s., o usuário pode usar o controle VCR Controls ou Current Time Controlspara mudar o tempo atual para 0.5. Estes controles estão localizados nas barras de ferramentas no topo doa janela do ParaView, como mostrado na figura 5.

Figura 5 - Barras de ferramentas no ParaView

Colorindo superfícies

Para visualizar a pressão, o usuário deve ir até o painel Display já que ele controla a representação visual do módulo selecionado. Para fazer um gráfico simples de pressão, o usuário deve selecionar o seguinte, como mostrado na figura 6.

  1. Selecione Surface do menu Representation
  2. Selecione em Coloring
  3. Clique no botão Rescale para configurar a escala de cor para a faixa de dados, se necessário.

Figura 6 - Exibição de contornos de pressão para o caso da cavidade

O campo de pressão deve ser exibido como mostra a figura 7, com uma região de baixa pressão no canto superior esquerdo da cavidade e uma de alta pressão no canto superior direito da cavidade.

Figura 7 - Campo de pressão para o caso da cavidade

Como o ícone o campo de pressão é interpolado através de cada célula para dar uma aparência contínua. Caso o usuário selecione o ícone célula do menu Coloring, um valor único para a pressão será atribuído a cada célula de tal forma que cada célula será colorida como uma única cor, sem gradientes.

Uma legenda para cor pode ser adicionada ao clicar o botão Toggle Color Legend Visibility na barra de ferramentas Active Variable Controls ou o botão Show na seção Coloring do painel Display. A legenda pode ser posicionada na janela de imagem ao arrastar e largar com o mouse. O botão Edit, tanto na barra de ferramentas Active Variable Controls ou no painel Coloring do painel Display, abre a janela Color Map Editor, como mostrado na figura 8, onde o usuário pode configurar uma série de atributos da escala de cores e da barra de cores.

Figura 8 - Color Map Editor

A configuração padrão do ParaView é o uso de uma escala de cores que vai do azul ao branco ao vermelho ao invés da escala mais comum do azul ao verde ao vermelho (arco-íris). Dessa forma, a primeira vez que o usuário executa o ParaView, talvez deseje alterar a escala de cores. Isso pode ser feito ao selecionar o botão Choose Preset (com o ícone de coração) noColor Scale Editor e selecionar Blue to Red Rainbow. Após clicar no botão de confirmação OK, o usuário pode clicar no botão Save as Default na parte inferior do painel (símbolo de disco rígido) para que o ParaView sempre adote esse tipo de barra de cores.

O usuário pode também editar as propriedades da legenda de cores, tal como tamanho de fonte, tipo de fonte e formato de numeração para a escala ao clicar Edit Color Legend Properties no lado direito extremo da barra de busca, como mostrado na figura 8.

Plano de corte (fatia)

Ao rotacionar a imagem segurando o botão esquerdo do mouse na janela de imagem e movimentando o cursor, o usuário pode perceber que toda s superfície da geometria foi colorida pelo valor da pressão. Para gerar um gráfico com um plano 2-D de linhas de contorno, o usuário deve primeiro criar um plano de corte, ou ‘fatia’. Como o módulo cavity.OpenFOAM realçado no Pipeline Browser, o usuário deve selecionar o filtro Slice fo menu Filters no topo do menu do ParaView (acessível no topo da tela em alguns sistemas). O filtro Slice pode ser encontrado no sub-menu Common, mas uma vez selecionado, este é movido para o sub-menu Recent, desaparecendo do sub-menu Common. O plano de corte deve ser centrado em (0.05, 0.05, 0.005) e sua normal dev ser configurada para (0, 0, 1)(clique no botão Z Normal).

Gráficos com Contornos

Uma vez gerado o plano de corte, contornos podem ser criados ao aplicar o filtro Contour. Como o módulo Slice realçado no Pipeline Browser, o usuário deve selecionar o filtro Contour. No painel Properties, o usuário deve selecionar pressão do menu Contour By. Sob Isosurfaces, o valor padrão pode ser deletado com o botão de menos e uma faixa de 10 valores pode ser adicionado. Os contornos podem ser exibidos como a representação Wireframe se Coloring for sólido ou por um campo, e.g. pressão.

Gráficos de vetores

Antes de exibir os vetores do campo de velocidades, pode ser útil remover outros módulos que tenham sido criados,e.g. com os filtros Slice e Contour descritos acima. Estes podem ser deletados completamente, ao realçar o módulo relevante no Pipeline Browser e clicar em Delete no painel Properties respectivo; ou ao desabilitados ao acionar o botão eye para o módulo relevante no Pipeline Browser.

Desejamos agora gerar um glifo para a velocidade no centro de cada célula. Primeiramente precisamos filtrar os dados para o centro das células. Com o módulo cavity.OpenFoam realçado no Pipeline Browser, o usuário deve selecionar Cell Centers do menu Filter->Alphabetical e clicar Apply.

Com Centers realçados no Pipeline Browser, o usuário deve selecionar Glyph do menu Filter->Common. A janela Properties deve aparecer como mostrado na figura 9. Note que os filtros recém-selecionados são movidos para o menu Filter->Recente não são disponíveis nos menus de onde foram inicialmente selecionados. No painel Properties resultante, o campo de velocidade, U, deve ser selecionado do menu vectors. O usuário deve configurar o Scale Mode para os glifos para a opção off, com o Set Scale Factor no valor 0.005. Ao clicar Apply, os glifos aparecem, mas provavelmente com uma única cor, e.g., branco. O usuário deve colorir os glifos com a magnitude da velocidade, que é controlado ao configurara Color by U no painel Display. O usuário também pode selecionar Show Color Legend em Edit Color Map. O resultado desse processo é mostrado na figura 10, onde a fonte caixa alta Times Roman foi selecionada para os cabeçalhos Color Legend e as legendas foram configuradas para mostrar dois algarismos significativos ao desselecionar Automatic Label Format e entrando com %-#6.2f na caixa de texto Label Format. A cor de fundo foi configurada para branca no painel General de View Settings.

Figura 9 - Painel de propriedades para o filtro Glyph

Figura 10 - Velocidades no caso cavity

Note que na parede esquerda e direita, os glifos aparentam indicar escoamento através da parede. No entanto, é claro que, apesar do direção do vetor estar normal à parede, a magnitude assume o valor 0. Essa situação um pouco confusa é causada pelo fato do ParaView escolher orientar os glifos na direção x quando a opção de escalonamento do glifo é off e a magnitude da velocidade é 0.

Gráficos de linha de corrente

Novamente, antes do usuário continuar a fazer pós-processamento no ParaView, deve desabilitar os módulos tais como aqueles usados para o gráfico de vetores descritos acima. Desejamos agora exibir linhas de corrente do campo de velocidades. Como o módulo cavity.OpenFoam realçado no Pipeline Browser, o usuário de e selecionar Stream Tracer do menu Filter e clicar Apply, A janela do painel Properties deve ser exibida como mostra a figura 11.

Figura 11 - Painel de propriedades para o filtro Stream Tracer

Os pontos de semeamento Seed deven ser especificados ao longo uma linha de alta resolução, High Resilution Line Source, que atravessa verticalmente o domínio pelo centro da geometria, i.e. de (0.05, 0, 0.005) a (0.05, 0.1, 0.005 ). Para a imagem exibida na figura 12 foi usado o valor Resolution igual a 21; Maximum Step Length de 0.5; Initial Step Length de 0.2 e Integration Direction BOTH. O integrador Runge-Kutta 4/5 IntegratorType foi usado com seus parâmetros padronizados.

Ao clicar Apply o traço é gerado. O usuário deve então selecionar Tube do menu Filter para produzir imagens de linhas de corrente com elevada qualidade. Para a imagem mostrada na figura 12 foi usado Num. sides 6; Radius 0.0003 e Radius factor 10. Os tubos de corrente são coloridos pela magnitude de velocidade. Ao clicar Apply a figura 12 deve ser gerada.

Figura 12 - Linhas de correte para o caso cavidade

Refinamento de malha

A resolução da malha irá ser agora aumentada por um fator dois em cada direção. Os resultados da malha mais grosseira serão mapeadas para a malha mais refinada para usar como condição inicial para o problema. A solução da malha mais refinada será então comparada com a da malha mais grosseira.

Criação de um novo caso a partir de um já existente

Desejamos agora criar um novo caso denominado cavityFine que será criado a partir do caso cavity. O usuário deve portanto clonar o caso cavity e editar os arquivos necessários. Primeiro o usuário deve ir a diretório run, ao digitar

cd $FOAM_RUN

Note que há também um alias conveniente, chamado run, que reproduz o comando acima para mudar o diretório para $FOAM_RUN, simplesmente ao digitar run.

O caso cavityFine pode ser criado ao estabelecer um novo diretório caso e copiar os diretórios relevantes do caso cavity.

mkdir cavityFine  
cp -r cavity/constant cavityFine  
cp -r cavity/system cavityFine

O usuário pode então preparar a nova simulação ao mudar de diretório para o novo caso.

cd cavityFine

Criação da malha mais refinada

Nós desejamos agora aumentar o número de células através do blockMesh. O usuário deve abrir o arquivo blockMeshDict no diretório system em um editor de texto e editar a especificação do bloco. Os blocos são especificados abaixo da palavra-chave blocks. A sintaxe das definições de bloco pode ser consultada no manual do OpenFoam; nesse momento é suficiente saber que em seguida do primeiro hex está a lista de vértices do bloco, depois uma lista (ou vetor) com o número de células em cada direção. Esse valor estava originalmente configurado para (20 20 1) no caso cavity. O usuário deve agora mudar isso para (40 40 1) e gravar o arquivo. A nova malha refinada deve ser criada com o comando blockMesh como foi feito anteriormente.

Mapeamento dos resultados da malha grosseira para a malha mais refinada

A ferramenta mapFields mapeia um ou mais campos relacionados a uma dada geometria nos campos correspondentes para uma outra geometria. Em nosso exemplo, os campos são considerados ‘consistentes’ porque a geometria e os tipos e condições de fronteira, tanto da origem quanto do destino, são idênticos. Nós usamos a opção de comando - consistent ao executar o comando mapFields nesse exemplo.

Os dados de campo mapeado por mapFields é lido do diretório de tempo especificado por startFrom e startTime no dicionário controlDict do caso destino, i.e. aquele no qual os resultados são mapeados. Nesse exemplo, nós desejamos mapear os resultados finais da malha mais grosseira do caso cavity para a malha mais fina do caso cavityFine. Assim, já que esses resultados estão armazenados no diretório 0.5 de cavity, startTime deve ser configurado para 0.5 no dicionário controlDict e startFrom deve ser configurado para startTime.

O caso está preparado para executar mapFields. Digitar mapFields -help rapidamente mostra que mapFields requer a fonte do diretório caso como um argumento. Nós usamos a opção -consistent, então a ferramenta é executada de dentro o diretório cavityFine através do comando:

mapFields ../cavity -consistent

A ferramenta deve ser executada e exibir as seguintes informações na tela do terminal:

Source: ".." "cavity"  
Target: "." "cavityFine"  
  
Create databases as time  
  
Source time: 0.5  
Target time: 0.5  
  
Create meshes  
  
Source mesh size: 400  Target mesh size: 1600  
  
Consistently creating and mapping fields for time 0.5  
  
interpolating p  
interpolating U  
  
End

Ajustes de controle

Para manter o número de Courant menor que um, como discutido anteriormente, o passo de tempo deve ser agora reduzido pela metade já que todas as células foram reduzidas pela metade. Dessa forma, deltaT deve ser configurado para 0.0025 no dicionário controlDict. Dados do campo são atualmente escritos em um número fixo de passos de tempo. Aqui nos demonstramos como especificar a saída de dados em intervalos fixos de tempo. Sob a palavra-chave writeControl no dicionário controlDict, ao invés de requerer a saída por um número fixo de passos de tempo com a entrada timeStep, uma quantidade fixa de tempo pode ser especificada entre a saída de dados ao adotar a entrada runTime. Nesse caso o usuário deve especificar uma saída a cada 0.1 s e portanto deve configurar writeInterval para o valor 0.1 e writeControl para runTime. Finalmente, como o caso inicia com a solução obtida na malha mais grosseira, nós somente necessitamos executar a simulação por um período longo suficiente para atingir convergência razoável para regime permanente. Assim, endTime deve ser configurado para o valor de 0.7, correspondendo a 0.7 s. Certifique-se de que essas configurações estão corretas e grave o arquivo.

Executar o código como um processo em segundo-plano

O usuário deve experimentar executar icoFoam como um processo em segundo plano, redirecionando a saída do terminal para um arquivo log que pode ser visualizado posteriormente. Do diretório cavityFine, o usuário deve executar:

icoFoam > log &  
cat log

Gráfico de vetores com malha refinada

O usuário pode abrir múltiplos casos simultaneamente no ParaView, essencialmente porque cada caso é simplesmente um módulo adicional que aparece no Pipeline Browser. Há um inconveniente ao abrir um novo caso OpenFOAM no ParaView porque o programa espera que os dados estejam armazenados em um único arquivo que contém a extensão que permite estabelecer o formato. No entanto, o OpenFOAM armazena os dados do caso em múltiplos arquivos sem uma extensão no nome, dentro de uma estrutura específica de diretório. O módulo de leitura ParaView trabalha na base de que, ao abrir os dados de um caso no formato OpenFOAM, é associado um arquivo dummy (vazio) com a extensão .OpenFOAM que reside no diretório do caso. O script paraFoam automaticamente cria esse arquivo. Para o exemplo cavityFine, isso é alcançado executando o seguinte comando do diretório do caso:

paraFoam -touch

O caso cavityFine pode ser carregado dentro do ParaView ao selecionar Opendo menu Filee navegar para o diretório cavityFine e selecionar o arquivo cavityFine.OpenFOAM. O usuário pode agora fazer um gráfico com os vetores do campo de velocidade da malha refinada no ParaView. Esse gráfico pode ser comparado com o caso cavity ao habilitar imagens glifo para ambos os casos simultaneamente.

Confecção de gráficos

O usuário pode desejar visualizar os resultados na forma de uma medida escalar ao longo de linhas dentro do domínio. OpenFOAM tem os recursos adequados para essa manipulação de dados. Há inúmeras ferramentas que realizam operações específicas, e a ferramenta postProcess que inclui uma faixa ampla de funcionalidade de pós-processamento. As funções disponíveis de pós-processamento podem ser listadas com o comando:

postProcess -list

As funções components e mag fornecem medidas escalares úteis do campo de velocidades. Quando a função components é executada em um caso, e.g. cavity, ela lê os dados do campo de velocidade de cada diretório de tempo e, nos correspondentes diretórios de tempo, escreve os escalares Ux,Uy e Uz, representando os componentes de velocidade nas direções x, y e z.

O usuário pode executar postProcess com a função components em ambos os casos cavity e cavityFine. Por exemplo, para o caso cavity o usuário deve entrar no diretório cavity e executar postProcess de acordo com o comando:

cd $FOAM_RUN/cavity  
postProcess -func "components(U)"

Os componentes individuais pode ser exibidos como um gráfico no ParaView. É rápido, conveniente, e há um controle razoável sobre as legendas e formatação, portanto a saída impressa é de um padrão razoável. No entanto, para confeccionar gráficos destinados à publicação, é preferível escrever os dados em formato bruto e fazer os gráficos com software especializado, tal como o gnuplot ou Grace/xmgr. Para fazer isso, recomenda-se usar ferramentas de amostragem descritas no manual do OpenFOAM.

Antes de começar a plotar, o usuário precisa carregar os campos gerados Ux,Uy e Uz no ParaView. Clique em Refresh Times no topo do painel Properties para o módulo cavity.OpenFoam. O campos são carregados no ParaView e exibidos na janela Volume Fields. Assegure-se de que os novos campos são selecionados e que mudanças são aplicadas, i.e. clique em Apply se necessário. Ainda, dados são interpolados de forma incorreta nas fronteiras se as regiões de fronteira são selecionadas no painel Mesh Parts. Assim, o usuário deve desselecionar as máscaras (patches) no painel Mesh Parts, i.e. movingWall, fixedWall e frontAndBack, e aplicar as mudanças.

Agora, para exibir o gráfico no ParaView, o usuário deve selecionar o módulo de interesse, e.g. cavity.OpenFOAM e aplicar o filtro Plot Over Line do menu Filter->Data Analysis. Isto abre uma nova janela XY Plot abaixo ao lado da janela 3D View existente. Um módulo PlotOverLine é criado no qual o usuário pode especificar os pontos que delimitam a linha no painel Properties. Nesse exemplo, o usuário deve posicionar uma linha vertical no centro do domínio, i.e. de (0.05, 0, 0.005) para (0.05, 0.1, 0.005) nas caixas de texto Point1 e Point2 respectivamente. Resolution pode ser configurado para o valor 100.

Ao clicar Apply, um gráfico é criado na janela XY Plot. No painel Display, o usuário deve configurar o Attribute Mode para Point Data. A opção Use Data Array pode ser selecionado para X Axis Data, adotando a opção arc_length para que o eixo das abcissas do gráfico represente a distância da base da cavidade.

O usuário pode criar os campos a serem exibidos no painel Line Series da janela Display. Da lista de campos escalares exibidas, pode-se ver que a magnitude e componentes do campos vetoriais são exibidos por padrão, i.e. exibidos como U_x, de tal forma que não era necessário criar Ux usando a função componentes. De todo modo, o usuário deve desselecionar todas as séries com exceção de Ux (ou U_x). Uma caixa colorida quadrada na coluna adjacente à serie selecionada indica a cor da linha. O usuário pode editar esse atributo facilmente com um duplo-clique do mouse sobre a seleção. Veja a figura 13.

Figura 13 - Seleção de campos para a confecção de gráficos

Para formatar o gráfico, o usuário deve modificar as configurações abaixo do painel Line Series, especificamente Line Color, Line Thickness, Line Style, Marker Style e Chart Axes.

O usuário pode também clicar um dos botões acima do canto superior esquerdo do XY Plot. O terceiro botão, por exemplo, permite ao usuário controlar View Settings, onde o usuário pode configurar o título e legenda para cada eixemos, por exemplo. Ainda, o usaria pode controlar a fonte, cor, e alinhamento dos títulos dos eixo, até de várias outras opções para a faixa de valores dos eixos e legendas em escala linear ou logarítmica.

A figura 14 é um gráfico produzido pelo ParaView. O usuário pode criar o gráfico como desejar. Para referência, o gráfico da figura 14 foi criado com as opções para os eixos: tipo Standard para Notation; Specify Axis Range selecionado; títulos na fonte Sans Serif 12. O gráfico é exibido com uma série de pontos ao invés de uma linha ao ativar o botão Enable Line Series na janela Display. Observação: caso o botão pareça estar desativado por estar em cinza, este pode ser ativado ao selecionar e desselecionar o conjunto de variáveis no painel Line Series. Uma vez que o botão Enable Line Series é selecionado, Line Style e Marker Style podem ser ajustados para a preferência do usuário.

Figura 14 - Confecção de gráficos no paraFoam

Uso de malha não-uniforme

O erro em qualquer solução será mais pronunciado em regiões onde a forma da solução verdadeira difere drasticamente da forma assumida em um esquema numérico escolhido. Por exemplo, um esquema numérico baseado na variação linear de variáveis através das células é capaz de gerar uma solução exata apenas quando a solução verdadeira é linear em sua forma. O erro é máximo em regiões onde a solução verdadeira apresenta o maior desvio de uma forma linear, _i.e., onde a mudança no gradiente é máxima. O erro diminui com o tamanho da célula.

É útil possuir uma apreciação intuitiva da forma da solução antes de configurar qualquer problema. Assim é possível antecipar onde os erros serão maiores e escolher uma malha não-uniforme onde o refino maior esteja nessas regiões. No caso cavity as grandes variações em velocidade são esperadas próximo às paredes, então nessa parte do tutorial a malha será refinada nessas regiões. Ao usar o mesmo número de células, uma maior acurácia pode ser alcançada sem um aumento significativo no custo computacional.

Uma malha de 20 x 20 células com refino na direção das paredes será criada para o problema da cavidade com tampa móvel e os resultados obtidos do caso cavityFine serão mapeados na malha não-uniforme para serem usados como condição inicial. Os resultados da malha não-uniforme serão comparados como aqueles das malhas anteriores. Uma vez que as mudanças no dicionário blockMeshDict são substanciais, o caso usado para parte desse tutorial, cavityGrade, é fornecido no diretório $FOAM_TUTORIALS/incompressible/icoFoam/cavity. O usuário deve copiar o caso cavityGrade no diretório run, e depois seguir os passos descritos abaixo.

Criação da malha

A malha requer agora 4 blocos com espaçamento diferente no lado esquerdo, direito, superior e inferior do domínio. A estrutura de bloco usado para essa malha é mostrada na figura 15.

Figura 15 - Estrutura de bloco da malha não-uniforme para a cavidade (número dos blocos circulados)

O usuário pode visualizar o arquivo blockMeshDict no subdiretório system do caso cavityGrade; para completude os elementos chave do arquivo blockMeshDict são reproduzidos abaixo. Cada bloco possui agora 10 células nas direções x e y e a razão entre a maior e menor célula é 2.

17  convertToMeters 0.1;  
18  
19  vertices  
20  (  
21  (0 0 0)  
22  (0.5 0 0)  
23  (1 0 0)  
24  (0 0.5 0)  
25  (0.5 0.5 0)  
26  (1 0.5 0)  
27  (0 1 0)  
28  (0.5 1 0)  
29  (1 1 0)  
30  (0 0 0.1)  
31  (0.5 0 0.1)  
32  (1 0 0.1)  
33  (0 0.5 0.1)  
34  (0.5 0.5 0.1)  
35  (1 0.5 0.1)  
36  (0 1 0.1)  
37  (0.5 1 0.1)  
38  (1 1 0.1)  
39  );  
40  
41  blocks  
42  (  
43  hex (0 1 4 3 9 10 13 12) (10 10 1) simpleGrading (2 2 1)  
44  hex (1 2 5 4 10 11 14 13) (10 10 1) simpleGrading (0.5 2 1)  
45  hex (3 4 7 6 12 13 16 15) (10 10 1) simpleGrading (2 0.5 1)  
46  hex (4 5 8 7 13 14 17 16) (10 10 1) simpleGrading (0.5 0.5 1)  
47  );  
48  
49  edges  
50  (  
51  );  
52  
53  boundary  
54  (  
55  movingWall  
56  {  
57  type wall;  
58  faces  
59  (  
60  (6 15 16 7)  
61  (7 16 17 8)  
62  );  
63  }  
64  fixedWalls  
65  {  
66  type wall;  
67  faces  
68  (  
69  (3 12 15 6)  
70  (0 9 12 3)  
71  (0 1 10 9)  
72  (1 2 11 10)  
73  (2 5 14 11)  
74  (5 8 17 14)  
75  );  
76  }  
77  frontAndBack  
78  {  
79  type empty;  
80  faces  
81  (  
82  (0 3 4 1)  
83  (1 4 5 2)  
84  (3 6 7 4)  
85  (4 7 8 5)  
86  (9 10 13 12)  
87  (10 11 14 13)  
88  (12 13 16 15)  
89  (13 14 17 16)  
90  );  
91  }  
92  );  
93  
94  mergePatchPairs  
95  (  
96  );  
97  
98  // ************************************************************************* //

Uma vez que o usuário esteja satisfeito com o arquivo blockMeshDict para esse caso, pode executar blockMesh da linha de comando. A malha não-uniforme pode ser visualizada com o paraFoam como descrito anteriormente.

Mudança do tempo e passo de tempo

As velocidades mais altas e menores tamanhos de células estão próximas à tampa (parede superior), portanto os números de Courant mais altos serão gerados nessa região, por razões descritas anteriormente. É útil portanto estimar o tamanho das células próximas à tampa para calcular um passo de tempo apropriado para esse caso.

Quando uma malha não-uniforme é usada, blockMesh calcula o tamanho da célula usando uma progressão geométrica. Ao longo do comprimento l , se n células são requisitadas como uma razão R entre a última e a primeira célula, o tamanho da menor célula, δxs, é dado por:

δxs=l (r-1)/(αr-1)

onde r é a razão entre o tamanho de uma célula e a próxima, dado por:

r=R1/(n-1)

e

α=R se R>1
ou
α=1-r-n+r-1 se R<1

Para o caso cavityGrade o número de células em cada direção em um bloco é 10, a razão entre célula maior e menor é 2 e a altura do bloco e largura do bloco é 0.05 m. Portanto o menor tamanho de célula é 3.45 mm. Da equação que define o número de Courant, o passo de tempo deve ser menor que 3.45 ms para manter um Courant menor que 1. Para assegurar que os resultados são escritos em intervalos de tempo convenientes, o passo de tempo deltaT deve ser reduzido para 2.5 ms e writeInterval deve ser especificado como 40 para que os resultados sejam escritos a cada 0.1 s. Essas configurações pode ser visualizadas no arquivo cavityGrade/system/controlDict.

A variável startTime precisa ser configurada para para a condição final do caso cavityFine, i.e. 0.7. Uma vez que cavity e cavityFine convergiram dentro tempo de simulação prescrito, nós podemos configurar o tempo de simulação para o caso cavityGrade para 0.1 s, i.e. endTime deve ser 0.8.

Mapear os campos

Use a ferramenta mapFields para mapear os resultados finais do caso cavityFine para a malha do caso cavityGrade. Entre no diretório do cavityGrade e execute mapFields com o comando:

cd $FOAM_RUN/cavityGrade  
mapFields ../cavityFine -consistent

Agora, execute icoFoam do diretório do caso e monitore a informação de execução. Visualize os resultados convergidos para esse caso e compare com os outros resultados usando as ferramentas de pós-processamento descritos anteriormente.

Aumento do número de Reynolds

Os casos até agora executados possuíram um número de Reynolds de 10. Esse número é bastante baixo e converge para uma solução estável rapidamente com apenas pequenos vórtices secundários nos cantos inferiores da cavidade. Nós iremos agora aumentar o número de Reynolds para 100, ponto a partir do qual a solução tarda um tempo significativamente maior para convergir. Inicialmente a malha mais grosseira do caso cavity irá usada. O usuário deve clonar o caso cavity e nomeá-lo cavityHighRe. Ao invés de copiar diretórios individuas (system,constant, etc.) como descrito previamente, a ferramenta foamCloneCase pode ser usada, a qual copia os diretórios relevantes em um único passo. Por padrão, o diretório de tempo 0 é copiado, mas aqui o usuário pode usar a opção -latestTime para copiar o diretório correspondente ao último tempo, 0.5, o qual pode ser usado como campo inicial para a nossa simulação. O exemplo também usa o alias run como uma forma rápida de mudar para o diretório run.

run  
foamCloneCase -latestTime cavity cavityHighRe  
cd cavityHighRe

Pré-processamento

Entre no caso cavityHighRe e edite o dicionário _transportProperties_no diretório constant. Já que o número de Reynolds precisa ser aumentado por um fator 10, diminua a viscosidade cinemática por um fator 10, i.e. para 1x10-3m2s-1. Nos agora executamos esse caso reiniciando da solução do tempo final do caso cavity. Para fazer isso podemos usar a opção de configurar a palavra-chave startFrom para latestTime para que icoFoam use como dados iniciais os valores armazenados no diretório que corresponde ao tempo mais recente, i.e. 0.5. A palavra-chave endTime deve ser 2 s.

Execução do código

Execute icoFoam para o caso do diretório do caso e visualize a informação de execução. Ao executar um trabalho em segundo-plano, os seguintes comandos em UNIX podem ser úteis:

nohup
permite a execução do comando mesmo após o usuário sair do sistema.

nice
muda a prioridade do trabalho no gerenciador de cronograma do kernel; um fator niceness de -20 é a mais alta prioridade e 19 é a mais baixa prioridade.

Isso é útil, por exemplo, se o usuário deseja configurar o caso para ser rodado em uma máquina remota e não deseja monitorar o trabalho intensamente, podendo assinalar uma prioridade baixa naquela máquina. Nessa instância, o comando nohup permite que o usuário faça log out da máquina remota enquanto o trabalho continua a ser executado; já 19 impõe uma prioridade baixa. Para esse caso de interesse, podemos executar o comando como mostrado abaixo.

nohup nice -n 19 icoFoam > log &  
cat log

Em casos anteriores você ode ter notado que o icoFoam termina de solucionar para a velocidade U rapidamente, mas continua a solucionar para a variável de pressão p para um tempo maior ou até o final da execução. Na prática, uma vez que icoFoam para de solucionar para U e o resíduo inicial de p é menor que a tolerância configurada no dicionário fvSolution (tipicamente 10-6), a execução efetivamente convergiu e pode ser concluída uma vez que os dados tenham sido escritos no diretório do tempo. Por exemplo, na condição de convergência uma amostra do arquivo log da execução do caso cavityHighRe é mostrado abaixo, no qual a velocidade convergiu após 1.395 s e os resíduos iniciais de pressão são pequenos; No Iterations 0 indica que a solução de U foi concluída:

1  Time = 1.43  
2  
3  Courant Number mean: 0.221921 max: 0.839902  
4  smoothSolver:  Solving for Ux, Initial residual = 8.73381e-06, Final residual = 8.73381e-06, No Iterations 0  
5  smoothSolver:  Solving for Uy, Initial residual = 9.89679e-06, Final residual = 9.89679e-06, No Iterations 0  
6  DICPCG:  Solving for p, Initial residual = 3.67506e-06, Final residual = 8.62986e-07, No Iterations 4  
7  time step continuity errors : sum local = 6.57947e-09, global = -6.6679e-19, cumulative = -6.2539e-18  
8  DICPCG:  Solving for p, Initial residual = 2.60898e-06, Final residual = 7.92532e-07, No Iterations 3  
9  time step continuity errors : sum local = 6.26199e-09, global = -1.02984e-18, cumulative = -7.28374e-18  
10  ExecutionTime = 0.37 s  ClockTime = 0 s  
11  
12  Time = 1.435  
13  
14  Courant Number mean: 0.221923 max: 0.839903  
15  smoothSolver:  Solving for Ux, Initial residual = 8.53935e-06, Final residual = 8.53935e-06, No Iterations 0  
16  smoothSolver:  Solving for Uy, Initial residual = 9.71405e-06, Final residual = 9.71405e-06, No Iterations 0  
17  DICPCG:  Solving for p, Initial residual = 4.0223e-06, Final residual = 9.89693e-07, No Iterations 3  
18  time step continuity errors : sum local = 8.15199e-09, global = 5.33614e-19, cumulative = -6.75012e-18  
19  DICPCG:  Solving for p, Initial residual = 2.38807e-06, Final residual = 8.44595e-07, No Iterations 3  
20  time step continuity errors : sum local = 7.48751e-09, global = -4.42707e-19, cumulative = -7.19283e-18  
21  ExecutionTime = 0.37 s  ClockTime = 0 s

Escoamento com elevado número de Reynolds

Visualize os resulted no paraFoam e exiba os vetores velocidade. Os vórtices secundários nos cantos aumentaram de tamanho. O usuário pode então aumentar ainda mais o número de Reynolds ao diminuir a viscosidade e executar novamente a simulação. O número de vórtices aumenta, portanto a resolução da malha em torno deles terá de aumentar para poder solucionar o padrão de escoamento mais complexo. Adicionalmente, com o aumento do número de Reynolds o tempo requerido para convergência também aumenta. O usuário deve monitorar os resíduos e estender endTime adequadamente para assegurar convergência.

A necessidade de aumento de resolução temporal e espacial torna-se inviável na medida em que o escomanento adentra o regime turbulento, onde problemas da estabilidade da solução também pode ocorrer. Evidentemente, muitos problemas de engenharia possuem números de Reynolds elevados e seria demasiado custoso solucionar o problema de turbulência diretamente. Ao invés disso, modelos de turbulência como as Médias de Reynolds das Equações de Navier-Stokes são usadas (RAS no OpenFOAM, RANS na literatura) para solucionar o comportamento do escoamento médio e para calcular as estatísticas das flutuações. O modelo padrão k-ε com funções de parede será usado nesse tutorial para solucionar o caso da cavidade quadrada com tampa móvel com um número de Reynolds igual a 104. Duas variáveis adicionais são solucionadas: k, a energia cinética turbulenta, e ε, a taxa de dissipação de energia cinética turbulenta. As equações adicionais e os modelos para escoamento turbulento são implementados em um solver do OpenFOAM chamado pisoFoam.

Pré-processamento

Retorne ao diretório run e copie o caso cavity no diretório $FOAM_RUN/tutorials/incompressible/pisoFoam/RAS, renomeando-o cavityRAS para evitar um conflito com o tutorial existente cavity. Entre no novo diretório.

run  
cp -r $FOAM_TUTORIALS/incompressible/pisoFoam/RAS/cavity cavityRAS  
cd cavityRAS

Gere a malha executando blockMesh como anteriormente. Refinamento da malha na direção da parede não é necessário ao adotar o modelo padrão k-ε com função de parede já que o escoamento próximo à parede é modelado, ao invés de ser resolvido.

Uma gama de modelos de função de parede estão disponíveis no OpenFOAM que são aplicados como condições de fronteira em máscaras individuais. Isso permite que modelos de parede distintos sejam usado para regiões de parede diferentes. A escolha do modelo função de parede é especificada através do campo de viscosidade turbulenta, νt no arquivo 0/nut.

7  
18  dimensions  [0 2 -1 0 0 0 0];  
19  
20  internalField  uniform 0;  
21  
22  boundaryField  
23  {  
24  movingWall  
25  {  
26  type  nutkWallFunction;  
27  value  uniform 0;  
28  }  
29  fixedWalls  
30  {  
31  type  nutkWallFunction;  
32  value  uniform 0;  
33  }  
34  frontAndBack  
35  {  
36  type  empty;  
37  }  
38  }  
39  
40  
41  // ************************************************************************* //

Esse caso usa funções de parede padrão, especificados pelo tipo nutWallFunction nas máscaras movingWall e fixedWalls. Outras modelos de função de parede inclui função de parede com rugosidade, especifados através da palavra-chave nutRoughWallFunction.

O usuário deve agora abrir os arquivos para k e ε (0/k e 0/epsilon) e examinar as condições de contorno. Para uma condição de fronteira de parede, é atribuído a ε a condição de contorno epsilonWallFunction e a condição de fronteira kqRWallFunction a k. Este último é uma condição de contorno genérica que pode ser alpicada a qualquer campo que é do tipo de energia cinética turbulenta, e.g. k, q ou tensão de Reynolds R. Os valores iniciais para k e ε são configurados através de uma estimativa da componente flutuante da velocidade U’ e da escala de comprimento turbulenta, l. k e ε são definidos em termos desses parâmetros de acordo com as equações abaixo.

k=1/2<U’U’>
ε=Cμ0.75k1.5/l

onde Cμ é uma constante do modelo k-ε igual a 0.09. Para um sistema de coordenadas cartesiano, k é dado por

k=1/2(U’x2+U’y2+U’z2)

onde U’x2, U’y2 e U’z2 são os quadrados das componentes flutuantes da velocidade nas direções x, y e z respectivamente. Assumiremos que a turbulência é isotrópica, i.e, U’x2=U’y2=U’z2, e igual a 5% da velocidade da tampa e que l é igual a 5% da largura da cavidade, 0.1 m. Nesse caso k e ε são dados por:

U’x=U’y=U’z=5/100 x 1 ms-1
k=3/2(5/100)2 m2s-2=3.75x10-3m2s-2
ε=Cμ0.75k1.5/l=7.54x10-3m2s-3

Esses formam os dados iniciais para k e ε. As condições iniciais para U e p são (0, 0, 0) e 0 respectivamente, como anteriormente.

Modelagem da turbulência inclui uma gama de modelos, e.g. RANS ou simulação dos grandes turbilhões (LES), que são disponíveis em OpenFOAM. A escolha de um modelo de turbulência é possível por meio da palavra-chave simulationType no dicionário turbulenceProperties. O usuário pode visualizar esse arquivo no diretório constant.

17  
18  simulationType  RAS;  
19  
20  RAS  
21  {  
22  RASModel  kEpsilon;  
23  
24  turbulence  on;  
25  
26  printCoeffs  on;  
27  }  
28  
29  // ************************************************************************* //

As opções para simulationType são laminar, RAS (corresponde a RANS na literatura) e LES. Com RAS selecionado neste caso, a escolha de modelagem RAS é especificada em um subdicionário RAS. O modelo de turbulência é selecionado pela entrada RASModel de uma longa lista de modelos disponíveis que podem ser consultadas no guia do OpenFOAM. O modelo kEpsilon deve ser selecionado, o qual é o modelo k-ε padrão; o usuário deve assegurar-se também que turbulence
esta configurado como on.

Os coefficients para cada modelo de turbulência são armazenados no respectivo código como um conjunto de valores. Configurando a opção adicional printCoeffs para on fará esses valores serem impressos para a saída padrão, i.e o terminal, quando o modelo é chamado na execução. Os coeficientes são impressos como um sub-dicionário cujo nome é aquele do nome do modelo com a palavra Coeffs adicionada, e.g. kEpsilonCoeffs no caso do modelo kEpsilon. Os coeficientes do modelo, e.g. kEpsilon podem ser modificados opcionalmente ao incluir o sub-direcionário (copiando e colando) dentro do sub-dicionário RAS e fazendo o ajuste de valores como desejado.

O usuário deve agora ajustar a viscosidade cinemática molecular no dicionário transportProperties. Para alcançar um número de Reynolds de 104, a viscosidade cinemática de 10-5 m2s-1 é requerida baseada na definição do número de Reynolds dada anteriormente.

Finalmente, o usuário deve ajustar startTime, stopTime, deltaT e writeInterval em controlDict. Configure deltaT para 0.005para satisfazer a restrição do número de Courant e endTimepara 10 s.

Execução do código

Execute pisoFoam ao entrar no diretório do caso e digitar pisoFoam no terminal. Nesse caso, onde a viscosidade é baixa, a camada limite próxima à tampa é muito fina e as células próximas à tampa são comparativamente grandes de tal forma que a velocidade no seus centros é muito menor que a velocidade da tampa. De fato, após aproximadamente 100 passos de tempo fica aparente que a velocidade nas células adjacentes à tampa atingem um limite superior de aproximadamente 0.2 ms-1, portanto o número máximo de Courant não excede 0.2 significativamente. É razoável aumentar o tempo de solução ao aumentar o passo de tempo até um nível onde o número de Courant fique muito mais próximo de 1. Dessa forma, reconfigure o valor de deltaT para 0.02 e nessa ocasião, ajuste startFrom para latestTime. Isso instrui pisoFOAM a ler os dados iniciais do último diretório do tempo simulado, i.e. 10.0. O valor endTime deve ser 20 já que a convergência e um pouco mais lenta do que o caso laminar. Reinicie a simulação novamente e monitore a convergência da solução. Veja os resultados em passos de tempo consecutivos na medida em que a solução progride para ver se há convergência para um regime permanente ou se possivelmente um estado oscilatório periódico é alcançado. No último caso, convergência pode nunca ocorrer, mas isso não significa que os dados estão incorretos.

Mudança da geometria

O usuário pode desejar fazer mudanças para a geometria do caso e realizar uma nova simulação. Isso pode ser uma operação um pouco mais complexa porque os campos da solução original não são consistentes com os campos do novo caso. No entanto, a ferramenta mapFields pode mapear os campos que são inconsistentes, em termos da geometria ou tipos de fronteira, ou ambos.

Como um exemplo, copiemos o caso cavityClipped do diretório tutorials no diretório run do usuário, e mudar para o diretório cavityClipped

run  
cp -r $FOAM_TUTORIALS/incompressible/icoFoam/cavity/cavityClipped .  
cd cavityClipped

O caso consiste de uma geometria padrão cavity mas como um quadrado de altura 0.04 m removido do canto inferior direito da cavidade, de acordo com blocMeshDict abaixo:

17  convertToMeters 0.1;  
18  
19  vertices  
20  (  
21  (0 0 0)  
22  (0.6 0 0)  
23  (0 0.4 0)  
24  (0.6 0.4 0)  
25  (1 0.4 0)  
26  (0 1 0)  
27  (0.6 1 0)  
28  (1 1 0)  
29  
30  (0 0 0.1)  
31  (0.6 0 0.1)  
32  (0 0.4 0.1)  
33  (0.6 0.4 0.1)  
34  (1 0.4 0.1)  
35  (0 1 0.1)  
36  (0.6 1 0.1)  
37  (1 1 0.1)  
38  
39  );  
40  
41  blocks  
42  (  
43  hex (0 1 3 2 8 9 11 10) (12 8 1) simpleGrading (1 1 1)  
44  hex (2 3 6 5 10 11 14 13) (12 12 1) simpleGrading (1 1 1)  
45  hex (3 4 7 6 11 12 15 14) (8 12 1) simpleGrading (1 1 1)  
46  );  
47  
48  edges  
49  (  
50  );  
51  
52  boundary  
53  (  
54  lid  
55  {  
56  type wall;  
57  faces  
58  (  
59  (5 13 14 6)  
60  (6 14 15 7)  
61  );  
62  }  
63  fixedWalls  
64  {  
65  type wall;  
66  faces  
67  (  
68  (0 8 10 2)  
69  (2 10 13 5)  
70  (7 15 12 4)  
71  (4 12 11 3)  
72  (3 11 9 1)  
73  (1 9 8 0)  
74  );  
75  }  
76  frontAndBack  
77  {  
78  type empty;  
79  faces  
80  (  
81  (0 2 3 1)  
82  (2 5 6 3)  
83  (3 6 7 4)  
84  (8 9 11 10)  
85  (10 11 14 13)  
86  (11 12 15 14)  
87  );  
88  }  
89  );  
90  
91  mergePatchPairs  
92  (  
93  );  
94  
95  // ************************************************************************* //

Gere a malha com blockMesh. As máscaras são configuradas como nos casos anteriores. Para fins de clareza na descrição do processo de mapeamentos dos campos, a máscara da parede superior é renomeada lid, previamente a máscara movingWall do caso original cavity.

Em um mapeamento inconsistente, não há garantia que todos os dados de campo possam ser mapeados do caso fonte. Os dados restantes devem vir de dados de campo do próprio caso alvo. Portanto, dados de campo devem existir no diretório de tempo do caso alvo antes que aconteça o mapeamento. No caso cavityClipped o mapeamento é configurado para acontecer no tempo 0.5 s, já que startTime é configurado para 0.5 em controlDict. Portanto o usuário precisa copiar dados iniciais de campo para aquele diretório, i.e. do tempo 0.

cp -r 0 0.5

Antes de mapear os dados, o usuário deve visualizar a geometria e os dados em 0.5 s.

Agora desejamos mapear os campos de velocidade e pressão de cavity para os novos campos de cavityClipped. Como o mapeamento é inconsistente, nos necessitamos editar o dicionário mapFieldsDict, localizado no diretório system. O dicionário contém duas palavras-chave de entrada: patchMap e cuttingPatches. A lista patchMap contém um mapeamento de máscaras dos campos fonte para os campos alvo. É usado se o usuário deseja que uma máscara no campo alvo herde os valores correspondentes a uma máscara no campo fonte. No caso cavityClipped, nós desejamos herdar os valores de fronteira na máscara lid da máscara movingWall em cavity, então devemos configurar patchmap como:

patchMap  
(  
lid movingWall  
);

A lista cuttingPatches contem o nome das máscaras alvo cujos valroes devem ser mapeados do campo interno da fonte através do qual a máscara alvo corta. Nesse caso, a máscara fixedWall assume a condição noSlip portanto os valores internos não podem ser interpolados para a máscara. Portanto, a lista cuttingPatches é vazia:

cuttingPatches  
(  
);

Caso o usuário deseje interpola os valores interno do caso fonte para a máscara fixedWalls no caso alvo, uma condição de fronteira fixedValue precisa ser especificada na máscara, cujo valor pode então ser sobrescrito durante o processo de mapeamento; a máscara fixedWalls então deve ser incluída na lista cuttingPatches. O usuário deve executar mapFields de dentro do diretório cavityClipped:

mapFields ../cavity

O usuário pode visualizar o campo mapeado como mostrado na figura 16. A máscara fixedWalls Não herdou valores do caso fonte, como esperado. O usuário pode então executar o caso com icoFoam.

Figura 16 - Solução cavity mapeada em cavityClipped

Pós-processamento da geometria modificada

Glifos do campo de velocidade podem ser gerados para o caso normalmente, primeiramente no tempo 0.5 s e depois no tempo 0.6 s, para efeito de comparação da solução inicial e final. Adicionalmente, fornecemos o contorno da geometria que reqeur algum cuidado para ser gerado no caso 2D. O usuário deve selecionar Extract Block do menu Filter e no painel Parameter, realçar as máscaras de interesse, nesse caso lid e fixedWalls. Ao clicar Apply, esses itens da geometria podem ser visualizados ao selecionar Wireframe no painel Display. A figura 17 exibe as máscaras em preto e vórtices são mostrados sendo formado nos cantos inferiores da geometria modificada.

Figura 17 - Solução do campo de velocidade do caso cavityClipped