Go to the documentation of this file.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 "cellPointWeight.H"
00027 #include <OpenFOAM/polyMesh.H>
00028
00029
00030
00031 int Foam::cellPointWeight::debug(debug::debugSwitch("cellPointWeight", 0));
00032 Foam::scalar Foam::cellPointWeight::tol(SMALL);
00033
00034
00035
00036 void Foam::cellPointWeight::findTetrahedron
00037 (
00038 const polyMesh& mesh,
00039 const vector& position,
00040 const label cellIndex
00041 )
00042 {
00043 if (debug)
00044 {
00045 Pout<< "\nFoam::cellPointWeight::findTetrahedron" << nl
00046 << "position = " << position << nl
00047 << "cellIndex = " << cellIndex << endl;
00048 }
00049
00050
00051 scalar minUVWClose = VGREAT;
00052 label pointIClose = 0;
00053 label faceClose = 0;
00054
00055 const vector& P0 = mesh.cellCentres()[cellIndex];
00056 const labelList& cellFaces = mesh.cells()[cellIndex];
00057 const scalar cellVolume = mesh.cellVolumes()[cellIndex];
00058
00059
00060 forAll(cellFaces, faceI)
00061 {
00062
00063
00064 const labelList& facePoints = mesh.faces()[cellFaces[faceI]];
00065
00066 label pointI = 1;
00067 while ((pointI + 1) < facePoints.size())
00068 {
00069
00070 const vector& P1 = mesh.points()[facePoints[0]];
00071 const vector& P2 = mesh.points()[facePoints[pointI]];
00072 const vector& P3 = mesh.points()[facePoints[pointI + 1]];
00073
00074
00075 const vector e1 = P1 - P0;
00076 const vector e2 = P2 - P0;
00077 const vector e3 = P3 - P0;
00078
00079
00080
00081
00082 const vector rhs = position - P0;
00083
00084
00085
00086 const scalar detA =
00087 e1.x()*e2.y()*e3.z() + e2.x()*e3.y()*e1.z()
00088 + e3.x()*e1.y()*e2.z() - e1.x()*e3.y()*e2.z()
00089 - e2.x()*e1.y()*e3.z() - e3.x()*e2.y()*e1.z();
00090
00091 if (mag(detA/cellVolume) > tol)
00092 {
00093
00094 const scalar u =
00095 (
00096 rhs.x()*e2.y()*e3.z() + e2.x()*e3.y()*rhs.z()
00097 + e3.x()*rhs.y()*e2.z() - rhs.x()*e3.y()*e2.z()
00098 - e2.x()*rhs.y()*e3.z() - e3.x()*e2.y()*rhs.z()
00099 )/detA;
00100
00101 const scalar v =
00102 (
00103 e1.x()*rhs.y()*e3.z() + rhs.x()*e3.y()*e1.z()
00104 + e3.x()*e1.y()*rhs.z() - e1.x()*e3.y()*rhs.z()
00105 - rhs.x()*e1.y()*e3.z() - e3.x()*rhs.y()*e1.z()
00106 )/detA;
00107
00108 const scalar w =
00109 (
00110 e1.x()*e2.y()*rhs.z() + e2.x()*rhs.y()*e1.z()
00111 + rhs.x()*e1.y()*e2.z() - e1.x()*rhs.y()*e2.z()
00112 - e2.x()*e1.y()*rhs.z() - rhs.x()*e2.y()*e1.z()
00113 )/detA;
00114
00115
00116
00117 if
00118 (
00119 (u + tol > 0) && (v + tol > 0) && (w + tol > 0)
00120 && (u + v + w < 1 + tol)
00121 )
00122 {
00123 faceVertices_[0] = facePoints[0];
00124 faceVertices_[1] = facePoints[pointI];
00125 faceVertices_[2] = facePoints[pointI + 1];
00126
00127 weights_[0] = u;
00128 weights_[1] = v;
00129 weights_[2] = w;
00130 weights_[3] = 1.0 - (u + v + w);
00131
00132 return;
00133 }
00134 else
00135 {
00136 scalar minU = mag(u);
00137 scalar minV = mag(v);
00138 scalar minW = mag(w);
00139 if (minU > 1.0)
00140 {
00141 minU -= 1.0;
00142 }
00143 if (minV > 1.0)
00144 {
00145 minV -= 1.0;
00146 }
00147 if (minW > 1.0)
00148 {
00149 minW -= 1.0;
00150 }
00151 const scalar minUVW = mag(minU + minV + minW);
00152
00153 if (minUVW < minUVWClose)
00154 {
00155 minUVWClose = minUVW;
00156 pointIClose = pointI;
00157 faceClose = faceI;
00158 }
00159 }
00160 }
00161
00162 pointI++;
00163 }
00164 }
00165
00166 if (debug)
00167 {
00168 Pout<< "cellPointWeight::findTetrahedron" << nl
00169 << " Tetrahedron search failed; using closest tet values to "
00170 << "point " << nl << " cell: " << cellIndex << nl << endl;
00171 }
00172
00173 const labelList& facePointsClose = mesh.faces()[cellFaces[faceClose]];
00174 faceVertices_[0] = facePointsClose[0];
00175 faceVertices_[1] = facePointsClose[pointIClose];
00176 faceVertices_[2] = facePointsClose[pointIClose + 1];
00177
00178 weights_[0] = 0.25;
00179 weights_[1] = 0.25;
00180 weights_[2] = 0.25;
00181 weights_[3] = 0.25;
00182 }
00183
00184
00185 void Foam::cellPointWeight::findTriangle
00186 (
00187 const polyMesh& mesh,
00188 const vector& position,
00189 const label faceIndex
00190 )
00191 {
00192 if (debug)
00193 {
00194 Pout<< "\nbool Foam::cellPointWeight::findTriangle" << nl
00195 << "position = " << position << nl
00196 << "faceIndex = " << faceIndex << endl;
00197 }
00198
00199
00200 scalar minUVClose = VGREAT;
00201 label pointIClose = 0;
00202
00203
00204
00205 const labelList& facePoints = mesh.faces()[faceIndex];
00206
00207 const scalar faceArea2 = magSqr(mesh.faceAreas()[faceIndex]);
00208
00209 label pointI = 1;
00210 while ((pointI + 1) < facePoints.size())
00211 {
00212
00213 const vector& P1 = mesh.points()[facePoints[0]];
00214 const vector& P2 = mesh.points()[facePoints[pointI]];
00215 const vector& P3 = mesh.points()[facePoints[pointI + 1]];
00216
00217
00218 vector v1 = position - P1;
00219 const vector v2 = P2 - P1;
00220 const vector v3 = P3 - P1;
00221
00222
00223 vector n = v2 ^ v3;
00224 n /= mag(n);
00225
00226
00227 v1 -= (n & v1)*v1;
00228
00229
00230 const scalar d12 = v1 & v2;
00231 const scalar d13 = v1 & v3;
00232 const scalar d22 = v2 & v2;
00233 const scalar d23 = v2 & v3;
00234 const scalar d33 = v3 & v3;
00235
00236
00237
00238 const scalar detA = d22*d33 - d23*d23;
00239
00240 if (0.25*detA/faceArea2 > tol)
00241 {
00242
00243 const scalar u = (d12*d33 - d23*d13)/detA;
00244 const scalar v = (d22*d13 - d12*d23)/detA;
00245
00246
00247 if ((u + tol > 0) && (v + tol > 0) && (u + v < 1 + tol))
00248 {
00249
00250 faceVertices_[0] = facePoints[0];
00251 faceVertices_[1] = facePoints[pointI];
00252 faceVertices_[2] = facePoints[pointI + 1];
00253
00254 weights_[0] = u;
00255 weights_[1] = v;
00256 weights_[2] = 1.0 - (u + v);
00257 weights_[3] = 0.0;
00258
00259 return;
00260 }
00261 else
00262 {
00263 scalar minU = mag(u);
00264 scalar minV = mag(v);
00265 if (minU > 1.0)
00266 {
00267 minU -= 1.0;
00268 }
00269 if (minV > 1.0)
00270 {
00271 minV -= 1.0;
00272 }
00273 const scalar minUV = mag(minU + minV);
00274
00275 if (minUV < minUVClose)
00276 {
00277 minUVClose = minUV;
00278 pointIClose = pointI;
00279 }
00280 }
00281 }
00282
00283 pointI++;
00284 }
00285
00286 if (debug)
00287 {
00288 Pout<< "Foam::cellPointWeight::findTriangle"
00289 << "Triangle search failed; using closest triangle to point" << nl
00290 << " cell face: " << faceIndex << nl << endl;
00291 }
00292
00293
00294 faceVertices_[0] = facePoints[0];
00295 faceVertices_[1] = facePoints[pointIClose];
00296 faceVertices_[2] = facePoints[pointIClose + 1];
00297
00298 weights_[0] = 1.0/3.0;
00299 weights_[1] = 1.0/3.0;
00300 weights_[2] = 1.0/3.0;
00301 weights_[3] = 0.0;
00302 }
00303
00304
00305
00306
00307 Foam::cellPointWeight::cellPointWeight
00308 (
00309 const polyMesh& mesh,
00310 const vector& position,
00311 const label cellIndex,
00312 const label faceIndex
00313 )
00314 :
00315 cellIndex_(cellIndex)
00316 {
00317 if (faceIndex < 0)
00318 {
00319
00320 findTetrahedron(mesh, position, cellIndex);
00321 }
00322 else
00323 {
00324
00325 findTriangle(mesh, position, faceIndex);
00326 }
00327 }
00328
00329
00330