1 /*---------------------------------------------------------------------------*\
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 -------------------------------------------------------------------------------
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/>.
25 Class applies a two-dimensional correction to mesh motion point field.
26 The correction guarantees that the mesh does not get twisted during motion
27 and thus introduce a third dimension into a 2-D problem.
29 \*---------------------------------------------------------------------------*/
31 #include "twoDPointCorrector.H"
33 #include "wedgePolyPatch.H"
34 #include "emptyPolyPatch.H"
36 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
41 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
43 const scalar twoDPointCorrector::edgeOrthogonalityTol = 1.0 - 1e-4;
45 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
47 void twoDPointCorrector::calcAddressing() const
49 // Find geometry normal
50 planeNormalPtr_ = new vector(0, 0, 0);
51 vector& pn = *planeNormalPtr_;
56 // Attempt to find wedge patch and work out the normal from it.
57 // If not found, find an empty patch with faces in it and use the
58 // normal of the first face. If neither is found, declare an
61 // Try and find a wedge patch
62 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
64 forAll (patches, patchI)
66 if (isA<wedgePolyPatch>(patches[patchI]))
70 pn = refCast<const wedgePolyPatch>(patches[patchI]).centreNormal();
74 Pout << "Found normal from wedge patch " << patchI;
81 // Try to find an empty patch with faces
84 forAll (patches, patchI)
86 if (isA<emptyPolyPatch>(patches[patchI]) && patches[patchI].size())
88 pn = patches[patchI].faceAreas()[0];
92 Pout << "Found normal from empty patch " << patchI;
101 if (mag(pn) < VSMALL)
105 "twoDPointCorrector::twoDPointCorrector(const polyMesh& mesh, "
107 ) << "Cannot determine normal vector from patches."
108 << abort(FatalError);
117 Pout << " twoDPointCorrector normal: " << pn << endl;
120 // Select edges to be included in check.
121 normalEdgeIndicesPtr_ = new labelList(mesh_.nEdges());
122 labelList& neIndices = *normalEdgeIndicesPtr_;
124 const edgeList& meshEdges = mesh_.edges();
126 const pointField& meshPoints = mesh_.points();
128 label nNormalEdges = 0;
130 forAll (meshEdges, edgeI)
133 meshEdges[edgeI].vec(meshPoints)/
134 (meshEdges[edgeI].mag(meshPoints) + VSMALL);
136 if (mag(edgeVector & pn) > edgeOrthogonalityTol)
138 // this edge is normal to the plane. Add it to the list
139 neIndices[nNormalEdges++] = edgeI;
143 neIndices.setSize(nNormalEdges);
145 // Construction check: number of points in a read 2-D or wedge geometry
146 // should be odd and the number of edges normal to the plane should be
147 // exactly half the number of points
150 if (meshPoints.size() % 2 != 0)
154 "twoDPointCorrector::twoDPointCorrector("
155 "const polyMesh& mesh, const vector& n)"
156 ) << "the number of vertices in the geometry "
157 << "is odd - this should not be the case for a 2-D case. "
158 << "Please check the geometry."
162 if (2*nNormalEdges != meshPoints.size())
166 "twoDPointCorrector::twoDPointCorrector("
167 "const polyMesh& mesh, const vector& n)"
168 ) << "The number of points in the mesh is not equal "
169 << "to twice the number of edges normal to the plane "
170 << "- this may be OK only for wedge geometries.\n"
171 << " Please check the geometry or adjust "
172 << "the orthogonality tolerance.\n" << endl
173 << "Number of normal edges: " << nNormalEdges
174 << " number of points: " << meshPoints.size()
181 void twoDPointCorrector::clearAddressing() const
183 deleteDemandDrivenData(planeNormalPtr_);
184 deleteDemandDrivenData(normalEdgeIndicesPtr_);
188 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
190 twoDPointCorrector::twoDPointCorrector(const polyMesh& mesh)
193 required_(mesh_.nGeometricD() == 2),
194 planeNormalPtr_(NULL),
195 normalEdgeIndicesPtr_(NULL)
200 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
202 Foam::twoDPointCorrector::~twoDPointCorrector()
208 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
210 direction twoDPointCorrector::normalDir() const
212 const vector& pn = planeNormal();
214 if (mag(pn.x()) >= edgeOrthogonalityTol)
218 else if (mag(pn.y()) >= edgeOrthogonalityTol)
222 else if (mag(pn.z()) >= edgeOrthogonalityTol)
228 FatalErrorIn("direction twoDPointCorrector::normalDir() const")
229 << "Plane normal not aligned with the coordinate system" << nl
231 << abort(FatalError);
238 // Return plane normal
239 const vector& twoDPointCorrector::planeNormal() const
241 if (!planeNormalPtr_)
246 return *planeNormalPtr_;
250 // Return indices of normal edges.
251 const labelList& twoDPointCorrector::normalEdgeIndices() const
253 if (!normalEdgeIndicesPtr_)
258 return *normalEdgeIndicesPtr_;
262 void twoDPointCorrector::correctPoints(pointField& p) const
264 if (!required_) return;
267 // Loop through all edges. Calculate the average point position A for
268 // the front and the back. Correct the position of point P (in two planes)
269 // such that vectors AP and planeNormal are parallel
271 // Get reference to edges
272 const edgeList& meshEdges = mesh_.edges();
274 const labelList& neIndices = normalEdgeIndices();
275 const vector& pn = planeNormal();
277 forAll (neIndices, edgeI)
279 point& pStart = p[meshEdges[neIndices[edgeI]].start()];
281 point& pEnd = p[meshEdges[neIndices[edgeI]].end()];
283 // calculate average point position
284 const point A = 0.5*(pStart + pEnd);
286 // correct point locations
287 pStart = A + pn*(pn & (pStart - A));
288 pEnd = A + pn*(pn & (pEnd - A));
293 void twoDPointCorrector::updateMesh()
299 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
301 } // End namespace Foam
303 // ************************************************************************* //