ある境界に隣接するセルのみから構成される cellZone は,setSet ユーティリティを使用して,以下のような手順で生成することができます.
1 2 3 |
readline>faceSet ductwall new patchToFace duct readline>cellSet layer1Cells new faceToCell ductwall owner readline>cellZoneSet layer1Zone new setToCellZone layer1Cells |
1行目のコマンドで,境界名が duct の境界フェイスから,ductwall という名前の faceSet を生成しています.2行目のコマンドでは,この faceSet に属するフェイスの owner セルから構成される cellSet を生成し,layer1Cells と名付けています.最後に3行目のコマンドで,この cellSet から,layer1Zone という名前の cellZone を生成しています.
ここで,2行目のコマンドで使用している faceToCell オプションは,指定した faceSet に属する face の neighbour セル,owner セル,またはその両方のセル (any) から構成される cellSet を生成することができます.また,all オプションを指定した場合には,全てのフェイスが指定した faceSet に属するセルから構成される cellSet を生成します.境界フェイスの場合,owner セルしか存在しないので,owner と any のどちらを指定しても同じ cellSet が生成されます.
1 2 3 4 |
Usage: faceToCell <faceSet> neighbour|owner|any|all Select cells that are the owner|neighbour|any of the faces in the faceSet or where all faces are in the faceSet |
実装は,faceToCell.C ファイルで確認できます.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // void Foam::faceToCell::combine(topoSet& set, const bool add) const { // Load the set faceSet loadedSet(mesh_, setName_); // Handle owner/neighbour/any selection forAllConstIter(faceSet, loadedSet, iter) { const label faceI = iter.key(); if ((option_ == OWNER) || (option_ == ANY)) { const label cellI = mesh_.faceOwner()[faceI]; addOrDelete(set, cellI, add); } if (mesh_.isInternalFace(faceI)) { if ((option_ == NEIGHBOUR) || (option_ == ANY)) { const label cellI = mesh_.faceNeighbour()[faceI]; addOrDelete(set, cellI, add); } } } // Handle all selection. if (option_ == ALL) { // Count number of selected faces per cell. Map<label> facesPerCell(loadedSet.size()); forAllConstIter(faceSet, loadedSet, iter) { const label faceI = iter.key(); const label own = mesh_.faceOwner()[faceI]; Map<label>::iterator fndOwn = facesPerCell.find(own); if (fndOwn == facesPerCell.end()) { facesPerCell.insert(own, 1); } else { fndOwn()++; } if (mesh_.isInternalFace(faceI)) { label nei = mesh_.faceNeighbour()[faceI]; Map<label>::iterator fndNei = facesPerCell.find(nei); if (fndNei == facesPerCell.end()) { facesPerCell.insert(nei, 1); } else { fndNei()++; } } } // Include cells that are referenced as many times as they have faces // -> all faces in set. forAllConstIter(Map<label>, facesPerCell, iter) { const label cellI = iter.key(); if (iter() == mesh_.cells()[cellI].size()) { addOrDelete(set, cellI, add); } } } } |
OpenFOAM では,それぞれのセルのフェイスの両側に位置する2つのセルを,owner セルと neighbour セルと呼んでいます(境界フェイスの場合は,neighbour セルのみ存在します).ここで,セル番号が小さい方のセルが owner セルです.ここら辺の話題については,こちらのスライドで触れています.
neighbour のスペルちょっと違和感ありますか?OpenFOAM Code Style Guide の最後の Orthography の項でも言及されているように,OpenFOAM はもともと,英国産のソフトウェアなので,今でも英国式のスペリングが好まれています.他には,centre なども頻出しますね.