Apa saja tipe data yang baik untuk kode CFV FVM berpusat sel yang tidak terstruktur?

12

Saya tertarik pada saran untuk struktur data yang efisien untuk penelusuran sel dalam CFD volume terbatas berbasis sel yang tidak terstruktur.

Salah satu contoh yang saya temui (dalam kode CFD dolfyn ) berjalan seperti ini (saya akan menunjukkan segmen yang relevan) Jadi kami memiliki array NFaces tempat jumlah wajah untuk setiap sel disimpan. Kemudian array CFace yang memetakan nomor wajah lokal ke sel ke nomor wajah global.

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

Kode berdasarkan wajah oleh karena itu ada tipe data wajah yang menyimpan nomor seri dua sel itu terletak antara Wajah (k)% sel1 dan Wajah (k)% sel2.

Setiap komentar tentang ini atau saran untuk pendekatan alternatif dipersilahkan.

Johntra Volta
sumber

Jawaban:

9

Struktur yang Anda perlihatkan adalah pilihan umum dan setara dengan menyimpan kedekatan wajah-sel dalam format matriks CSR, dengan sel-sel hantu batas di tempat khusus. Namun, perhatikan bahwa metode FV juga dapat diformulasikan untuk terdiri seluruhnya atau hampir seluruhnya dari traversal wajah di mana setiap wajah hanya dikunjungi sekali (merekonstruksi untuk menghadapi titik massa tengah / quadrature dari kedua sisi, menyelesaikan masalah Riemann, mendistribusikan fluks kembali ke residu pada sel ). Anda dapat "memalsukan" itu dengan menggunakan traversal berbasis sel dan melewatkan dua sel yang berada di bawah "diagonal" dalam matriks jarang, tetapi alternatif yang populer adalah menyimpan(leftCell, rightCell) = support(face), dalam hal ini wajah menjadi entitas kelas satu. Itu berguna karena Anda biasanya membutuhkan tempat untuk menyimpan titik quadrature wajah (centroid), wajah normal. Anda juga dapat menempatkan bagian-bagian rekonstruksi (seperti kuadrat terkecil) ke dalam struktur data berbasis wajah. Face traversal tampaknya ramah vektorisasi karena semua ukurannya teratur, tetapi di sisi lain, ada output yang tumpang tindih sehingga Anda perlu mengatur traversal untuk menghindari meletakkannya di loop dalam. Dengan struktur data yang lebih berorientasi wajah ini, adalah wajar untuk memesan nomor wajah sehingga setiap tipe kondisi batas dapat diterapkan menggunakan traversal wajah yang bersebelahan (juga ramah vektorisasi).

Jika Anda memilih struktur data ini, ingatlah untuk mengurutkan wajah sehingga traversal menggunakan kembali data sel dalam cache sebanyak mungkin. Lihat makalah PETSc-FUN3D untuk analisis kinerja pemesanan wajah dan optimisasi terkait.

Jed Brown
sumber
Jika Anda mengulangi permukaan, Anda perlu mendapatkan informasi dari sel kiri dan sel kanan untuk menghitung fluks, katakan wajah 1 telah meninggalkan sel 1 dan sel kanan 10, wajah 2 telah meninggalkan sel 6 dan sel kanan 31, ... sehingga melompati memori . Bagaimana itu ramah vektorisasi?
chris
Seperti disebutkan di atas (dan dibahas dalam makalah PETSc-FUN3D), Anda memesan wajah untuk menggunakan kembali cache. Hasilnya seperti lintasan sel "satu sisi" di mana setiap wajah hanya dikunjungi sekali.
Jed Brown
3

Saya tahu pertanyaan ini sudah dijawab, tetapi inilah penyimpanan perulangan berbasis satu wajah yang serupa yang diterapkan di pustaka OpenFOAM C ++:

Setiap sel memiliki indeks (ID) dalam selList. Dua daftar didefinisikan untuk semua wajah: "face internal owner" dan "face neighbor". Panjang kedua daftar wajah sesuai dengan jumlah wajah internal di jala. Pemilik wajah akan menjadi sel dengan ID yang lebih rendah di cellList (berlawanan dengan tetangga wajah). Batas wajah ditulis terakhir, dan mereka memiliki normals berorientasi keluar (dari domain solusi), dan tentu saja, hanya satu sel pemilik. Normal area wajah diorientasikan sehingga terlihat keluar dari sel pemilik ke sel tetangga.

Ini bekerja dengan baik untuk perhitungan fluks misalnya. Fluks dievaluasi sekali per wajah, dan ditambahkan ke jumlah wajah total untuk sel pemilik, dan dikurangkan dari sel tetangga (penjumlahan / pengurangan ditentukan berdasarkan orientasi normal area wajah). Wajah batas diurutkan dan disimpan di bagian bawah daftar wajah, yang memungkinkan kondisi batas untuk didefinisikan sebagai irisan daftar wajah (label awal, label akhir patch batas), sehingga menyederhanakan penerapan kondisi batas, juga sebagai peningkatan efisiensi proses pembaruan untuk kondisi batas, karena mengandalkan solusi yang disediakan oleh operasi pada permukaan internal.

Karena permukaan batas diaglomerasi menjadi tambalan, komunikasi antar-proses didefinisikan untuk tambalan (prosesor) yang dipasangkan, dan yang telah ditentukan sebelumnya. Ini berarti bahwa segera setelah ada loop di atas batas mesh, fungsi akses tingkat atas envoke panggilan MPI dibungkus, membuat kode tersebut "secara otomatis" diparalelkan, jika itu bergantung pada konektivitas berbasis wajah yang dijelaskan di atas.

tmaric
sumber
Tidak masalah, saya senang melihat bahwa deskripsi ini bermanfaat bagi seseorang .. :) Apakah Anda bekerja dengan OpenFOAM juga?
tmaric
Saya dulu, sedikit di masa lalu. Saya biasanya cenderung menjauhi tren yang diterima dan mencoba menemukan kembali roda. Itu Tao saya.
Johntra Volta
1
Tao Anda adalah kebalikan dari Tao Ilmu Komputer: "Jangan menemukan kembali roda". Tapi saya bisa memahaminya, menarik untuk melakukan hal-hal dari awal! :)
tmaric