Como calculo a diferença numérica entre dois campos armazenados em dois arquivos VTK diferentes com a mesma estrutura?

14

Suponha que eu tenha dois arquivos VTK, ambos no formato de grade estruturada. As grades estruturadas são as mesmas (elas têm a mesma lista de pontos, na mesma ordem) e existe um campo, chamado "Phi", em cada arquivo VTK. Quero criar um terceiro arquivo VTK, novamente com a mesma grade estruturada, e plotar um campo que seja a diferença entre Phi no primeiro arquivo VTK e Phi no segundo arquivo VTK.

Eu sei como fazer isso manualmente; Posso analisar o texto bruto nos dois arquivos VTK, copiar os dados em matrizes, subtrair uma matriz da outra e depois despejar os dados no formato correto em um novo arquivo. Existe uma maneira melhor de calcular essa diferença e exportá-la para o VTK? Uma solução em Python ou em software de visualização como VisIt ou Paraview seria preferível a usar uma linguagem compilada como C ++.

O objetivo de calcular essa diferença é comparar diferentes métodos numéricos para calcular a solução de um PDE; Como estou usando o mesmo software para gerar as soluções, posso garantir que todos os dados, exceto o campo Phi, serão iguais em cada arquivo que eu gerar.

Geoff Oxberry
fonte
Postei essa pergunta porque demorei um dia e meio para descobrir a resposta; se eu não o tivesse encontrado ontem, eu teria feito essa pergunta aqui de qualquer maneira. Estou interessado em ver se existem outras maneiras rápidas de realizar a mesma tarefa.
Geoff Oxberry
Quando você diz "analisar o texto bruto", você quer dizer literalmente entrar no arquivo ou usar um analisador python?
SAAD
Na época, eu quis dizer escrever um analisador Python à mão.
Geoff Oxberry

Respostas:

15

A maneira mais fácil de encontrar para subtrair dois campos de arquivos VTK diferentes com a mesma grade estruturada é usar um filtro programável no Paraview, que permite manipular dados usando scripts Python.

Na caixa de diálogo do filtro programável, você pode subtrair as duas matrizes e gravar na saída com o código:

   phi_0 = inputs[0].CellData['Phi']
   phi_1 = inputs[1].CellData['Phi']
   output.CellData.append(phi_1 - phi_0, 'difference')

Nesse caso, o campo Phi passa a ser dados da célula. Se o seu campo for um dado pontual, substitua CellDatatodos os lugares do script por PointData. Consulte http://public.kitware.com/pipermail/paraview/2010-April/016667.html para obter mais detalhes.

Geoff Oxberry
fonte
4
Nunca é demais lembrar que, para ter duas entradas (entradas [0] e entradas [1]), é preciso destacar os dois conjuntos de dados antes de selecionar o filtro programável (isso é mencionado no link mencionado).
toliveira
3

No ParaView, existe o filtro Anexar atributos, que pode ser usado para isso. Requer que o mesmo número de pontos esteja no conjunto de dados para anexar dados de pontos corretamente e o mesmo número de células no conjunto de dados para anexar dados de células corretamente. Porém, haverá problemas com matrizes com o mesmo nome (ou seja, Phi no seu exemplo). Você pode copiar essa matriz facilmente com o filtro Calculadora antes de usar o filtro Anexar atributos. Em seguida, você pode usar outro filtro da calculadora para fazer a subtração. Isso provavelmente é menos eficiente do que usar o filtro programável Python do ParaView. Além disso, você pode usar o executável vtkpython para fazê-lo manualmente, pois você terá acesso direto às grades e seus atributos.

andybauer
fonte
1

Não tenho uma abordagem particularmente boa, mas copio o campo 'phi' de um arquivo VTK para o outro e o nomeio de 'phiprime' ou algo assim. No Paraview e no Visit, você tem a opção de definir novos campos por uma fórmula que usa os valores de outros campos. Você pode definir um campo "error" como "error = phi-phiprime" no editor de campos e plotar esse campo "error" como uma superfície, uma plotagem de contorno ou o que você estiver interessado.

A etapa de copiar o bloco de dados de um arquivo para outro é claramente complicada, mas é o melhor que posso apresentar.

Wolfgang Bangerth
fonte
1

Percebi que isso é um pouco mais antigo, mas acho que você pode estar interessado na solução VisIt:

Você pode fazer isso no VisIt com algo chamado Expressão de campo de malha cruzada baseada em conectividade. Isso é um bocado, mas é basicamente um mecanismo para mapear campos entre bancos de dados (no seu caso, arquivos VTK).

O "Baseado em conectividade" (conn_cmfe) é usado quando a topologia é a mesma entre os arquivos - como no seu caso.

Também existe uma "Posição baseada" (pos_cmfe) que mostra amostras entre malhas com diferentes topologias.

Para o seu caso, abra o primeiro arquivo e use a janela Expressões para definir uma expressão (MyPhi_Diff):

Phi - conn_cmfe(<file2.vtk:Phi>, mesh)

Em seguida, você pode plotar "MyPhi_Diff" com uma plotagem Pseudocolor.

Também há um assistente que você pode usar para ajudar a definir a expressão

(Menu Opções -> "Comparações de nível de dados")

Aqui estão mais algumas informações:

http://visitusers.org/index.php?title=Cmfe

Cyrus
fonte