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 "coupledPolyPatch.H"
28 #include "transform.H"
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35 defineTypeNameAndDebug(coupledPolyPatch, 0);
37 const scalar coupledPolyPatch::defaultMatchTol_ = 1E-4;
40 const char* NamedEnum<coupledPolyPatch::transformType, 4>::names[] =
48 const NamedEnum<coupledPolyPatch::transformType, 4>
49 coupledPolyPatch::transformTypeNames;
53 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
55 void Foam::coupledPolyPatch::writeOBJ(Ostream& os, const point& pt)
57 os << "v " << pt.x() << ' ' << pt.y() << ' ' << pt.z() << endl;
61 void Foam::coupledPolyPatch::writeOBJ
64 const pointField& points,
65 const labelList& pointLabels
68 forAll(pointLabels, i)
70 writeOBJ(os, points[pointLabels[i]]);
75 void Foam::coupledPolyPatch::writeOBJ
89 os << "l " << vertI-1 << ' ' << vertI << nl;
93 void Foam::coupledPolyPatch::writeOBJ
95 const fileName& fName,
96 const UList<face>& faces,
97 const pointField& points
102 Map<label> foamToObj(4*faces.size());
108 const face& f = faces[i];
112 if (foamToObj.insert(f[fp], vertI))
114 writeOBJ(os, points[f[fp]]);
122 os << ' ' << foamToObj[f[fp]]+1;
124 os << ' ' << foamToObj[f[0]]+1 << nl;
129 Foam::pointField Foam::coupledPolyPatch::getAnchorPoints
131 const UList<face>& faces,
132 const pointField& points
135 pointField anchors(faces.size());
139 anchors[faceI] = points[faces[faceI][0]];
146 Foam::scalarField Foam::coupledPolyPatch::calcFaceTol
148 const scalar matchTol,
149 const UList<face>& faces,
150 const pointField& points,
151 const pointField& faceCentres
154 // Calculate typical distance per face
155 scalarField tols(faces.size());
159 const point& cc = faceCentres[faceI];
161 const face& f = faces[faceI];
163 // 1. calculate a typical size of the face. Use maximum distance
165 scalar maxLenSqr = -GREAT;
166 // 2. as measure of truncation error when comparing two coordinates
167 // use SMALL * maximum component
168 scalar maxCmpt = -GREAT;
172 const point& pt = points[f[fp]];
173 maxLenSqr = max(maxLenSqr, magSqr(pt - cc));
174 maxCmpt = max(maxCmpt, cmptMax(cmptMag(pt)));
176 tols[faceI] = max(SMALL*maxCmpt, matchTol*Foam::sqrt(maxLenSqr));
182 Foam::label Foam::coupledPolyPatch::getRotation
184 const pointField& points,
191 scalar minDistSqr = GREAT;
195 scalar distSqr = magSqr(anchor - points[f[fp]]);
197 if (distSqr < minDistSqr)
199 minDistSqr = distSqr;
204 if (anchorFp == -1 || mag(minDistSqr) > tol)
211 return (f.size() - anchorFp) % f.size();
216 void Foam::coupledPolyPatch::calcTransformTensors
218 const vectorField& Cf,
219 const vectorField& Cr,
220 const vectorField& nf,
221 const vectorField& nr,
222 const scalarField& smallDist,
224 const transformType transform
229 Pout<< "coupledPolyPatch::calcTransformTensors : " << name() << endl
230 << " transform:" << transformTypeNames[transform] << nl
231 << " (half)size:" << Cf.size() << nl
232 << " absTol:" << absTol << nl
233 << " smallDist min:" << min(smallDist) << nl
234 << " smallDist max:" << max(smallDist) << nl
235 << " sum(mag(nf & nr)):" << sum(mag(nf & nr)) << endl;
238 // Tolerance calculation.
239 // - normal calculation: assume absTol is the absolute error in a
240 // single normal/transformation calculation. Consists both of numerical
241 // precision (on the order of SMALL and of writing precision
242 // (from e.g. decomposition)
243 // Then the overall error of summing the normals is sqrt(size())*absTol
244 // - separation calculation: pass in from the outside an allowable error.
249 separation_.setSize(0);
252 collocated_.setSize(0);
256 scalar error = absTol*Foam::sqrt(1.0*Cf.size());
260 Pout<< " error:" << error << endl;
265 transform == ROTATIONAL
267 transform != TRANSLATIONAL
268 && (sum(mag(nf & nr)) < Cf.size()-error)
272 // Type is rotation or unknown and normals not aligned
274 // Assume per-face differing transformation, correct later
276 separation_.setSize(0);
278 forwardT_.setSize(Cf.size());
279 reverseT_.setSize(Cf.size());
280 collocated_.setSize(Cf.size());
283 forAll(forwardT_, facei)
285 forwardT_[facei] = rotationTensor(-nr[facei], nf[facei]);
286 reverseT_[facei] = rotationTensor(nf[facei], -nr[facei]);
291 Pout<< " sum(mag(forwardT_ - forwardT_[0])):"
292 << sum(mag(forwardT_ - forwardT_[0]))
296 if (sum(mag(forwardT_ - forwardT_[0])) < error)
298 forwardT_.setSize(1);
299 reverseT_.setSize(1);
300 collocated_.setSize(1);
304 Pout<< " difference in rotation less than"
305 << " local tolerance "
306 << error << ". Assuming uniform rotation." << endl;
312 // Translational or (unknown and normals aligned)
314 forwardT_.setSize(0);
315 reverseT_.setSize(0);
317 separation_ = Cr - Cf;
319 collocated_.setSize(separation_.size());
322 // - separation is zero. No separation.
323 // - separation is same. Single separation vector.
324 // - separation differs per face. Separation vectorField.
326 // Check for different separation per face
327 bool sameSeparation = true;
328 bool doneWarning = false;
330 forAll(separation_, facei)
332 scalar smallSqr = sqr(smallDist[facei]);
334 collocated_[facei] = (magSqr(separation_[facei]) < smallSqr);
336 // Check if separation differing w.r.t. face 0.
337 if (magSqr(separation_[facei] - separation_[0]) > smallSqr)
339 sameSeparation = false;
341 if (!doneWarning && debug)
345 Pout<< " separation " << separation_[facei]
347 << " differs from separation[0] " << separation_[0]
348 << " by more than local tolerance "
350 << ". Assuming non-uniform separation." << endl;
357 // Check for zero separation (at 0 so everywhere)
362 Pout<< " separation " << mag(separation_[0])
363 << " less than local tolerance " << smallDist[0]
364 << ". Assuming zero separation." << endl;
367 separation_.setSize(0);
368 collocated_ = boolList(1, true);
374 Pout<< " separation " << mag(separation_[0])
375 << " more than local tolerance " << smallDist[0]
376 << ". Assuming uniform separation." << endl;
379 separation_.setSize(1);
380 collocated_ = boolList(1, false);
388 Pout<< " separation_:" << separation_.size() << nl
389 << " forwardT size:" << forwardT_.size() << endl;
394 // * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * * * //
396 Foam::coupledPolyPatch::coupledPolyPatch
402 const polyBoundaryMesh& bm
405 polyPatch(name, size, start, index, bm),
406 matchTolerance_(defaultMatchTol_)
410 Foam::coupledPolyPatch::coupledPolyPatch
413 const dictionary& dict,
415 const polyBoundaryMesh& bm
418 polyPatch(name, dict, index, bm),
419 matchTolerance_(dict.lookupOrDefault("matchTolerance", defaultMatchTol_))
423 Foam::coupledPolyPatch::coupledPolyPatch
425 const coupledPolyPatch& pp,
426 const polyBoundaryMesh& bm
430 matchTolerance_(pp.matchTolerance_)
434 Foam::coupledPolyPatch::coupledPolyPatch
436 const coupledPolyPatch& pp,
437 const polyBoundaryMesh& bm,
443 polyPatch(pp, bm, index, newSize, newStart),
444 matchTolerance_(pp.matchTolerance_)
448 Foam::coupledPolyPatch::coupledPolyPatch
450 const coupledPolyPatch& pp,
451 const polyBoundaryMesh& bm,
453 const labelUList& mapAddressing,
457 polyPatch(pp, bm, index, mapAddressing, newStart),
458 matchTolerance_(pp.matchTolerance_)
462 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
464 Foam::coupledPolyPatch::~coupledPolyPatch()
468 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
470 void Foam::coupledPolyPatch::write(Ostream& os) const
472 polyPatch::write(os);
473 //if (matchTolerance_ != defaultMatchTol_)
475 os.writeKeyword("matchTolerance") << matchTolerance_
476 << token::END_STATEMENT << nl;
481 // ************************************************************************* //