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 "surfaceDisplacementPointPatchVectorField.H"
27 #include "addToRunTimeSelectionTable.H"
29 #include "transformField.H"
31 #include "displacementLaplacianFvMotionSolver.H"
33 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
43 NamedEnum<surfaceDisplacementPointPatchVectorField::projectMode, 3>::
51 const NamedEnum<surfaceDisplacementPointPatchVectorField::projectMode, 3>
52 surfaceDisplacementPointPatchVectorField::projectModeNames_;
55 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
57 void surfaceDisplacementPointPatchVectorField::calcProjection
59 vectorField& displacement
62 const polyMesh& mesh = patch().boundaryMesh().mesh()();
63 const pointField& localPoints = patch().localPoints();
64 const labelList& meshPoints = patch().meshPoints();
66 //const scalar deltaT = mesh.time().deltaTValue();
68 // Construct large enough vector in direction of projectDir so
69 // we're guaranteed to hit something.
71 //- Per point projection vector:
72 const scalar projectLen = mag(mesh.bounds().max()-mesh.bounds().min());
74 // For case of fixed projection vector:
76 if (projectMode_ == FIXEDNORMAL)
78 vector n = projectDir_/mag(projectDir_);
79 projectVec = projectLen*n;
83 // Get fixed points (bit of a hack)
84 const pointZone* zonePtr = NULL;
86 if (frozenPointsZone_.size() > 0)
88 const pointZoneMesh& pZones = mesh.pointZones();
90 zonePtr = &pZones[frozenPointsZone_];
92 Pout<< "surfaceDisplacementPointPatchVectorField : Fixing all "
93 << zonePtr->size() << " points in pointZone " << zonePtr->name()
97 // Get the starting locations from the motionSolver
98 const pointField& points0 = mesh.lookupObject<displacementFvMotionSolver>
104 pointField start(meshPoints.size());
107 start[i] = points0[meshPoints[i]] + displacement[i];
110 label nNotProjected = 0;
112 if (projectMode_ == NEAREST)
114 List<pointIndexHit> nearest;
115 labelList hitSurfaces;
116 surfaces().findNearest
119 scalarField(start.size(), sqr(projectLen)),
126 if (zonePtr && (zonePtr->whichPoint(meshPoints[i]) >= 0))
128 // Fixed point. Reset to point0 location.
129 displacement[i] = points0[meshPoints[i]] - localPoints[i];
131 else if (nearest[i].hit())
134 nearest[i].hitPoint()
135 - points0[meshPoints[i]];
143 Pout<< " point:" << meshPoints[i]
144 << " coord:" << localPoints[i]
145 << " did not find any surface within " << projectLen
153 // Do tests on all points. Combine later on.
155 // 1. Check if already on surface
156 List<pointIndexHit> nearest;
158 labelList nearestSurface;
159 surfaces().findNearest
162 scalarField(start.size(), sqr(SMALL)),
168 // 2. intersection. (combined later on with information from nearest
170 vectorField projectVecs(start.size(), projectVec);
172 if (projectMode_ == POINTNORMAL)
174 projectVecs = projectLen*patch().pointNormals();
177 // Knock out any wedge component
178 scalarField offset(start.size(), 0.0);
179 if (wedgePlane_ >= 0 && wedgePlane_ <= vector::nComponents)
183 offset[i] = start[i][wedgePlane_];
184 start[i][wedgePlane_] = 0;
185 projectVecs[i][wedgePlane_] = 0;
189 List<pointIndexHit> rightHit;
192 surfaces().findAnyIntersection
201 List<pointIndexHit> leftHit;
204 surfaces().findAnyIntersection
213 // 3. Choose either -fixed, nearest, right, left.
214 forAll(displacement, i)
216 if (zonePtr && (zonePtr->whichPoint(meshPoints[i]) >= 0))
218 // Fixed point. Reset to point0 location.
219 displacement[i] = points0[meshPoints[i]] - localPoints[i];
221 else if (nearest[i].hit())
225 nearest[i].hitPoint()
226 - points0[meshPoints[i]];
230 pointIndexHit interPt;
232 if (rightHit[i].hit())
234 if (leftHit[i].hit())
238 magSqr(rightHit[i].hitPoint()-start[i])
239 < magSqr(leftHit[i].hitPoint()-start[i])
242 interPt = rightHit[i];
246 interPt = leftHit[i];
251 interPt = rightHit[i];
256 if (leftHit[i].hit())
258 interPt = leftHit[i];
265 if (wedgePlane_ >= 0 && wedgePlane_ <= vector::nComponents)
267 interPt.rawPoint()[wedgePlane_] += offset[i];
269 displacement[i] = interPt.rawPoint()-points0[meshPoints[i]];
277 Pout<< " point:" << meshPoints[i]
278 << " coord:" << localPoints[i]
279 << " did not find any intersection between"
280 << " ray from " << start[i]-projectVecs[i]
281 << " to " << start[i]+projectVecs[i] << endl;
288 reduce(nNotProjected, sumOp<label>());
290 if (nNotProjected > 0)
292 Info<< "surfaceDisplacement :"
293 << " on patch " << patch().name()
294 << " did not project " << nNotProjected
295 << " out of " << returnReduce(localPoints.size(), sumOp<label>())
296 << " points." << endl;
301 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
303 surfaceDisplacementPointPatchVectorField::
304 surfaceDisplacementPointPatchVectorField
307 const DimensionedField<vector, pointMesh>& iF
310 fixedValuePointPatchVectorField(p, iF),
311 velocity_(vector::zero),
312 projectMode_(NEAREST),
313 projectDir_(vector::zero),
318 surfaceDisplacementPointPatchVectorField::
319 surfaceDisplacementPointPatchVectorField
322 const DimensionedField<vector, pointMesh>& iF,
323 const dictionary& dict
326 fixedValuePointPatchVectorField(p, iF, dict),
327 velocity_(dict.lookup("velocity")),
328 surfacesDict_(dict.subDict("geometry")),
329 projectMode_(projectModeNames_.read(dict.lookup("projectMode"))),
330 projectDir_(dict.lookup("projectDirection")),
331 wedgePlane_(dict.lookupOrDefault("wedgePlane", -1)),
332 frozenPointsZone_(dict.lookupOrDefault("frozenPointsZone", word::null))
334 if (velocity_.x() < 0 || velocity_.y() < 0 || velocity_.z() < 0)
338 "surfaceDisplacementPointPatchVectorField::\n"
339 "surfaceDisplacementPointPatchVectorField\n"
341 " const pointPatch& p,\n"
342 " const DimensionedField<vector, pointMesh>& iF,\n"
343 " const dictionary& dict\n"
345 ) << "All components of velocity have to be positive : "
347 << "Set velocity components to a great value if no clipping"
348 << " necessary." << exit(FatalError);
353 surfaceDisplacementPointPatchVectorField::
354 surfaceDisplacementPointPatchVectorField
356 const surfaceDisplacementPointPatchVectorField& ppf,
358 const DimensionedField<vector, pointMesh>& iF,
359 const pointPatchFieldMapper& mapper
362 fixedValuePointPatchVectorField(ppf, p, iF, mapper),
363 velocity_(ppf.velocity_),
364 surfacesDict_(ppf.surfacesDict_),
365 projectMode_(ppf.projectMode_),
366 projectDir_(ppf.projectDir_),
367 wedgePlane_(ppf.wedgePlane_),
368 frozenPointsZone_(ppf.frozenPointsZone_)
372 surfaceDisplacementPointPatchVectorField::
373 surfaceDisplacementPointPatchVectorField
375 const surfaceDisplacementPointPatchVectorField& ppf
378 fixedValuePointPatchVectorField(ppf),
379 velocity_(ppf.velocity_),
380 surfacesDict_(ppf.surfacesDict_),
381 projectMode_(ppf.projectMode_),
382 projectDir_(ppf.projectDir_),
383 wedgePlane_(ppf.wedgePlane_),
384 frozenPointsZone_(ppf.frozenPointsZone_)
388 surfaceDisplacementPointPatchVectorField::
389 surfaceDisplacementPointPatchVectorField
391 const surfaceDisplacementPointPatchVectorField& ppf,
392 const DimensionedField<vector, pointMesh>& iF
395 fixedValuePointPatchVectorField(ppf, iF),
396 velocity_(ppf.velocity_),
397 surfacesDict_(ppf.surfacesDict_),
398 projectMode_(ppf.projectMode_),
399 projectDir_(ppf.projectDir_),
400 wedgePlane_(ppf.wedgePlane_),
401 frozenPointsZone_(ppf.frozenPointsZone_)
405 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
407 const searchableSurfaces&
408 surfaceDisplacementPointPatchVectorField::surfaces() const
410 if (surfacesPtr_.empty())
414 new searchableSurfaces
419 db().time().constant(), // directory
420 "triSurface", // instance
421 db().time(), // registry
429 return surfacesPtr_();
433 void surfaceDisplacementPointPatchVectorField::updateCoeffs()
440 const polyMesh& mesh = patch().boundaryMesh().mesh()();
442 vectorField currentDisplacement(this->patchInternalField());
444 // Calculate intersections with surface w.r.t points0.
445 vectorField displacement(currentDisplacement);
446 calcProjection(displacement);
448 // offset wrt current displacement
449 vectorField offset(displacement-currentDisplacement);
451 // Clip offset to maximum displacement possible: velocity*timestep
453 const scalar deltaT = mesh.time().deltaTValue();
454 const vector clipVelocity = velocity_*deltaT;
456 forAll(displacement, i)
458 vector& d = offset[i];
460 for (direction cmpt = 0; cmpt < vector::nComponents; cmpt++)
464 d[cmpt] = max(d[cmpt], -clipVelocity[cmpt]);
468 d[cmpt] = min(d[cmpt], clipVelocity[cmpt]);
473 this->operator==(currentDisplacement+offset);
475 fixedValuePointPatchVectorField::updateCoeffs();
479 void surfaceDisplacementPointPatchVectorField::write(Ostream& os) const
481 fixedValuePointPatchVectorField::write(os);
482 os.writeKeyword("velocity") << velocity_
483 << token::END_STATEMENT << nl;
484 os.writeKeyword("geometry") << surfacesDict_
485 << token::END_STATEMENT << nl;
486 os.writeKeyword("projectMode") << projectModeNames_[projectMode_]
487 << token::END_STATEMENT << nl;
488 os.writeKeyword("projectDirection") << projectDir_
489 << token::END_STATEMENT << nl;
490 os.writeKeyword("wedgePlane") << wedgePlane_
491 << token::END_STATEMENT << nl;
492 if (frozenPointsZone_ != word::null)
494 os.writeKeyword("frozenPointsZone") << frozenPointsZone_
495 << token::END_STATEMENT << nl;
500 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
502 makePointPatchTypeField
504 fixedValuePointPatchVectorField,
505 surfaceDisplacementPointPatchVectorField
509 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
511 } // End namespace Foam
513 // ************************************************************************* //