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
25 \*---------------------------------------------------------------------------*/
27 #include "coupledPolyPatch.H"
28 #include "SortableList.H"
30 #include "transform.H"
33 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
37 defineTypeNameAndDebug(coupledPolyPatch, 0);
40 Foam::scalar Foam::coupledPolyPatch::matchTol = 1E-3;
43 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
45 void Foam::coupledPolyPatch::writeOBJ(Ostream& os, const point& pt)
47 os << "v " << pt.x() << ' ' << pt.y() << ' ' << pt.z() << endl;
51 void Foam::coupledPolyPatch::writeOBJ
54 const pointField& points,
55 const labelList& pointLabels
58 forAll(pointLabels, i)
60 writeOBJ(os, points[pointLabels[i]]);
65 void Foam::coupledPolyPatch::writeOBJ
79 os<< "l " << vertI-1 << ' ' << vertI << nl;
83 void Foam::coupledPolyPatch::writeOBJ
85 const fileName& fName,
86 const UList<face>& faces,
87 const pointField& points
92 Map<label> foamToObj(4*faces.size());
98 const face& f = faces[i];
102 if (foamToObj.insert(f[fp], vertI))
104 writeOBJ(os, points[f[fp]]);
112 os << ' ' << foamToObj[f[fp]]+1;
114 os << ' ' << foamToObj[f[0]]+1 << nl;
119 Foam::pointField Foam::coupledPolyPatch::calcFaceCentres
121 const UList<face>& faces,
122 const pointField& points
125 pointField ctrs(faces.size());
129 ctrs[faceI] = faces[faceI].centre(points);
136 Foam::pointField Foam::coupledPolyPatch::getAnchorPoints
138 const UList<face>& faces,
139 const pointField& points
142 pointField anchors(faces.size());
146 anchors[faceI] = points[faces[faceI][0]];
153 bool Foam::coupledPolyPatch::inPatch
155 const labelList& oldToNew,
159 label faceI = oldToNew[oldFaceI];
161 return faceI >= start() && faceI < start()+size();
165 Foam::label Foam::coupledPolyPatch::whichPatch
167 const labelList& patchStarts,
171 forAll(patchStarts, patchI)
173 if (patchStarts[patchI] <= faceI)
175 if (patchI == patchStarts.size()-1)
179 else if (patchStarts[patchI+1] > faceI)
190 Foam::scalarField Foam::coupledPolyPatch::calcFaceTol
192 const UList<face>& faces,
193 const pointField& points,
194 const pointField& faceCentres
197 // Calculate typical distance per face
198 scalarField tols(faces.size());
202 const point& cc = faceCentres[faceI];
204 const face& f = faces[faceI];
206 scalar maxLenSqr = -GREAT;
210 maxLenSqr = max(maxLenSqr, magSqr(points[f[fp]] - cc));
212 tols[faceI] = matchTol * Foam::sqrt(maxLenSqr);
218 Foam::label Foam::coupledPolyPatch::getRotation
220 const pointField& points,
227 scalar minDistSqr = GREAT;
231 scalar distSqr = magSqr(anchor - points[f[fp]]);
233 if (distSqr < minDistSqr)
235 minDistSqr = distSqr;
240 if (anchorFp == -1 || mag(minDistSqr) > tol)
247 return (f.size() - anchorFp) % f.size();
252 void Foam::coupledPolyPatch::calcTransformTensors
254 const vectorField& Cf,
255 const vectorField& Cr,
256 const vectorField& nf,
257 const vectorField& nr,
258 const scalarField& smallDist,
264 Pout<< "coupledPolyPatch::calcTransformTensors : " << name() << endl
265 << " (half)size:" << Cf.size() << nl
266 << " absTol:" << absTol << nl
267 << " sum(mag(nf & nr)):" << sum(mag(nf & nr)) << endl;
270 // Tolerance calculation.
271 // - normal calculation: assume absTol is the absolute error in a
272 // single normal/transformation calculation. Consists both of numerical
273 // precision (on the order of SMALL and of writing precision
274 // (from e.g. decomposition)
275 // Then the overall error of summing the normals is sqrt(size())*absTol
276 // - separation calculation: pass in from the outside an allowable error.
281 separation_.setSize(0);
287 scalar error = absTol*Foam::sqrt(1.0*Cf.size());
291 Pout<< " error:" << error << endl;
294 if (sum(mag(nf & nr)) < Cf.size()-error)
296 // Rotation, no separation
298 separation_.setSize(0);
300 forwardT_.setSize(Cf.size());
301 reverseT_.setSize(Cf.size());
303 forAll (forwardT_, facei)
305 forwardT_[facei] = rotationTensor(-nr[facei], nf[facei]);
306 reverseT_[facei] = rotationTensor(nf[facei], -nr[facei]);
311 Pout<< " sum(mag(forwardT_ - forwardT_[0])):"
312 << sum(mag(forwardT_ - forwardT_[0]))
316 if (sum(mag(forwardT_ - forwardT_[0])) < error)
318 forwardT_.setSize(1);
319 reverseT_.setSize(1);
324 forwardT_.setSize(0);
325 reverseT_.setSize(0);
327 separation_ = (nf&(Cr - Cf))*nf;
330 // - separation is zero. No separation.
331 // - separation is same. Single separation vector.
332 // - separation differs per face. Separation vectorField.
334 // Check for different separation per face
335 bool sameSeparation = true;
337 forAll(separation_, facei)
339 scalar smallSqr = sqr(smallDist[facei]);
341 if (magSqr(separation_[facei] - separation_[0]) > smallSqr)
345 Pout<< " separation " << separation_[facei]
347 << " differs from separation[0] " << separation_[0]
348 << " by more than local tolerance "
350 << ". Assuming non-uniform separation." << endl;
352 sameSeparation = false;
359 // Check for zero separation (at 0 so everywhere)
360 if (magSqr(separation_[0]) < sqr(smallDist[0]))
364 Pout<< " separation " << mag(separation_[0])
365 << " less than local tolerance " << smallDist[0]
366 << ". Assuming zero separation." << endl;
369 separation_.setSize(0);
375 Pout<< " separation " << mag(separation_[0])
376 << " more than local tolerance " << smallDist[0]
377 << ". Assuming uniform separation." << endl;
380 separation_.setSize(1);
388 Pout<< " separation_:" << separation_ << nl
389 << " forwardT size:" << forwardT_.size() << endl;
394 // * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * * * //
396 Foam::coupledPolyPatch::coupledPolyPatch
402 const polyBoundaryMesh& bm
405 polyPatch(name, size, start, index, bm)
409 Foam::coupledPolyPatch::coupledPolyPatch
412 const dictionary& dict,
414 const polyBoundaryMesh& bm
417 polyPatch(name, dict, index, bm)
421 Foam::coupledPolyPatch::coupledPolyPatch
423 const coupledPolyPatch& pp,
424 const polyBoundaryMesh& bm
431 Foam::coupledPolyPatch::coupledPolyPatch
433 const coupledPolyPatch& pp,
434 const polyBoundaryMesh& bm,
440 polyPatch(pp, bm, index, newSize, newStart)
444 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
446 Foam::coupledPolyPatch::~coupledPolyPatch()
450 // ************************************************************************* //