1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
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 Class applies a two-dimensional correction to mesh motion point field.
27 The correction guarantees that the mesh does not get twisted during motion
28 and thus introduce a third dimension into a 2-D problem.
30 \*---------------------------------------------------------------------------*/
32 #include "twoDPointCorrector.H"
34 #include "wedgePolyPatch.H"
35 #include "emptyPolyPatch.H"
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
44 const scalar twoDPointCorrector::edgeOrthogonalityTol = 1.0 - 1e-4;
46 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
48 void twoDPointCorrector::calcAddressing() const
50 // Find geometry normal
51 planeNormalPtr_ = new vector(0, 0, 0);
52 vector& pn = *planeNormalPtr_;
57 // Attempt to find wedge patch and work out the normal from it.
58 // If not found, find an empty patch with faces in it and use the
59 // normal of the first face. If neither is found, declare an
62 // Try and find a wedge patch
63 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
65 forAll (patches, patchI)
67 if (isA<wedgePolyPatch>(patches[patchI]))
71 pn = refCast<const wedgePolyPatch>(patches[patchI]).centreNormal();
75 Pout << "Found normal from wedge patch " << patchI;
82 // Try to find an empty patch with faces
85 forAll (patches, patchI)
89 isA<emptyPolyPatch>(patches[patchI])
90 && patches[patchI].size() > 0
93 pn = patches[patchI].faceAreas()[0];
97 Pout << "Found normal from empty patch " << patchI;
106 if (mag(pn) < VSMALL)
110 "twoDPointCorrector::twoDPointCorrector(const polyMesh& mesh, "
112 ) << "Cannot determine normal vector from patches."
113 << abort(FatalError);
122 Pout << " twoDPointCorrector normal: " << pn << endl;
125 // Select edges to be included in check.
126 normalEdgeIndicesPtr_ = new labelList(mesh_.nEdges());
127 labelList& neIndices = *normalEdgeIndicesPtr_;
129 const edgeList& meshEdges = mesh_.edges();
131 const pointField& meshPoints = mesh_.points();
133 label nNormalEdges = 0;
135 forAll (meshEdges, edgeI)
138 meshEdges[edgeI].vec(meshPoints)/
139 (meshEdges[edgeI].mag(meshPoints) + VSMALL);
141 if (mag(edgeVector & pn) > edgeOrthogonalityTol)
143 // this edge is normal to the plane. Add it to the list
144 neIndices[nNormalEdges++] = edgeI;
148 neIndices.setSize(nNormalEdges);
150 // Construction check: number of points in a read 2-D or wedge geometry
151 // should be odd and the number of edges normal to the plane should be
152 // exactly half the number of points
155 if (meshPoints.size() % 2 != 0)
159 "twoDPointCorrector::twoDPointCorrector("
160 "const polyMesh& mesh, const vector& n)"
161 ) << "the number of vertices in the geometry "
162 << "is odd - this should not be the case for a 2-D case. "
163 << "Please check the geometry."
167 if (2*nNormalEdges != meshPoints.size())
171 "twoDPointCorrector::twoDPointCorrector("
172 "const polyMesh& mesh, const vector& n)"
173 ) << "The number of points in the mesh is "
174 << "not equal to twice the number of edges normal to the plane "
175 << "- this may be OK only for wedge geometries.\n"
176 << " Please check the geometry or adjust "
177 << "the orthogonality tolerance.\n" << endl
178 << "Number of normal edges: " << nNormalEdges
179 << " number of points: " << meshPoints.size()
186 void twoDPointCorrector::clearAddressing() const
188 deleteDemandDrivenData(planeNormalPtr_);
189 deleteDemandDrivenData(normalEdgeIndicesPtr_);
193 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
195 twoDPointCorrector::twoDPointCorrector(const polyMesh& mesh)
198 required_(mesh_.nGeometricD() == 2),
199 planeNormalPtr_(NULL),
200 normalEdgeIndicesPtr_(NULL)
205 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
207 Foam::twoDPointCorrector::~twoDPointCorrector()
213 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
215 direction twoDPointCorrector::normalDir() const
217 const vector& pn = planeNormal();
219 if (mag(pn.x()) >= edgeOrthogonalityTol)
223 else if (mag(pn.y()) >= edgeOrthogonalityTol)
227 else if (mag(pn.z()) >= edgeOrthogonalityTol)
233 FatalErrorIn("direction twoDPointCorrector::normalDir() const")
234 << "Plane normal not aligned with the coordinate system" << nl
236 << abort(FatalError);
243 // Return plane normal
244 const vector& twoDPointCorrector::planeNormal() const
246 if (!planeNormalPtr_)
251 return *planeNormalPtr_;
255 // Return indices of normal edges.
256 const labelList& twoDPointCorrector::normalEdgeIndices() const
258 if (!normalEdgeIndicesPtr_)
263 return *normalEdgeIndicesPtr_;
267 void twoDPointCorrector::correctPoints(pointField& p) const
269 if (!required_) return;
272 // Loop through all edges. Calculate the average point position A for
273 // the front and the back. Correct the position of point P (in two planes)
274 // such that vectors AP and planeNormal are parallel
276 // Get reference to edges
277 const edgeList& meshEdges = mesh_.edges();
279 const labelList& neIndices = normalEdgeIndices();
280 const vector& pn = planeNormal();
282 forAll (neIndices, edgeI)
284 point& pStart = p[meshEdges[neIndices[edgeI]].start()];
286 point& pEnd = p[meshEdges[neIndices[edgeI]].end()];
288 // calculate average point position
289 const point A = 0.5*(pStart + pEnd);
291 // correct point locations
292 pStart = A + pn*(pn & (pStart - A));
293 pEnd = A + pn*(pn & (pEnd - A));
298 void twoDPointCorrector::updateMesh()
304 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
306 } // End namespace Foam
308 // ************************************************************************* //