4

四面体のすべての面のノードIDを、対応する四面体IDにリンクしようとしています。

tetras = [1 2 3 4  % Tetra 1
          5 6 7 8] % Tetra 2

テトラ1の場合、4つの面があります。

faces = [1 2 3; 1 2 4; 1 3 4; 2 3 4] % Notice these are sorted

次に、これらをデータ構造に格納したいと思います。

tet_for_face = cell(8,8,8) % 8 allows for the maximum node id

tet_for_face{1,2,3} = 1;
tet_for_face{1,2,4} = 1;
tet_for_face{1,3,4} = 1;
tet_for_face{2,3,4} = 1;

これは、 O(1)で特定の顔のテトラIDを見つけることができることを意味します:

tet_for_face{2,3,3}
ans = []
tet_for_face{2,3,4}
ans = 1

このアプローチの問題は、連続したメモリが必要になることです。メッシュが大きくなると、メモリが不足します。

cell(1000, 1000, 1000)
??? Error using ==> cell
Out of memory. Type HELP MEMORY for your options.

また、ネストされたセルを使用して遊んだことがあります。

tet = cell(num_nodes, 1);
tet2 = cellfun(@(x) cell(num_nodes, 1), tet, 'UniformOutput', 0);
tet3 = cellfun(@(x) cellfun(@(y) cell(num_nodes, 1), x, 'UniformOutput', 0), tet2, 'UniformOutput', 0);

tet3{2}{3}{4} = 1;
...

これは小さなメッシュで機能し、連続メモリ(AFAIK)を必要としませんが、N=1000でMATLABをクラッシュさせるという厄介な習慣があります。

何か案は?

4

2 に答える 2

2

スパース配列(3Dではなく1Dまたは2Dのみ)で少し遊んだ後、どこにも到達しなかったので、containers.Map(HashMap)を使用することにしました。

私は文字列キーを使用しましたが、それらを作成するための最速の方法は、(int2strやmat2strではなく)sprintfを使用することでした。

サンプルコード:

tet = containers.Map;
for tetra_id in tetras 
    for face in faces
        face_key = sprintf('%d ', face);
        tet(face_key) = tetra_id;

これは私にそのような地図を与えます:

tet('1 2 3') = 1
于 2012-10-04T13:24:41.783 に答える
1

スパース行列を使用して、メッシュで発生する多くの問題に対処できます。これは、実際にこのデータ構造で何をしたいかによって異なりますが、ここに1つの例があります。

% tetras and faces are transposed - column-wise storage
tetras = [1 2 3 4; 5 6 7 8]';
faces = [1 2 3; 1 2 4; 1 3 4; 2 3 4]';

ntetras    = size(tetras, 2);
nfaces     = size(faces, 2);
nfacenodes = size(faces, 1);

% construct face definitions for all tetras
tetras_faces = reshape(tetras(faces, :), nfacenodes, ntetras*nfaces);

% assign the faces to tetras keeping the face id within the tetra, if you need it
enum_faces  = repmat(1:ntetras*nfaces, nfacenodes, 1);

% create a sparse matrix connecting tetra faces to tetras.
% Every column contains 3 non-zeros - 1 for every node in a face
% The number of matrix columns is ntetras*nfaces - 4 columns for every element.
A = sparse(tetras_faces, enum_faces, 1);

ここで、必要な情報を抽出するために、Aに、探している顔に関する情報を保持するベクトルを掛けることができます。

v = sparse(ntetras*nfaces, 1);
v([1 2 3]) = 1;
tetra_id = ceil(find(A*v==nfacenodes)/nfaces)

これは単なる例であることに注意してください。この方法ではるかに有用な情報を抽出でき、行列-ベクトル乗算の代わりに行列-行列乗算を使用して、より高度な検索を実行できます。

于 2012-10-04T10:23:03.733 に答える