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/>.
24 \*---------------------------------------------------------------------------*/
26 #include "twoDPointCorrector.H"
28 #include "wedgePolyPatch.H"
29 #include "emptyPolyPatch.H"
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39 const scalar twoDPointCorrector::edgeOrthogonalityTol = 1.0 - 1e-4;
41 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
43 void twoDPointCorrector::calcAddressing() const
45 // Find geometry normal
46 planeNormalPtr_ = new vector(0, 0, 0);
47 vector& pn = *planeNormalPtr_;
52 // Attempt to find wedge patch and work out the normal from it.
53 // If not found, find an empty patch with faces in it and use the
54 // normal of the first face. If neither is found, declare an
57 // Try and find a wedge patch
58 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
60 forAll(patches, patchI)
62 if (isA<wedgePolyPatch>(patches[patchI]))
66 pn = refCast<const wedgePolyPatch>(patches[patchI]).centreNormal();
70 Pout<< "Found normal from wedge patch " << patchI;
77 // Try to find an empty patch with faces
80 forAll(patches, patchI)
82 if (isA<emptyPolyPatch>(patches[patchI]) && patches[patchI].size())
84 pn = patches[patchI].faceAreas()[0];
88 Pout<< "Found normal from empty patch " << patchI;
101 "twoDPointCorrector::twoDPointCorrector(const polyMesh& mesh, "
103 ) << "Cannot determine normal vector from patches."
104 << abort(FatalError);
113 Pout<< " twoDPointCorrector normal: " << pn << endl;
116 // Select edges to be included in check.
117 normalEdgeIndicesPtr_ = new labelList(mesh_.nEdges());
118 labelList& neIndices = *normalEdgeIndicesPtr_;
120 const edgeList& meshEdges = mesh_.edges();
122 const pointField& meshPoints = mesh_.points();
124 label nNormalEdges = 0;
126 forAll(meshEdges, edgeI)
129 meshEdges[edgeI].vec(meshPoints)/
130 (meshEdges[edgeI].mag(meshPoints) + VSMALL);
132 if (mag(edgeVector & pn) > edgeOrthogonalityTol)
134 // this edge is normal to the plane. Add it to the list
135 neIndices[nNormalEdges++] = edgeI;
139 neIndices.setSize(nNormalEdges);
141 // Construction check: number of points in a read 2-D or wedge geometry
142 // should be odd and the number of edges normal to the plane should be
143 // exactly half the number of points
146 if (meshPoints.size() % 2 != 0)
150 "twoDPointCorrector::twoDPointCorrector("
151 "const polyMesh& mesh, const vector& n)"
152 ) << "the number of vertices in the geometry "
153 << "is odd - this should not be the case for a 2-D case. "
154 << "Please check the geometry."
158 if (2*nNormalEdges != meshPoints.size())
162 "twoDPointCorrector::twoDPointCorrector("
163 "const polyMesh& mesh, const vector& n)"
164 ) << "The number of points in the mesh is "
165 << "not equal to twice the number of edges normal to the plane "
166 << "- this may be OK only for wedge geometries.\n"
167 << " Please check the geometry or adjust "
168 << "the orthogonality tolerance.\n" << endl
169 << "Number of normal edges: " << nNormalEdges
170 << " number of points: " << meshPoints.size()
177 void twoDPointCorrector::clearAddressing() const
179 deleteDemandDrivenData(planeNormalPtr_);
180 deleteDemandDrivenData(normalEdgeIndicesPtr_);
184 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
186 twoDPointCorrector::twoDPointCorrector(const polyMesh& mesh)
189 required_(mesh_.nGeometricD() == 2),
190 planeNormalPtr_(NULL),
191 normalEdgeIndicesPtr_(NULL)
196 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
198 Foam::twoDPointCorrector::~twoDPointCorrector()
204 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
206 direction twoDPointCorrector::normalDir() const
208 const vector& pn = planeNormal();
210 if (mag(pn.x()) >= edgeOrthogonalityTol)
214 else if (mag(pn.y()) >= edgeOrthogonalityTol)
218 else if (mag(pn.z()) >= edgeOrthogonalityTol)
224 FatalErrorIn("direction twoDPointCorrector::normalDir() const")
225 << "Plane normal not aligned with the coordinate system" << nl
227 << abort(FatalError);
234 // Return plane normal
235 const vector& twoDPointCorrector::planeNormal() const
237 if (!planeNormalPtr_)
242 return *planeNormalPtr_;
246 // Return indices of normal edges.
247 const labelList& twoDPointCorrector::normalEdgeIndices() const
249 if (!normalEdgeIndicesPtr_)
254 return *normalEdgeIndicesPtr_;
258 void twoDPointCorrector::correctPoints(pointField& p) const
260 if (!required_) return;
263 // Loop through all edges. Calculate the average point position A for
264 // the front and the back. Correct the position of point P (in two planes)
265 // such that vectors AP and planeNormal are parallel
267 // Get reference to edges
268 const edgeList& meshEdges = mesh_.edges();
270 const labelList& neIndices = normalEdgeIndices();
271 const vector& pn = planeNormal();
273 forAll(neIndices, edgeI)
275 point& pStart = p[meshEdges[neIndices[edgeI]].start()];
277 point& pEnd = p[meshEdges[neIndices[edgeI]].end()];
279 // calculate average point position
280 const point A = 0.5*(pStart + pEnd);
282 // correct point locations
283 pStart = A + pn*(pn & (pStart - A));
284 pEnd = A + pn*(pn & (pEnd - A));
289 void twoDPointCorrector::updateMesh()
295 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
297 } // End namespace Foam
299 // ************************************************************************* //