Forward compatibility: flex
[foam-extend-3.2.git] / src / foam / meshes / primitiveMesh / primitiveMeshCellCentresAndVols.C
blob4e84337dbbc337022efb30b3fa02834f0991aad2
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | foam-extend: Open Source CFD
4    \\    /   O peration     | Version:     3.2
5     \\  /    A nd           | Web:         http://www.foam-extend.org
6      \\/     M anipulation  | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
8 License
9     This file is part of foam-extend.
11     foam-extend 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 3 of the License, or (at your
14     option) any later version.
16     foam-extend is distributed in the hope that it will be useful, but
17     WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19     General Public License for more details.
21     You should have received a copy of the GNU General Public License
22     along with foam-extend.  If not, see <http://www.gnu.org/licenses/>.
24 Description
25     Efficient cell-centre calculation using face-addressing, face-centres and
26     face-areas.
28 \*---------------------------------------------------------------------------*/
30 #include "primitiveMesh.H"
32 #include "tetPointRef.H"
34 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
36 void Foam::primitiveMesh::calcCellCentresAndVols() const
38     if (debug)
39     {
40         Pout<< "primitiveMesh::calcCellCentresAndVols() : "
41             << "Calculating cell centres and cell volumes"
42             << endl;
43     }
45     // It is an error to attempt to recalculate cellCentres
46     // if the pointer is already set
47     if (cellCentresPtr_ || cellVolumesPtr_)
48     {
49         FatalErrorIn("primitiveMesh::calcCellCentresAndVols() const")
50             << "Cell centres or cell volumes already calculated"
51             << abort(FatalError);
52     }
54     // set the accumulated cell centre to zero vector
55     cellCentresPtr_ = new vectorField(nCells());
56     vectorField& cellCtrs = *cellCentresPtr_;
58     // Initialise cell volumes to 0
59     cellVolumesPtr_ = new scalarField(nCells());
60     scalarField& cellVols = *cellVolumesPtr_;
62     // Make centres and volumes
63     makeCellCentresAndVols(faceCentres(), faceAreas(), cellCtrs, cellVols);
65     if (debug)
66     {
67         Pout<< "primitiveMesh::calcCellCentresAndVols() : "
68             << "Finished calculating cell centres and cell volumes"
69             << endl;
70     }
74 void Foam::primitiveMesh::makeCellCentresAndVols
76     const vectorField& fCtrs,
77     const vectorField& fAreas,
78     vectorField& cellCtrs,
79     scalarField& cellVols
80 ) const
82     // Clear the fields for accumulation
83     cellCtrs = vector::zero;
84     cellVols = 0.0;
86     const labelList& own = faceOwner();
87     const labelList& nei = faceNeighbour();
89     // first estimate the approximate cell centre as the average of
90     // face centres
92     vectorField cEst(nCells(), vector::zero);
93     labelField nCellFaces(nCells(), 0);
95     forAll (own, facei)
96     {
97         cEst[own[facei]] += fCtrs[facei];
98         nCellFaces[own[facei]] += 1;
99     }
101     forAll (nei, facei)
102     {
103         cEst[nei[facei]] += fCtrs[facei];
104         nCellFaces[nei[facei]] += 1;
105     }
107     forAll(cEst, celli)
108     {
109         cEst[celli] /= nCellFaces[celli];
110     }
112     const faceList& allFaces = faces();
113     const pointField& allPoints = points();
115     forAll(own, faceI)
116     {
117         const face& f = allFaces[faceI];
119         if (f.size() == 3)
120         {
121             tetPointRef tpr
122             (
123                 allPoints[f[2]],
124                 allPoints[f[1]],
125                 allPoints[f[0]],
126                 cEst[own[faceI]]
127             );
129             scalar tetVol = tpr.mag();
131             // Accumulate volume-weighted tet centre
132             cellCtrs[own[faceI]] += tetVol*tpr.centre();
134             // Accumulate tet volume
135             cellVols[own[faceI]] += tetVol;
136         }
137         else
138         {
139             forAll(f, pI)
140             {
141                 tetPointRef tpr
142                 (
143                     allPoints[f[pI]],
144                     allPoints[f.prevLabel(pI)],
145                     fCtrs[faceI],
146                     cEst[own[faceI]]
147                 );
149                 scalar tetVol = tpr.mag();
151                 // Accumulate volume-weighted tet centre
152                 cellCtrs[own[faceI]] += tetVol*tpr.centre();
154                 // Accumulate tet volume
155                 cellVols[own[faceI]] += tetVol;
156             }
157         }
158     }
160     forAll(nei, faceI)
161     {
162         const face& f = allFaces[faceI];
164         if (f.size() == 3)
165         {
166             tetPointRef tpr
167             (
168                 allPoints[f[0]],
169                 allPoints[f[1]],
170                 allPoints[f[2]],
171                 cEst[nei[faceI]]
172             );
174             scalar tetVol = tpr.mag();
176             // Accumulate volume-weighted tet centre
177             cellCtrs[nei[faceI]] += tetVol*tpr.centre();
179             // Accumulate tet volume
180             cellVols[nei[faceI]] += tetVol;
181         }
182         else
183         {
184             forAll(f, pI)
185             {
186                 tetPointRef tpr
187                 (
188                     allPoints[f[pI]],
189                     allPoints[f.nextLabel(pI)],
190                     fCtrs[faceI],
191                     cEst[nei[faceI]]
192                 );
194                 scalar tetVol = tpr.mag();
196                 // Accumulate volume-weighted tet centre
197                 cellCtrs[nei[faceI]] += tetVol*tpr.centre();
199                 // Accumulate tet volume
200                 cellVols[nei[faceI]] += tetVol;
201             }
202         }
203     }
205     cellCtrs /= cellVols + VSMALL;
209 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
211 const Foam::vectorField& Foam::primitiveMesh::cellCentres() const
213     if (!cellCentresPtr_)
214     {
215         calcCellCentresAndVols();
216     }
218     return *cellCentresPtr_;
222 const Foam::scalarField& Foam::primitiveMesh::cellVolumes() const
224     if (!cellVolumesPtr_)
225     {
226         calcCellCentresAndVols();
227     }
229     return *cellVolumesPtr_;
233 // ************************************************************************* //