00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "hexCellLooper.H"
00027 #include <meshTools/cellFeatures.H>
00028 #include <OpenFOAM/polyMesh.H>
00029 #include <OpenFOAM/cellModeller.H>
00030 #include <OpenFOAM/mathematicalConstants.H>
00031 #include <OpenFOAM/plane.H>
00032 #include <OpenFOAM/ListOps.H>
00033 #include <meshTools/meshTools.H>
00034 #include <OpenFOAM/OFstream.H>
00035
00036 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00037
00038
00039
00040 namespace Foam
00041 {
00042
00043
00044
00045 defineTypeNameAndDebug(hexCellLooper, 0);
00046
00047 addToRunTimeSelectionTable(cellLooper, hexCellLooper, word);
00048
00049
00050 }
00051
00052
00053
00054
00055
00056 bool Foam::hexCellLooper::walkHex
00057 (
00058 const label cellI,
00059 const label startFaceI,
00060 const label startEdgeI,
00061
00062 labelList& loop,
00063 scalarField& loopWeights
00064 ) const
00065 {
00066 label faceI = startFaceI;
00067
00068 label edgeI = startEdgeI;
00069
00070 label cutI = 0;
00071
00072 do
00073 {
00074 if (debug & 2)
00075 {
00076 Pout<< " walkHex : inserting cut onto edge:" << edgeI
00077 << " vertices:" << mesh().edges()[edgeI] << endl;
00078 }
00079
00080
00081 loop[cutI] = edgeToEVert(edgeI);
00082 loopWeights[cutI] = 0.5;
00083 cutI++;
00084
00085 faceI = meshTools::otherFace(mesh(), cellI, faceI, edgeI);
00086
00087 const edge& e = mesh().edges()[edgeI];
00088
00089
00090 edgeI = meshTools::walkFace(mesh(), faceI, edgeI, e.end(), 2);
00091
00092 if (edgeI == startEdgeI)
00093 {
00094 break;
00095 }
00096 }
00097 while (true);
00098
00099
00100 if (cutI > 4)
00101 {
00102 Pout<< "hexCellLooper::walkHex" << "Problem : cell:" << cellI
00103 << " collected loop:";
00104 writeCuts(Pout, loop, loopWeights);
00105 Pout<< "loopWeights:" << loopWeights << endl;
00106
00107 return false;
00108 }
00109 else
00110 {
00111 return true;
00112 }
00113 }
00114
00115
00116
00117 void Foam::hexCellLooper::makeFace
00118 (
00119 const labelList& loop,
00120 const scalarField& loopWeights,
00121
00122 labelList& faceVerts,
00123 pointField& facePoints
00124 ) const
00125 {
00126 facePoints.setSize(loop.size());
00127 faceVerts.setSize(loop.size());
00128
00129 forAll(loop, cutI)
00130 {
00131 label cut = loop[cutI];
00132
00133 if (isEdge(cut))
00134 {
00135 label edgeI = getEdge(cut);
00136
00137 const edge& e = mesh().edges()[edgeI];
00138
00139 const point& v0 = mesh().points()[e.start()];
00140 const point& v1 = mesh().points()[e.end()];
00141
00142 facePoints[cutI] =
00143 loopWeights[cutI]*v1 + (1.0-loopWeights[cutI])*v0;
00144 }
00145 else
00146 {
00147 label vertI = getVertex(cut);
00148
00149 facePoints[cutI] = mesh().points()[vertI];
00150 }
00151
00152 faceVerts[cutI] = cutI;
00153 }
00154 }
00155
00156
00157
00158
00159
00160 Foam::hexCellLooper::hexCellLooper(const polyMesh& mesh)
00161 :
00162 geomCellLooper(mesh),
00163 hex_(*(cellModeller::lookup("hex")))
00164 {}
00165
00166
00167
00168
00169 Foam::hexCellLooper::~hexCellLooper()
00170 {}
00171
00172
00173
00174
00175 bool Foam::hexCellLooper::cut
00176 (
00177 const vector& refDir,
00178 const label cellI,
00179 const boolList& vertIsCut,
00180 const boolList& edgeIsCut,
00181 const scalarField& edgeWeight,
00182
00183 labelList& loop,
00184 scalarField& loopWeights
00185 ) const
00186 {
00187 bool success = false;
00188
00189 if (mesh().cellShapes()[cellI].model() == hex_)
00190 {
00191
00192
00193 label edgeI = meshTools::cutDirToEdge(mesh(), cellI, refDir);
00194
00195
00196 label face0;
00197 label face1;
00198 meshTools::getEdgeFaces(mesh(), cellI, edgeI, face0, face1);
00199
00200
00201 loop.setSize(4);
00202 loopWeights.setSize(4);
00203
00204 success = walkHex(cellI, face0, edgeI, loop, loopWeights);
00205 }
00206 else
00207 {
00208 success = geomCellLooper::cut
00209 (
00210 refDir,
00211 cellI,
00212 vertIsCut,
00213 edgeIsCut,
00214 edgeWeight,
00215
00216 loop,
00217 loopWeights
00218 );
00219 }
00220
00221 if (debug)
00222 {
00223 if (loop.empty())
00224 {
00225 WarningIn("hexCellLooper")
00226 << "could not cut cell " << cellI << endl;
00227
00228 fileName cutsFile("hexCellLooper_" + name(cellI) + ".obj");
00229
00230 Pout<< "hexCellLooper : writing cell to " << cutsFile << endl;
00231
00232 OFstream cutsStream(cutsFile);
00233
00234 meshTools::writeOBJ
00235 (
00236 cutsStream,
00237 mesh().cells(),
00238 mesh().faces(),
00239 mesh().points(),
00240 labelList(1, cellI)
00241 );
00242
00243 return false;
00244 }
00245
00246
00247 labelHashSet loopSet(loop.size());
00248
00249 forAll(loop, elemI)
00250 {
00251 label elem = loop[elemI];
00252
00253 if (loopSet.found(elem))
00254 {
00255 FatalErrorIn("hexCellLooper::walkHex") << " duplicate cut"
00256 << abort(FatalError);
00257 }
00258 loopSet.insert(elem);
00259 }
00260
00261
00262 face faceVerts(loop.size());
00263 pointField facePoints(loop.size());
00264
00265 makeFace(loop, loopWeights, faceVerts, facePoints);
00266
00267 if ((faceVerts.mag(facePoints) < SMALL) || (loop.size() < 3))
00268 {
00269 FatalErrorIn("hexCellLooper::walkHex") << "Face:" << faceVerts
00270 << " on points:" << facePoints << endl
00271 << UIndirectList<point>(facePoints, faceVerts)()
00272 << abort(FatalError);
00273 }
00274 }
00275 return success;
00276 }
00277
00278
00279
00280 bool Foam::hexCellLooper::cut
00281 (
00282 const plane& cutPlane,
00283 const label cellI,
00284 const boolList& vertIsCut,
00285 const boolList& edgeIsCut,
00286 const scalarField& edgeWeight,
00287
00288 labelList& loop,
00289 scalarField& loopWeights
00290 ) const
00291 {
00292 return
00293 geomCellLooper::cut
00294 (
00295 cutPlane,
00296 cellI,
00297 vertIsCut,
00298 edgeIsCut,
00299 edgeWeight,
00300
00301 loop,
00302 loopWeights
00303 );
00304 }
00305
00306
00307