Як обчислити числову різницю між двома полями, що зберігаються у двох різних файлах VTK з однаковою структурою?


15

Припустимо, у мене є два файли VTK, обидва в структурованому форматі сітки. Структуровані сітки однакові (у них однаковий список точок, в одному порядку), і в кожному файлі VTK є поле, назвіть його "Phi". Я хочу створити третій файл VTK, знову з тією ж структурованою сіткою, і побудувати поле, яке є різницею між Phi у першому файлі VTK та Phi у другому файлі VTK.

Я знаю, як це зробити вручну; Я можу проаналізувати необроблений текст у двох файлах VTK, скопіювати дані в масиви, відняти один масив від іншого, а потім скинути дані у потрібному форматі в новий файл. Чи є кращий спосіб обчислити цю різницю та експортувати її до VTK? Рішення в Python або в програмному забезпеченні для візуалізації на зразок VisIt або Paraview було б кращим, ніж використання компільованої мови на зразок C ++.

Метою обчислення цієї різниці є порівняння різних чисельних методів обчислення рішення ПДЕ; оскільки я використовую одне і те ж програмне забезпечення для генерації рішень, я можу гарантувати, що всі дані, крім поля Phi, будуть однаковими у кожному створеному вами файлі.


Я розмістив це запитання, оскільки мені знадобилося близько півтора днів, щоб зрозуміти відповідь; якби я не знайшов її вчора, я б все одно поставив це питання тут. Мені цікаво побачити, чи існують інші швидкі способи виконання того ж завдання.
Джефф Оксберрі

Коли ви говорите "розбір сирого тексту", ви маєте на увазі буквально перейти у файл або використовувати синтаксичний аналізатор python?
SAAD

У той час я мав на увазі написати аналізатор Python вручну.
Джефф Оксберрі

Відповіді:


16

Найпростіший спосіб, яким я міг би відняти два поля з різних файлів VTK з однаковою структурованою сіткою, - це застосувати програмований фільтр у Paraview, який дозволяє вам маніпулювати даними за допомогою скриптів Python.

У діалоговому вікні програмованого фільтра можна відняти два масиви і записати на вихід з кодом:

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

У цьому випадку в полі Phi трапляються дані клітини. Якщо ваше поле є точковими даними, замініть CellDataскрізь у скрипті на PointData. Детальнішу інформацію див. У розділі http://public.kitware.com/pipermail/paraview/2010-April/016667.html .


4
Ніколи не надто нагадувати, що для того, щоб мати два входи (входи [0] та входи [1]), необхідно виділити обидва набори даних перед вибором програмованого фільтра (це згаданий один посилається посилання).
toliveira

3

У ParaView є фільтр Додавання атрибутів, який можна використовувати для цього. Потрібно, щоб однакова кількість точок була в наборі даних для належного додавання даних точок і однакова кількість комірок міститься в наборі даних для належного додавання даних комірок. У нього будуть проблеми, хоча із однойменними масивами (наприклад, Phi у вашому прикладі). Ви можете легко скопіювати цей масив за допомогою фільтра калькулятора, хоча перед використанням фільтра "Додавати атрибути". Потім ви можете використовувати інший фільтр калькулятора, щоб зробити віднімання. Це, мабуть, менш ефективно, ніж використання фільтра програмованого Python ParaView. Крім того, ви можете використовувати виконуваний файл vtkpython, щоб зробити це вручну, оскільки у вас був би прямий доступ до сіток та їх атрибутів.


1

У мене немає особливо хорошого підходу, але я скопіював би поле 'phi' з одного файлу VTK в інший і назвав його 'phiprime' чи щось. І в Paraview, і в візиті ви маєте можливість визначити нові поля за формулою, яка використовує значення інших полів. Потім ви можете визначити поле "помилка" як "помилка = фі-піпріме" в редакторі поля та побудувати це поле "помилка" як поверхню, контурний графік або все, що вас цікавить.

Крок копіювання блоку даних з одного файлу в інший явно незручний, але це найкраще, що я можу придумати.


1

Я зрозумів, що це трохи старше, але, хоча, можливо, вас зацікавить рішення VisIt:

Ви можете зробити це у VisIt за допомогою чогось, що називається Поле з полем крос-меж. Це дуже просто, але це в основному механізм для відображення полів між базами даних (у вашому випадку файли VTK).

"На основі з'єднання" (conn_cmfe) використовується, коли топологія між файлами однакова - як у вашому випадку.

Існує також "Позиція на основі" (pos_cmfe), що вибірки між сітками з різними топологіями.

Для вашого випадку відкрийте перший файл і скористайтеся вікном вирази, щоб визначити вираз (MyPhi_Diff):

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

Тоді ви можете побудувати "MyPhi_Diff" за допомогою сюжету Pseudocolor.

Також є майстер, який ви можете використовувати для визначення виразу

(Меню параметрів -> "Порівняння рівня даних")

Ось додаткова інформація:

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.