1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 Efficient cell-centre calculation using face-addressing, face-centres and
29 \*---------------------------------------------------------------------------*/
31 #include "primitiveMesh.H"
33 #include "tetPointRef.H"
35 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
37 void Foam::primitiveMesh::calcCellCentresAndVols() const
41 Pout<< "primitiveMesh::calcCellCentresAndVols() : "
42 << "Calculating cell centres and cell volumes"
46 // It is an error to attempt to recalculate cellCentres
47 // if the pointer is already set
48 if (cellCentresPtr_ || cellVolumesPtr_)
50 FatalErrorIn("primitiveMesh::calcCellCentresAndVols() const")
51 << "Cell centres or cell volumes already calculated"
55 // set the accumulated cell centre to zero vector
56 cellCentresPtr_ = new vectorField(nCells());
57 vectorField& cellCtrs = *cellCentresPtr_;
59 // Initialise cell volumes to 0
60 cellVolumesPtr_ = new scalarField(nCells());
61 scalarField& cellVols = *cellVolumesPtr_;
63 // Make centres and volumes
64 makeCellCentresAndVols(faceCentres(), faceAreas(), cellCtrs, cellVols);
68 Pout<< "primitiveMesh::calcCellCentresAndVols() : "
69 << "Finished calculating cell centres and cell volumes"
75 void Foam::primitiveMesh::makeCellCentresAndVols
77 const vectorField& fCtrs,
78 const vectorField& fAreas,
79 vectorField& cellCtrs,
83 // Clear the fields for accumulation
84 cellCtrs = vector::zero;
87 const labelList& own = faceOwner();
88 const labelList& nei = faceNeighbour();
90 // first estimate the approximate cell centre as the average of
93 vectorField cEst(nCells(), vector::zero);
94 labelField nCellFaces(nCells(), 0);
98 cEst[own[facei]] += fCtrs[facei];
99 nCellFaces[own[facei]] += 1;
104 cEst[nei[facei]] += fCtrs[facei];
105 nCellFaces[nei[facei]] += 1;
110 cEst[celli] /= nCellFaces[celli];
113 const faceList& allFaces = faces();
114 const pointField& allPoints = points();
118 const face& f = allFaces[faceI];
130 scalar tetVol = tpr.mag();
132 // Accumulate volume-weighted tet centre
133 cellCtrs[own[faceI]] += tetVol*tpr.centre();
135 // Accumulate tet volume
136 cellVols[own[faceI]] += tetVol;
145 allPoints[f.prevLabel(pI)],
150 scalar tetVol = tpr.mag();
152 // Accumulate volume-weighted tet centre
153 cellCtrs[own[faceI]] += tetVol*tpr.centre();
155 // Accumulate tet volume
156 cellVols[own[faceI]] += tetVol;
163 const face& f = allFaces[faceI];
175 scalar tetVol = tpr.mag();
177 // Accumulate volume-weighted tet centre
178 cellCtrs[nei[faceI]] += tetVol*tpr.centre();
180 // Accumulate tet volume
181 cellVols[nei[faceI]] += tetVol;
190 allPoints[f.nextLabel(pI)],
195 scalar tetVol = tpr.mag();
197 // Accumulate volume-weighted tet centre
198 cellCtrs[nei[faceI]] += tetVol*tpr.centre();
200 // Accumulate tet volume
201 cellVols[nei[faceI]] += tetVol;
206 cellCtrs /= cellVols + VSMALL;
210 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
212 const Foam::vectorField& Foam::primitiveMesh::cellCentres() const
214 if (!cellCentresPtr_)
216 calcCellCentresAndVols();
219 return *cellCentresPtr_;
223 const Foam::scalarField& Foam::primitiveMesh::cellVolumes() const
225 if (!cellVolumesPtr_)
227 calcCellCentresAndVols();
230 return *cellVolumesPtr_;
234 // ************************************************************************* //