Які хороші типи даних для неструктурованого коду FVM CFD, орієнтованого на клітинку?


12

Мене цікавить порада щодо ефективних структур даних для перегляду стільників у неструктурованому КЗД на кінцевому об'ємі з кінцевим об'ємом.

Один із прикладів, з якими я стикався (у коді dolfyn cfd ), виглядає так (я покажу відповідний сегмент) Internal Отже, у нас є масив NFaces, де зберігається кількість граней для кожної комірки. Потім масив CFace, який відображає номер обличчя від локальної до комірки до глобального номера обличчя.

\begin{listing}do ip=1,Ncel         ...         do j=1,NFaces(ip)           k   = CFace(ip,j)           ipp = Face(k)%cell1           inn = Face(k)%cell2           if( inn > 0 )then             ! internal\end{listing}

Код заснований на обличчі, тому існує тип даних особи, який зберігає порядковий номер двох комірок, він лежить між Face (k)% cell1 та Face (k)% cell2.

Будь-які коментарі щодо цього або пропозиції щодо альтернативного підходу вітаються.

Відповіді:


9

Показана вами структура - це звичайний вибір і рівнозначна збереженню прилягань клітини-обличчя у форматі матриці CSR, причому осередки прикордонних примар мають особливе місце. Однак зауважте, що методи FV також можуть бути сформульовані так, щоб повністю або майже повністю складалися з обходу обличчя, де кожне обличчя відвідується лише один раз (реконструюйте до центральної / квадратурної точки з обох сторін, вирішіть задачу Рімана, розподіліть флюс назад у залишки на клітинах ). Ви можете "підробити" це, використовуючи обхід на основі комірок і пропустивши будь-які дві комірки, які знаходяться нижче "діагоналі" в рідкій матриці, але популярною альтернативою є зберігання(leftCell, rightCell) = support(face), в цьому випадку обличчя стають сутнісними категоріями. Це корисно, оскільки вам зазвичай потрібно місце для зберігання квадратурних точок обличчя (центроїдів), нормальних облич. Ви також можете розмістити частини реконструкції (наприклад, найменші квадрати) в структурах даних на основі обличчя. Обхід обличчя здається векторизаційним, тому що всі розміри є регулярними, але, з іншого боку, є виходи, що перекриваються, тому вам потрібно організувати обхід, щоб не ставити його у внутрішню петлю. Завдяки цій структурі даних, орієнтованої на обличчя, природно впорядкувати номери обличчя, щоб кожен тип граничних умов можна застосувати за допомогою суміжного обходу граней (також сприятливого для векторизації).

Якщо ви вибираєте цю структуру даних, не забудьте сортувати обличчя, щоб обхід даних максимально використовував дані комірок у кеші. Дивіться будь-який документ із PETSc-FUN3D для аналізу ефективності впорядкування обличчя та пов'язаних з ними оптимізацій.


Якщо ви переходите на обличчя, вам потрібно буде отримати інформацію з leftCell і rightCell для обчислення потоків, скажімо, обличчя 1 має leftCell 1 і rightCell 10, face 2 має leftCell 6 і rightCell 31, ... тим самим стрибаючи через пам'ять . Як це може бути векторизацією?
chris

Як було сказано вище (і обговорювалося в документах PETSc-FUN3D), ви наказуєте особам повторно використовувати кеш. Результат - це як «однобічний» обхід клітин, в якому кожне обличчя відвідується лише один раз.
Джед Браун

3

Я знаю, що на це питання вже відповіли, але ось схожий циклічний накопичувач на основі однієї особи, який реалізований у бібліотеці OpenFOAM C ++:

Кожна комірка має індекс (ID) у списку комірок. Для всіх облич визначено два списки: "обличчя внутрішнього власника" та "обличчя сусіда". Довжина обох списків обличчя відповідає кількості внутрішніх граней у сітці. Власником обличчя буде клітинка з нижчим ідентифікатором у клітинному списку (навпаки для сусіда обличчя). Межі обличчя написані останніми, і вони мають орієнтовані назовні нормали (з області рішення), і, звичайно, лише одну власну клітинку. Область обличчя нормальна орієнтована таким чином, що вона виглядає назовні від клітини власника до сусідньої клітини.

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

Оскільки граничні грані агломеровані в патчі, міжпроцесовий зв'язок визначається для зв'язаних (процесорних) патчів і попередньо визначених. Це означає, що як тільки відбувається цикл через прикордонну сітку, функції доступу верхнього рівня викликають загорнуті MPI-дзвінки, роблячи такий код "автоматично" паралельним, якщо він покладається на вищеописане пояснення на основі обличчя.


Немає проблем, я радий бачити, що цей опис комусь корисний .. :) Ви також працюєте з OpenFOAM?
tmaric

Раніше я трохи раніше. Я, як правило, тримаюся осторонь прийнятих тенденцій і намагаюся винаходити колесо. Це мій Дао.
Джоннтра Вольта

1
Ваш Дао - це протилежність дао комп’ютерних наук: "Не вигадуйте колесо заново". Але я можу це зрозуміти, привабливо робити речі з нуля! :)
tmaric
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.