41 void Foam::primitiveMeshGeometry::updateFaceCentresAndAreas
51 label facei = changedFaces[i];
54 label nPoints = f.size();
60 faceCentres_[facei] = (1.0/3.0)*(p[f[0]] + p[f[1]] + p[f[2]]);
61 faceAreas_[facei] = 0.5*((p[f[1]] - p[f[0]])^(p[f[2]] - p[f[0]]));
69 point fCentre = p[f[0]];
79 const point& nextPoint = p[f[(
pi + 1) % nPoints]];
81 vector c = p[f[
pi]] + nextPoint + fCentre;
82 vector n = (nextPoint - p[f[
pi]])^(fCentre - p[f[
pi]]);
90 faceCentres_[facei] = (1.0/3.0)*sumAc/(sumA + VSMALL);
91 faceAreas_[facei] = 0.5*sumN;
97 void Foam::primitiveMeshGeometry::updateCellCentresAndVols
104 UIndirectList<vector>(cellCentres_, changedCells) =
vector::zero;
105 UIndirectList<scalar>(cellVolumes_, changedCells) = 0.0;
107 const labelList& own = mesh_.faceOwner();
108 const labelList& nei = mesh_.faceNeighbour();
113 UIndirectList<vector>(cEst, changedCells) =
vector::zero;
115 UIndirectList<scalar>(nCellFaces, changedCells) = 0.0;
119 label faceI = changedFaces[i];
120 cEst[own[faceI]] += faceCentres_[faceI];
121 nCellFaces[own[faceI]] += 1;
123 if (mesh_.isInternalFace(faceI))
125 cEst[nei[faceI]] += faceCentres_[faceI];
126 nCellFaces[nei[faceI]] += 1;
132 label cellI = changedCells[i];
133 cEst[cellI] /= nCellFaces[cellI];
138 label faceI = changedFaces[i];
143 faceAreas_[faceI] & (faceCentres_[faceI] - cEst[own[faceI]]),
148 vector pc = (3.0/4.0)*faceCentres_[faceI] + (1.0/4.0)*cEst[own[faceI]];
151 cellCentres_[own[faceI]] += pyr3Vol*pc;
154 cellVolumes_[own[faceI]] += pyr3Vol;
156 if (mesh_.isInternalFace(faceI))
161 faceAreas_[faceI] & (cEst[nei[faceI]] - faceCentres_[faceI]),
167 (3.0/4.0)*faceCentres_[faceI]
168 + (1.0/4.0)*cEst[nei[faceI]];
171 cellCentres_[nei[faceI]] += pyr3Vol*pc;
174 cellVolumes_[nei[faceI]] += pyr3Vol;
180 label cellI = changedCells[i];
182 cellCentres_[cellI] /= cellVolumes_[cellI];
183 cellVolumes_[cellI] *= (1.0/3.0);
193 const labelList& own = mesh_.faceOwner();
194 const labelList& nei = mesh_.faceNeighbour();
200 label faceI = changedFaces[i];
202 affectedCells.insert(own[faceI]);
204 if (mesh_.isInternalFace(faceI))
206 affectedCells.insert(nei[faceI]);
209 return affectedCells.toc();
236 faceAreas_ = mesh_.faceAreas();
237 faceCentres_ = mesh_.faceCentres();
238 cellCentres_ = mesh_.cellCentres();
239 cellVolumes_ = mesh_.cellVolumes();
251 updateFaceCentresAndAreas(p, changedFaces);
253 updateCellCentresAndVols(affectedCells(changedFaces), changedFaces);
260 const scalar orthWarn,
274 const scalar severeNonorthogonalityThreshold =
::cos(
degToRad(orthWarn));
276 scalar minDDotS = GREAT;
280 label severeNonOrth = 0;
282 label errorNonOrth = 0;
286 label faceI = checkFaces[i];
290 vector d = cellCentres[nei[faceI]] - cellCentres[own[faceI]];
291 const vector&
s = faceAreas[faceI];
293 scalar dDotS = (d &
s)/(
mag(d)*
mag(s) + VSMALL);
295 if (dDotS < severeNonorthogonalityThreshold)
302 Pout<<
"Severe non-orthogonality for face " << faceI
303 <<
" between cells " << own[faceI]
304 <<
" and " << nei[faceI]
323 "primitiveMeshGeometry::checkFaceDotProduct" 324 "(const bool, const scalar, const labelList&" 326 ) <<
"Severe non-orthogonality detected for face " 328 <<
" between cells " << own[faceI] <<
" and " 343 if (dDotS < minDDotS)
363 if (report && minDDotS < severeNonorthogonalityThreshold)
365 Info<<
"Number of non-orthogonality errors: " << errorNonOrth
366 <<
". Number of severely non-orthogonal faces: " 367 << severeNonOrth <<
"." <<
endl;
375 Info<<
"Mesh non-orthogonality Max: " 382 if (errorNonOrth > 0)
388 "primitiveMeshGeometry::checkFaceDotProduct" 389 "(const bool, const scalar, const labelList&, labelHashSet*)" 390 ) <<
"Error in non-orthogonality detected" <<
endl;
399 Info<<
"Non-orthogonality check OK.\n" <<
endl;
410 const scalar minPyrVol,
424 label nErrorPyrs = 0;
428 label faceI = checkFaces[i];
434 cellCentres[own[faceI]]
437 if (pyrVol > -minPyrVol)
441 Pout<<
"bool primitiveMeshGeometry::checkFacePyramids(" 442 <<
"const bool, const scalar, const pointField&" 443 <<
", const labelList&, labelHashSet*): " 444 <<
"face " << faceI <<
" points the wrong way. " <<
endl 445 <<
"Pyramid volume: " << -pyrVol
446 <<
" Face " << f[faceI] <<
" area: " << f[faceI].mag(p)
447 <<
" Owner cell: " << own[faceI] <<
endl 448 <<
"Owner cell vertex labels: " 449 << mesh.
cells()[own[faceI]].labels(f)
468 if (pyrVol < minPyrVol)
472 Pout<<
"bool primitiveMeshGeometry::checkFacePyramids(" 473 <<
"const bool, const scalar, const pointField&" 474 <<
", const labelList&, labelHashSet*): " 475 <<
"face " << faceI <<
" points the wrong way. " <<
endl 476 <<
"Pyramid volume: " << -pyrVol
477 <<
" Face " << f[faceI] <<
" area: " << f[faceI].mag(p)
478 <<
" Neighbour cell: " << nei[faceI] <<
endl 479 <<
"Neighbour cell vertex labels: " 480 << mesh.
cells()[nei[faceI]].labels(f)
502 "primitiveMeshGeometry::checkFacePyramids(" 503 "const bool, const scalar, const pointField&" 504 ", const labelList&, labelHashSet*)" 505 ) <<
"Error in face pyramids: faces pointing the wrong way!" 515 Info<<
"Face pyramids OK.\n" <<
endl;
526 const scalar internalSkew,
527 const scalar boundarySkew,
548 label faceI = checkFaces[i];
552 scalar dOwn =
mag(faceCentres[faceI] - cellCentres[own[faceI]]);
553 scalar dNei =
mag(faceCentres[faceI] - cellCentres[nei[faceI]]);
555 point faceIntersection =
556 cellCentres[own[faceI]]*dNei/(dOwn+dNei)
557 + cellCentres[nei[faceI]]*dOwn/(dOwn+dNei);
560 mag(faceCentres[faceI] - faceIntersection)
562 mag(cellCentres[nei[faceI]]-cellCentres[own[faceI]])
569 if (skewness > internalSkew)
573 Pout<<
"Severe skewness for face " << faceI
574 <<
" skewness = " << skewness <<
endl;
585 if (skewness > maxSkew)
595 vector faceNormal = faceAreas[faceI];
596 faceNormal /=
mag(faceNormal) + VSMALL;
598 vector dOwn = faceCentres[faceI] - cellCentres[own[faceI]];
600 vector dWall = faceNormal*(faceNormal & dOwn);
602 point faceIntersection = cellCentres[own[faceI]] + dWall;
605 mag(faceCentres[faceI] - faceIntersection)
606 /(2*
mag(dWall) + VSMALL);
611 if (skewness > boundarySkew)
615 Pout<<
"Severe skewness for boundary face " << faceI
616 <<
" skewness = " << skewness <<
endl;
627 if (skewness > maxSkew)
643 "primitiveMeshGeometry::checkFaceSkewness" 644 "(const bool, const scalar, const labelList&, labelHashSet*)" 645 ) <<
"Large face skewness detected. Max skewness = " 647 <<
" percent.\nThis may impair the quality of the result." <<
nl 648 << nWarnSkew <<
" highly skew faces detected." 658 Info<<
"Max skewness = " << 100*maxSkew
659 <<
" percent. Face skewness OK.\n" <<
endl;
670 const scalar warnWeight,
684 scalar minWeight = GREAT;
686 label nWarnWeight = 0;
690 label faceI = checkFaces[i];
694 const point& fc = faceCentres[faceI];
696 scalar dOwn =
mag(faceAreas[faceI] & (fc-cellCentres[own[faceI]]));
697 scalar dNei =
mag(faceAreas[faceI] & (cellCentres[nei[faceI]]-fc));
699 scalar weight =
min(dNei,dOwn)/(dNei+dOwn);
701 if (weight < warnWeight)
705 Pout<<
"Small weighting factor for face " << faceI
706 <<
" weight = " << weight <<
endl;
717 minWeight =
min(minWeight, weight);
724 if (minWeight < warnWeight)
730 "primitiveMeshGeometry::checkFaceWeights" 731 "(const bool, const scalar, const labelList&, labelHashSet*)" 732 ) <<
"Small interpolation weight detected. Min weight = " 733 << minWeight <<
'.' <<
nl 734 << nWarnWeight <<
" faces with small weights detected." 744 Info<<
"Min weight = " << minWeight
745 <<
" percent. Weights OK.\n" <<
endl;
768 if (maxDeg < -SMALL || maxDeg > 180+SMALL)
772 "primitiveMeshGeometry::checkFaceAngles" 773 "(const bool, const scalar, const pointField&, const labelList&" 775 ) <<
"maxDeg should be [0..180] but is now " << maxDeg
783 scalar maxEdgeSin = 0.0;
787 label errorFaceI = -1;
791 label faceI = checkFaces[i];
793 const face& f = fcs[faceI];
795 vector faceNormal = faceAreas[faceI];
796 faceNormal /=
mag(faceNormal) + VSMALL;
800 scalar magEPrev =
mag(ePrev);
801 ePrev /= magEPrev + VSMALL;
809 vector e10(p[f[fp1]] - p[f[fp0]]);
810 scalar magE10 =
mag(e10);
811 e10 /= magE10 + VSMALL;
813 if (magEPrev > SMALL && magE10 > SMALL)
815 vector edgeNormal = ePrev ^ e10;
816 scalar magEdgeNormal =
mag(edgeNormal);
818 if (magEdgeNormal < maxSin)
825 edgeNormal /= magEdgeNormal;
827 if ((edgeNormal & faceNormal) < SMALL)
829 if (faceI != errorFaceI)
841 maxEdgeSin =
max(maxEdgeSin, magEdgeNormal);
856 if (maxEdgeSin > SMALL)
858 scalar maxConcaveDegr =
861 Info<<
"There are " << nConcave
862 <<
" faces with concave angles between consecutive" 863 <<
" edges. Max concave angle = " << maxConcaveDegr
864 <<
" degrees.\n" <<
endl;
868 Info<<
"All angles in faces are convex or less than " << maxDeg
869 <<
" degrees concave.\n" <<
endl;
879 "primitiveMeshGeometry::checkFaceAngles" 880 "(const bool, const scalar, const pointField&" 881 ", const labelList&, labelHashSet*)" 882 ) << nConcave <<
" face points with severe concave angle (> " 883 << maxDeg <<
" deg) found.\n" 1039 const scalar minTwist,
1048 if (minTwist < -1-SMALL || minTwist > 1+SMALL)
1052 "primitiveMeshGeometry::checkFaceTwist" 1053 "(const bool, const scalar, const primitiveMesh&, const pointField&" 1054 ", const labelList&, labelHashSet*)" 1055 ) <<
"minTwist should be [-1..1] but is now " << minTwist
1069 label faceI = checkFaces[i];
1071 const face& f = fcs[faceI];
1073 scalar magArea =
mag(faceAreas[faceI]);
1075 if (f.
size() > 3 && magArea > VSMALL)
1077 const vector nf = faceAreas[faceI] / magArea;
1079 const point& fc = faceCentres[faceI];
1093 scalar magTri =
mag(triArea);
1095 if (magTri > VSMALL && ((nf & triArea/magTri) < minTwist))
1115 Info<<
"There are " << nWarped
1116 <<
" faces with cosine of the angle" 1117 <<
" between triangle normal and face normal less than " 1118 << minTwist <<
nl <<
endl;
1122 Info<<
"All faces are flat in that the cosine of the angle" 1123 <<
" between triangle normal and face normal less than " 1124 << minTwist <<
nl <<
endl;
1134 "primitiveMeshGeometry::checkFaceTwist" 1135 "(const bool, const scalar, const primitiveMesh&" 1136 ", const pointField&, const labelList&, labelHashSet*)" 1137 ) << nWarped <<
" faces with severe warpage " 1138 <<
"(cosine of the angle between triangle normal and " 1139 <<
"face normal < " << minTwist <<
") found.\n" 1155 const scalar minArea,
1162 label nZeroArea = 0;
1166 label faceI = checkFaces[i];
1168 if (
mag(faceAreas[faceI]) < minArea)
1185 Info<<
"There are " << nZeroArea
1186 <<
" faces with area < " << minArea <<
'.' <<
nl <<
endl;
1190 Info<<
"All faces have area > " << minArea <<
'.' <<
nl <<
endl;
1200 "primitiveMeshGeometry::checkFaceArea" 1201 "(const bool, const scalar, const primitiveMesh&" 1202 ", const pointField&, const labelList&, labelHashSet*)" 1203 ) << nZeroArea <<
" faces with area < " << minArea
1220 const scalar warnDet,
1230 scalar minDet = GREAT;
1231 scalar sumDet = 0.0;
1237 const cell& cFaces = cells[affectedCells[i]];
1240 scalar magAreaSum = 0;
1244 label faceI = cFaces[cFaceI];
1246 scalar magArea =
mag(faceAreas[faceI]);
1248 magAreaSum += magArea;
1249 areaSum += faceAreas[faceI]*(faceAreas[faceI]/magArea);
1252 scalar scaledDet =
det(areaSum/magAreaSum)/0.037037037037037;
1254 minDet =
min(minDet, scaledDet);
1255 sumDet += scaledDet;
1258 if (scaledDet < warnDet)
1265 label faceI = cFaces[cFaceI];
1282 Info<<
"Cell determinant (1 = uniform cube) : average = " 1283 << sumDet / nSumDet <<
" min = " << minDet <<
endl;
1288 Info<<
"There are " << nWarnDet
1289 <<
" cells with determinant < " << warnDet <<
'.' <<
nl 1294 Info<<
"All faces have determinant > " << warnDet <<
'.' <<
nl 1305 "primitiveMeshGeometry::checkCellDeterminant" 1306 "(const bool, const scalar, const primitiveMesh&" 1307 ", const pointField&, const labelList&, const labelList&" 1309 ) << nWarnDet <<
" cells with determinant < " << warnDet
1326 const scalar orthWarn,
1331 return checkFaceDotProduct
1347 const scalar minPyrVol,
1353 return checkFacePyramids
1369 const scalar internalSkew,
1370 const scalar boundarySkew,
1375 return checkFaceSkewness
1393 const scalar warnWeight,
1398 return checkFaceWeights
1415 const scalar maxDeg,
1421 return checkFaceAngles
1460 const scalar minTwist,
1466 return checkFaceTwist
1483 const scalar minArea,
1488 return checkFaceArea
1503 const scalar warnDet,
1509 return checkCellDeterminant
#define SeriousErrorIn(functionName)
Report an error message using Foam::SeriousError.
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
vector point
Point is a vector.
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject( name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE ))
dimensioned< scalar > mag(const dimensioned< Type > &)
A cell is defined as a list of faces with extra functionality.
T & last()
Return the last element of the list.
primitiveMeshGeometry(const primitiveMesh &)
Construct from mesh.
static bool checkFaceArea(const bool report, const scalar minArea, const primitiveMesh &, const vectorField &faceAreas, const labelList &checkFaces, labelHashSet *setPtr)
Info<< "Predicted p max-min : "<< max(p).value()<< " "<< min(p).value()<< endl;rho==max(psi *p+alphal *rhol0+((alphav *psiv+alphal *psil)-psi)*pSat, rhoMin);#1"/home/dm2/henry/OpenFOAM/OpenFOAM-3.0.x/applications/solvers/multiphase/cavitatingFoam/alphavPsi.H"1{alphav=max(min((rho-rholSat)/(rhovSat-rholSat), scalar(1)), scalar(0));alphal=1.0-alphav;Info<< "max-min alphav: "<< max(alphav).value()<< " "<< min(alphav).value()<< endl;psiModel-> correct()
static bool checkFaceDotProduct(const bool report, const scalar orthWarn, const primitiveMesh &, const vectorField &cellCentres, const vectorField &faceAreas, const labelList &checkFaces, labelHashSet *setPtr)
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
void size(const label)
Override size to be inconsistent with allocated storage.
label fcIndex(const label i) const
Return the forward circular index, i.e. the next index.
const cellList & cells() const
void correct()
Take over properties from mesh.
virtual const faceList & faces() const =0
Return faces.
label nextLabel(const label i) const
Next vertex on face.
T & first()
Return the first element of the list.
vectorField pointField
pointField is a vectorField.
A triangle primitive used to calculate face normals and swept volumes.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
static bool checkFaceWeights(const bool report, const scalar warnWeight, const primitiveMesh &mesh, const vectorField &cellCentres, const vectorField &faceCentres, const vectorField &faceAreas, const labelList &checkFaces, labelHashSet *setPtr)
A face is a list of labels corresponding to mesh vertices.
static bool checkFacePyramids(const bool report, const scalar minPyrVol, const primitiveMesh &, const vectorField &cellCentres, const pointField &p, const labelList &checkFaces, labelHashSet *)
Cell-face mesh analysis engine.
Ostream & endl(Ostream &os)
Add newline and flush stream.
#define WarningIn(functionName)
Report a warning using Foam::Warning.
dimensionedScalar det(const dimensionedSphericalTensor &dt)
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
Field< vector > vectorField
Specialisation of Field<T> for vector.
static bool checkCellDeterminant(const bool report, const scalar minDet, const primitiveMesh &, const vectorField &faceAreas, const labelList &checkFaces, const labelList &affectedCells, labelHashSet *setPtr)
dimensionedScalar cos(const dimensionedScalar &ds)
static bool checkFaceTwist(const bool report, const scalar minTwist, const primitiveMesh &, const vectorField &faceAreas, const vectorField &faceCentres, const pointField &p, const labelList &checkFaces, labelHashSet *setPtr)
scalar radToDeg(const scalar rad)
Conversion from radians to degrees.
Unit conversion functions.
dimensionedScalar acos(const dimensionedScalar &ds)
errorManip< error > abort(error &err)
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
const cellShapeList & cells
pyramid< point, const point &, const face & > pyramidPointFaceRef
labelList affectedCells(const labelList &changedFaces) const
Helper function: get affected cells from faces.
List< label > labelList
A List of labels.
scalar degToRad(const scalar deg)
Conversion from degrees to radians.
A normal distribution model.
const dimensionedScalar c
Speed of light in a vacuum.
Vector< scalar > vector
A scalar version of the templated Vector.
static bool checkFaceAngles(const bool report, const scalar maxDeg, const primitiveMesh &mesh, const vectorField &faceAreas, const pointField &p, const labelList &checkFaces, labelHashSet *setPtr)
static bool checkFaceSkewness(const bool report, const scalar internalSkew, const scalar boundarySkew, const primitiveMesh &mesh, const vectorField &cellCentres, const vectorField &faceCentres, const vectorField &faceAreas, const labelList &checkFaces, labelHashSet *setPtr)
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
virtual const labelList & faceOwner() const =0
Face face-owner addresing.
dimensionedScalar asin(const dimensionedScalar &ds)
virtual const labelList & faceNeighbour() const =0
Face face-neighbour addressing.
defineTypeNameAndDebug(combustionModel, 0)
prefixOSstream Pout(cout,"Pout")
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
dimensionedScalar sin(const dimensionedScalar &ds)
bool insert(const Key &key)
Insert a new entry.