1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
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
13 the Free Software Foundation, either version 3 of the License, or
14 (at your 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, see <http://www.gnu.org/licenses/>.
25 Efficient cell-centre calculation using face-addressing, face-centres and
28 \*---------------------------------------------------------------------------*/
30 #include "primitiveMesh.H"
32 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
34 void Foam::primitiveMesh::calcCellCentresAndVols() const
38 Pout<< "primitiveMesh::calcCellCentresAndVols() : "
39 << "Calculating cell centres and cell volumes"
43 // It is an error to attempt to recalculate cellCentres
44 // if the pointer is already set
45 if (cellCentresPtr_ || cellVolumesPtr_)
47 FatalErrorIn("primitiveMesh::calcCellCentresAndVols() const")
48 << "Cell centres or cell volumes already calculated"
52 // set the accumulated cell centre to zero vector
53 cellCentresPtr_ = new vectorField(nCells());
54 vectorField& cellCtrs = *cellCentresPtr_;
56 // Initialise cell volumes to 0
57 cellVolumesPtr_ = new scalarField(nCells());
58 scalarField& cellVols = *cellVolumesPtr_;
60 // Make centres and volumes
61 makeCellCentresAndVols(faceCentres(), faceAreas(), cellCtrs, cellVols);
65 Pout<< "primitiveMesh::calcCellCentresAndVols() : "
66 << "Finished calculating cell centres and cell volumes"
72 void Foam::primitiveMesh::makeCellCentresAndVols
74 const vectorField& fCtrs,
75 const vectorField& fAreas,
76 vectorField& cellCtrs,
80 // Clear the fields for accumulation
81 cellCtrs = vector::zero;
84 const labelList& own = faceOwner();
85 const labelList& nei = faceNeighbour();
87 // first estimate the approximate cell centre as the average of
90 vectorField cEst(nCells(), vector::zero);
91 labelField nCellFaces(nCells(), 0);
95 cEst[own[facei]] += fCtrs[facei];
96 nCellFaces[own[facei]] += 1;
101 cEst[nei[facei]] += fCtrs[facei];
102 nCellFaces[nei[facei]] += 1;
107 cEst[celli] /= nCellFaces[celli];
112 // Calculate 3*face-pyramid volume
114 max(fAreas[facei] & (fCtrs[facei] - cEst[own[facei]]), VSMALL);
116 // Calculate face-pyramid centre
117 vector pc = (3.0/4.0)*fCtrs[facei] + (1.0/4.0)*cEst[own[facei]];
119 // Accumulate volume-weighted face-pyramid centre
120 cellCtrs[own[facei]] += pyr3Vol*pc;
122 // Accumulate face-pyramid volume
123 cellVols[own[facei]] += pyr3Vol;
128 // Calculate 3*face-pyramid volume
130 max(fAreas[facei] & (cEst[nei[facei]] - fCtrs[facei]), VSMALL);
132 // Calculate face-pyramid centre
133 vector pc = (3.0/4.0)*fCtrs[facei] + (1.0/4.0)*cEst[nei[facei]];
135 // Accumulate volume-weighted face-pyramid centre
136 cellCtrs[nei[facei]] += pyr3Vol*pc;
138 // Accumulate face-pyramid volume
139 cellVols[nei[facei]] += pyr3Vol;
142 cellCtrs /= cellVols;
143 cellVols *= (1.0/3.0);
147 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
149 const Foam::vectorField& Foam::primitiveMesh::cellCentres() const
151 if (!cellCentresPtr_)
153 calcCellCentresAndVols();
156 return *cellCentresPtr_;
160 const Foam::scalarField& Foam::primitiveMesh::cellVolumes() const
162 if (!cellVolumesPtr_)
164 calcCellCentresAndVols();
167 return *cellVolumesPtr_;
171 // ************************************************************************* //