Como implementar de forma eficiente as condições de contorno de Dirichlet em matrizes globais de rigidez esparsa de elementos finitos

9

Estou me perguntando como as condições de contorno de Dirichlet em matrizes esparsas de elementos finitos globais são realmente implementadas com eficiência. Por exemplo, digamos que nossa matriz global de elementos finitos fosse:

K=[5201024100016321037000203]and right-hand side vectorb=[b1b2b3b4b5]

Em seguida, para aplicar uma condição Dirichlet no primeiro nó ( ), a primeira linha, colocamos 1 em e a primeira coluna do lado direito. Por exemplo, nosso sistema se tornaria: K 11x1=cK11

K=[1000004100016320037000203]and right-hand side vectorb=[cb22×cb30×cb4+1×cb50×c]

Isso é bom em teoria, mas se nossa matriz K for armazenada em formato de linha compactada (CRS), mover as colunas para o lado direito se tornará caro para sistemas grandes (com muitos nós sendo dirichlet). Uma alternativa seria não mover as colunas correspondentes a uma condição de Dirichlet para o lado direito, ou seja, nosso sistema se tornaria:

K=[1000024100016321037000203]and right-hand side vectorb=[cb2b3b4b5]

No entanto, isso tem uma grande desvantagem, pois o sistema não é mais simétrico e, portanto, não podemos mais usar gradiente conjugado pré-condicionado (ou outros solucionadores simétricos). Uma solução interessante que me deparei é o "Método de grandes números", que encontrei no livro "Programação de elementos finitos em Java", de Gennadiy Nikishkov. Este método usa o fato de que a precisão dupla contém apenas cerca de 16 dígitos de precisão. Em vez de colocar um 1 na posição , colocamos um número grande. Por exemplo, nosso sistema se torna: K = [ 1.0 e 64 2 0 - 1 0 2 4 1 0 0 0 1 6 3 2 - 1 0 3 7 0 0 0 2 0 3 ]K11

K=[1.0e64201024100016321037000203]and right-hand side vectorb=[c×1.0e64b2b3b4b5]

As vantagens deste método são que ele mantém a simetria da matriz e também é muito eficiente para formatos de armazenamento esparsos. Minhas perguntas são as seguintes:

Como as condições de contorno de Dirichlet são normalmente implementadas em códigos de elementos finitos para calor / fluidos? As pessoas costumam usar o método de grandes números ou fazem outra coisa? Existe alguma desvantagem no método de grandes números que alguém pode ver? Suponho que provavelmente exista algum método eficiente padrão usado na maioria dos códigos comerciais e não comerciais que resolva esse problema (obviamente, não espero que as pessoas conheçam todo o funcionamento interno de todos os solucionadores de elementos finitos comerciais, mas esse problema parece básico / fundamental o suficiente para que alguém tenha trabalhado em tais projetos e possa fornecer orientação).

James
fonte
2
Você tem evidências de que isso está diminuindo sua velocidade?
Bill Barth
@ BillBarth Sim, embora sempre exista a chance de fazer algo de forma ineficiente. O próprio Gennadily escreve que, embora o método explícito seja fácil para matrizes 2D completas, ".. nem sempre é fácil acessar linhas e colunas da matriz quando uma matriz está no formato compacto". sugerindo que o método explícito pode ser mais desafiador para implementar com eficiência. Como meu código está atualmente escrito, o método explícito pode levar mais tempo que a solução real.
James
11
faça como Wolfgang diz e aplique condições de contorno às matrizes de elementos antes de montar.
Bill Barth
@ BillBarth Sim, acho que vou fazer isso. Seus vídeos são incríveis! Acabei de deixar um comentário / pergunta para ele sobre se você precisa remontar as matrizes globais em cada intervalo de tempo, após o que acho que aceitarei a resposta dele.
James

Respostas:

11

Em deal.II ( http://www.dealii.org - exoneração de responsabilidade: sou um dos principais autores dessa biblioteca), eliminamos linhas e colunas inteiras e, em geral, não é muito caro. O truque é usar o fato de que o padrão de dispersão é tipicamente simétrico, para que você saiba em quais linhas você deve procurar ao eliminar uma coluna inteira.

A melhor abordagem, na minha opinião, é eliminar essas linhas e colunas nas matrizes de células, antes de serem adicionadas à matriz global. Lá você trabalha com matrizes completas, para que tudo seja eficiente.

Nunca ouvi falar da abordagem de grandes números e não a usaria porque certamente levaria a problemas terrivelmente mal condicionados.

Para referência, os algoritmos que usamos em deal.II são descritos conceitualmente nas aulas 21.6 e 21.65 em http://www.math.colostate.edu/~bangerth/videos.html . Eles correspondem à sua descrição.

Wolfgang Bangerth
fonte
2
No caso de um problema dependente do tempo (digamos a equação do calor), você remonta a matriz global a cada passo do tempo? O motivo pelo qual pergunto é que, no caso de condições Dirichlet diferentes de zero, você precisa de informações da matriz global original ao modificar o lado direito, mas se você zerou essas colunas durante o passo anterior, essas informações serão perdidas (a menos que você as armazene em matrizes adicionais). Isso não seria um problema se a matriz global fosse remontada a cada intervalo de tempo, que é o que estou pensando em fazer e o que teria que ser feito de qualquer maneira se estiver usando malha adaptativa.
James
11
Depende da aplicação. Todos os códigos "grandes" resolvem problemas não lineares dependentes do tempo e, para esses, fica claro que você precisa remontar de uma maneira ou de outra. Para códigos lineares, você pode simplesmente armazenar a matriz original e, a cada passo, copiá-la em outro lugar, aplicar condições de contorno e usá-la no solucionador. Isso requer apenas mais memória, mas é barato.
Wolfgang Bangerth
11
Ah eu vejo que é o que eu suspeitava. Vou implementar como você sugeriu. Ok, é por sua ajuda. Esses vídeos tutoriais são realmente muito bons!
James
2

Zero BCs são fáceis. Para BCs diferentes de zero, você também pode usar multiplicadores Lagrange. Por exemplo, veja aqui . Uma vantagem dos LMs é que você pode usar qualquer equação de restrição, embora o sistema se torne indefinido, portanto você precisa de um solucionador apropriado.

stali
fonte