Quais são as estratégias para o Refinamento de Malha Adaptável local (AMR local) em malhas não estruturadas?

8

Estou interessado em AMR local em malhas não estruturadas. Atualmente, estou trabalhando com a biblioteca OpenFOAM - ela suporta AMR local completamente não estruturada:

  • critérios de refinamento de células determinam uma lista de células que são cortadas
  • as células selecionadas são refinadas: a malha inteira é reconstruída
  • um mapa é criado da malha antiga para uma nova
  • a conectividade é recalculada (células da face, faces da borda etc.)
  • campos são mapeados para a nova malha

Como as estruturas de dados envolvidas são basicamente vetores C ++, a malha é inflada e copiada.

Preciso aprender sobre abordagens alternativas que podem ser construídas sobre uma malha que usa estruturas de dados estáticas. Um deles é o AMR paralelo de Octree Forrest, presente em p4est e Dendro .

Alguém pode me indicar um artigo de revisão recente sobre estratégias locais de AMR adaptativas para malha não estruturada?

O aconselhamento com base na experiência seria ainda melhor: qual mecanismo de AMR local é a escolha ideal para malha não estruturada baseada em estrutura de dados fixa?

Preciso de uma visão geral antes de ler sobre o equilíbrio da comunicação entre árvores na primeira página de um artigo. :)

tmaric
fonte
O que exatamente você quer dizer com "estruturas de dados estáticas"? Durante o refinamento da malha, é claro que o número de células aumenta e, portanto, é necessário que alguma estrutura de dados cresça (seu "inflado, copiado"). Só não tenho certeza qual é exatamente a sua pergunta, receio.
precisa saber é o seguinte
Bem, se a malha se basear nas estruturas de dados std :: vector, adicionar uma única célula causará a criação de um novo std :: vector (com tamanho aumentado para a nova célula, seus pontos e faces) e copiará o dados antigos não refinados para as novas estruturas. Com o Octree Forrest, se eu entendi corretamente, não expandirei as estruturas de dados que definem minha malha, o Octree Forrest manterá todas as informações necessárias para o refinamento, e o octree é uma estrutura de dados dinâmica no sentido de alterar uma única célula não copia a árvore inteira e a expande para um único elemento.
Tmaric
Outra observação: como estou em fluxos de duas fases, mesmo para fluxos altamente dispersos (muitas bolhas), terei talvez até 25% da contagem total de células que precisa ser refinada, o que significa que, para uma estrutura completamente não estruturada AMR local, toda vez que refino, copio a malha inteira apenas para aqueles 25% das células que estão ativas no refinamento.
tmaric
2
Se você usar uma estrutura de dados estática, realmente não há uma maneira eficiente de adicionar novos dados sem copiar laboriosamente os dados antigos em um novo vetor. Uma operação de inserção / exclusão custaria umΘ(n)nΘ(1)
2
Não sei o que as outras bibliotecas usam, mas temos um acordo. Temos uma combinação de estruturas de dados estáticas e dinâmicas: temos um vetor std :: para cada nível da malha hierárquica. Se as células forem mais grossas, marcamos os elementos do vetor como não utilizados. Se as células são refinadas, os filhos são colocados no vetor std :: do próximo nível, primeiro em elementos não utilizados e depois anexados ao final. Quando a realocação é necessária porque os elementos são adicionados, primeiro contamos quantos novos elementos precisaremos durante o refinamento e fazemos uma única alocação. Nesse esquema, o custo de alocação / cópia é insignificante.
Wolfgang Bangerth

Respostas:

4

Pelos comentários acima, entendo que você deseja evitar copiar o vetor ao adicionar mais células. A abordagem mais fácil é reservar espaço para o número máximo de células que você deseja:

std::vector<YourCellType> myVectorOfCells;
vectorOfCells.reserve(maxNoCells);

Seu vetor alocou espaço para a criação de células maxNoCells, mas nenhuma célula foi criada ainda. Agora você pode adicionar maxNoCells ao seu vetor, a cada operação no O(1)tempo, sem que o vetor se copie. No entanto, o padrão C ++ exige que a operação push_back seja amortizada O(1) . Se você adicionar mais do que maxNoCells, o vetor se copiará, reservando espaço para k-vezes quantas células anteriormente (implementações típicas escolhem ak entre 1,4 e 2), para que você possa continuar adicionando células ao vetor a O(1)tempo. Esta operação de redimensionamento não é O(1).

O(1)n/2n/2O(1)time ... desde que você reserve memória primeiro, você pode adicionar elementos no tempo O (1) também! Como o professor Bangerth mencionou acima, estruturas hierárquicas de dados, como árvores, também usam vetores internamente para armazenar seus dados.

No entanto, acho melhor prática alocar memória no início da simulação. Você precisa saber quantas células você pode precisar para verificar se você possui memória suficiente disponível. Você não deseja que sua simulação em 200.000 processadores tenha que realocar sua estrutura de dados ou ficar sem memória e ter que trocar para o disco. Caso isso aconteça, minha opinião é que seu programa falhe alto devido a um erro de entrada do usuário.

gnzlbg
fonte
Obrigado! :) Vou verificar a funcionalidade da operação de reserva para a estrutura dinâmica de dados vetoriais no OpenFOAM ... Acho que a operação agora é executada com base nos dados de malha lidos no disco, preenchendo a estrutura de dados até o final .
tmaric