Một số kiểu dữ liệu tốt cho mã FVM CFD tập trung vào ô không cấu trúc là gì?


12

Tôi quan tâm đến một lời khuyên cho các cấu trúc dữ liệu hiệu quả để duyệt tìm tế bào trong khối CFD khối lượng hữu hạn dựa trên tế bào không cấu trúc.

Một ví dụ mà tôi gặp phải (trong mã dolfyn cfd) như thế này (tôi sẽ hiển thị phân đoạn có liên quan) list } Vì vậy, chúng ta có một mảng NFaces nơi lưu trữ số lượng khuôn mặt cho mỗi ô. Sau đó, mảng CFace ánh xạ số mặt từ địa phương đến ô thành số mặt toàn cầu.

\ started {list} do ip = 1, Ncel ... do j = 1, NFaces (ip) k = CFace (ip, j) ipp = Face (k)% cell1 inn = Face (k)% cell2 if (inn > 0) rồi! nội bộ \ end {list}

Mã dựa trên khuôn mặt do đó có một kiểu dữ liệu khuôn mặt lưu trữ số sê-ri của hai ô mà nó nằm giữa Face (k)% cell1 và Face (k)% cell2.

Bất kỳ ý kiến ​​về điều này hoặc đề xuất cho phương pháp thay thế đều được chào đón.

Câu trả lời:


9

Cấu trúc bạn hiển thị là một lựa chọn phổ biến và tương đương với việc lưu trữ các phần phụ của mặt ô theo định dạng ma trận CSR, với các ô ma ranh giới ở một vị trí đặc biệt. Tuy nhiên, lưu ý rằng các phương pháp FV cũng có thể được xây dựng để bao gồm toàn bộ hoặc gần như toàn bộ giao diện khuôn mặt trong đó mỗi khuôn mặt chỉ được truy cập một lần (tái tạo để đối mặt với điểm trung tâm / hình cầu từ cả hai bên, giải quyết vấn đề Riemann, phân phối lại dòng chảy vào các tế bào ). Bạn có thể "giả mạo" điều đó bằng cách sử dụng giao dịch dựa trên ô của bạn và bỏ qua bất kỳ hai ô nào nằm dưới "đường chéo" trong ma trận thưa thớt, nhưng một cách thay thế phổ biến là lưu trữ(leftCell, rightCell) = support(face), trong trường hợp khuôn mặt trở thành thực thể hạng nhất. Điều đó rất hữu ích vì bạn thường cần một nơi để lưu trữ các điểm cầu phương (centroid), mặt chuẩn. Bạn cũng có thể đặt các phần tái cấu trúc (như hình vuông nhỏ nhất) vào cấu trúc dữ liệu dựa trên khuôn mặt. Giao diện khuôn mặt có vẻ thân thiện với véc tơ vì tất cả các kích thước đều đặn, nhưng mặt khác, có các đầu ra chồng chéo, do đó bạn cần tổ chức truyền tải để tránh đặt nó vào một vòng lặp bên trong. Với cấu trúc dữ liệu hướng khuôn mặt này, việc sắp xếp các số mặt sao cho mỗi loại điều kiện biên có thể được áp dụng bằng cách sử dụng một giao diện liền kề của khuôn mặt (cũng thân thiện với vector hóa).

Nếu bạn chọn cấu trúc dữ liệu này, hãy nhớ sắp xếp các khuôn mặt để truyền tải lại sử dụng dữ liệu di động trong bộ đệm càng nhiều càng tốt. Xem bất kỳ bài viết nào của PETSc-FUN3D để phân tích hiệu suất của việc đặt hàng khuôn mặt và tối ưu hóa liên quan.


Nếu bạn lặp qua các khuôn mặt, bạn sẽ cần lấy thông tin từ leftCell và rightCell để tính toán các thông lượng, giả sử mặt 1 có leftCell 1 và rightCell 10, mặt 2 có leftCell 6 và rightCell 31, ... từ đó nhảy qua bộ nhớ . Làm thế nào mà thân thiện với vector hóa?
chris

Như đã đề cập ở trên (và được thảo luận trong các bài báo của PETSc-FUN3D), bạn ra lệnh cho các khuôn mặt sử dụng lại bộ đệm. Kết quả giống như một giao dịch tế bào "một phía" trong đó mỗi khuôn mặt chỉ được truy cập một lần.
Jed Brown

3

Tôi biết câu hỏi này đã được trả lời, nhưng đây là bộ lưu trữ vòng lặp dựa trên một mặt tương tự được triển khai trong thư viện OpenFOAM C ++:

Mỗi ô có một chỉ mục (ID) trong một ô. Hai danh sách được xác định cho tất cả các khuôn mặt: "chủ sở hữu nội bộ" và "hàng xóm đối mặt". Độ dài của cả hai danh sách khuôn mặt tương ứng với số lượng khuôn mặt bên trong lưới. Chủ sở hữu khuôn mặt sẽ là ô có ID thấp hơn trong ô Danh sách (đối diện với hàng xóm khuôn mặt). Các mặt ranh giới được viết sau cùng và chúng có các quy tắc hướng ra bên ngoài (từ miền giải pháp), và tất nhiên, chỉ có một ô chủ sở hữu. Vùng mặt bình thường được định hướng sao cho nó nhìn ra ngoài từ ô chủ sang ô bên cạnh.

Điều này hoạt động tốt cho ví dụ tính toán thông lượng. Thông lượng được đánh giá một lần trên mỗi mặt và nó được thêm vào tổng số mặt cho các ô chủ sở hữu và được khấu trừ từ các ô lân cận (tính tổng / khấu trừ được quyết định dựa trên hướng của diện tích mặt bình thường). Các mặt biên được sắp xếp và lưu trữ ở dưới cùng của danh sách mặt, cho phép các điều kiện biên được xác định là các lát của danh sách mặt (nhãn bắt đầu, nhãn cuối của miếng vá ranh giới), do đó cũng đơn giản hóa việc thực hiện các điều kiện biên như hiệu quả của quá trình cập nhật cho các điều kiện biên, vì nó dựa vào giải pháp được cung cấp bởi các hoạt động trên các mặt bên trong.

Do các mặt biên được kết tụ thành các bản vá, nên giao tiếp giữa các quá trình được xác định cho các bản vá (bộ xử lý) được ghép nối và được xác định trước. Điều này có nghĩa là ngay khi có một vòng lặp trên lưới ranh giới, các hàm truy cập cấp cao nhất sẽ thực hiện các cuộc gọi MPI được bao bọc, làm cho mã đó "tự động" song song, nếu nó phụ thuộc vào kết nối dựa trên khuôn mặt được giải thích ở trên.


Không có vấn đề gì, tôi rất vui khi thấy mô tả này hữu ích với ai đó .. :) Bạn có đang làm việc với OpenFOAM không?
tmaric

Tôi đã từng, một chút trong quá khứ. Tôi thường có xu hướng tránh xa các xu hướng được chấp nhận và cố gắng phát minh lại bánh xe. Đó là Đạo của tôi.
Johntra Volta

1
Đạo của bạn trái ngược với Đạo khoa học máy tính: "Đừng tái tạo bánh xe". Nhưng tôi có thể hiểu nó, nó hấp dẫn để làm những thứ từ đầu! :)
tmaric
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.