1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
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 "surfaceDisplacementPointPatchVectorField.H"
28 #include "addToRunTimeSelectionTable.H"
30 #include "transformField.H"
32 #include "displacementLaplacianFvMotionSolver.H"
34 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
44 NamedEnum<surfaceDisplacementPointPatchVectorField::projectMode, 3>::
52 const NamedEnum<surfaceDisplacementPointPatchVectorField::projectMode, 3>
53 surfaceDisplacementPointPatchVectorField::projectModeNames_;
56 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
58 void surfaceDisplacementPointPatchVectorField::calcProjection
60 vectorField& displacement
63 const polyMesh& mesh = patch().boundaryMesh().mesh()();
64 const pointField& localPoints = patch().localPoints();
65 const labelList& meshPoints = patch().meshPoints();
67 //const scalar deltaT = mesh.time().deltaT().value();
69 // Construct large enough vector in direction of projectDir so
70 // we're guaranteed to hit something.
72 //- Per point projection vector:
73 const scalar projectLen = mag(mesh.bounds().max()-mesh.bounds().min());
75 // For case of fixed projection vector:
77 if (projectMode_ == FIXEDNORMAL)
79 vector n = projectDir_/mag(projectDir_);
80 projectVec = projectLen*n;
84 // Get fixed points (bit of a hack)
85 const pointZone* zonePtr = NULL;
87 if (frozenPointsZone_.size() > 0)
89 const pointZoneMesh& pZones = mesh.pointZones();
91 zonePtr = &pZones[pZones.findZoneID(frozenPointsZone_)];
93 Pout<< "surfaceDisplacementPointPatchVectorField : Fixing all "
94 << zonePtr->size() << " points in pointZone " << zonePtr->name()
98 // Get the starting locations from the motionSolver
99 const pointField& points0 = mesh.lookupObject<displacementFvMotionSolver>
105 pointField start(meshPoints.size());
108 start[i] = points0[meshPoints[i]] + displacement[i];
111 label nNotProjected = 0;
113 if (projectMode_ == NEAREST)
115 List<pointIndexHit> nearest;
116 labelList hitSurfaces;
117 surfaces().findNearest
120 scalarField(start.size(), sqr(projectLen)),
127 if (zonePtr && (zonePtr->whichPoint(meshPoints[i]) >= 0))
129 // Fixed point. Reset to point0 location.
130 displacement[i] = points0[meshPoints[i]] - localPoints[i];
132 else if (nearest[i].hit())
135 nearest[i].hitPoint()
136 - points0[meshPoints[i]];
144 Pout<< " point:" << meshPoints[i]
145 << " coord:" << localPoints[i]
146 << " did not find any surface within " << projectLen
154 // Do tests on all points. Combine later on.
156 // 1. Check if already on surface
157 List<pointIndexHit> nearest;
159 labelList nearestSurface;
160 surfaces().findNearest
163 scalarField(start.size(), sqr(SMALL)),
169 // 2. intersection. (combined later on with information from nearest
171 vectorField projectVecs(start.size(), projectVec);
173 if (projectMode_ == POINTNORMAL)
175 projectVecs = projectLen*patch().pointNormals();
178 // Knock out any wedge component
179 scalarField offset(start.size(), 0.0);
180 if (wedgePlane_ >= 0 && wedgePlane_ <= vector::nComponents)
184 offset[i] = start[i][wedgePlane_];
185 start[i][wedgePlane_] = 0;
186 projectVecs[i][wedgePlane_] = 0;
190 List<pointIndexHit> rightHit;
193 surfaces().findAnyIntersection
202 List<pointIndexHit> leftHit;
205 surfaces().findAnyIntersection
214 // 3. Choose either -fixed, nearest, right, left.
215 forAll(displacement, i)
217 if (zonePtr && (zonePtr->whichPoint(meshPoints[i]) >= 0))
219 // Fixed point. Reset to point0 location.
220 displacement[i] = points0[meshPoints[i]] - localPoints[i];
222 else if (nearest[i].hit())
226 nearest[i].hitPoint()
227 - points0[meshPoints[i]];
231 pointIndexHit interPt;
233 if (rightHit[i].hit())
235 if (leftHit[i].hit())
239 magSqr(rightHit[i].hitPoint()-start[i])
240 < magSqr(leftHit[i].hitPoint()-start[i])
243 interPt = rightHit[i];
247 interPt = leftHit[i];
252 interPt = rightHit[i];
257 if (leftHit[i].hit())
259 interPt = leftHit[i];
266 if (wedgePlane_ >= 0 && wedgePlane_ <= vector::nComponents)
268 interPt.rawPoint()[wedgePlane_] += offset[i];
270 displacement[i] = interPt.rawPoint()-points0[meshPoints[i]];
278 Pout<< " point:" << meshPoints[i]
279 << " coord:" << localPoints[i]
280 << " did not find any intersection between"
281 << " ray from " << start[i]-projectVecs[i]
282 << " to " << start[i]+projectVecs[i] << endl;
289 reduce(nNotProjected, sumOp<label>());
291 if (nNotProjected > 0)
293 Info<< "surfaceDisplacement :"
294 << " on patch " << patch().name()
295 << " did not project " << nNotProjected
296 << " out of " << returnReduce(localPoints.size(), sumOp<label>())
297 << " points." << endl;
302 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
304 surfaceDisplacementPointPatchVectorField::
305 surfaceDisplacementPointPatchVectorField
308 const DimensionedField<vector, pointMesh>& iF
311 fixedValuePointPatchVectorField(p, iF),
312 velocity_(vector::zero),
313 projectMode_(NEAREST),
314 projectDir_(vector::zero),
319 surfaceDisplacementPointPatchVectorField::
320 surfaceDisplacementPointPatchVectorField
323 const DimensionedField<vector, pointMesh>& iF,
324 const dictionary& dict
327 fixedValuePointPatchVectorField(p, iF, dict),
328 velocity_(dict.lookup("velocity")),
329 surfacesDict_(dict.subDict("geometry")),
330 projectMode_(projectModeNames_.read(dict.lookup("projectMode"))),
331 projectDir_(dict.lookup("projectDirection")),
332 wedgePlane_(dict.lookupOrDefault("wedgePlane", -1)),
333 frozenPointsZone_(dict.lookupOrDefault("frozenPointsZone", word::null))
335 if (velocity_.x() < 0 || velocity_.y() < 0 || velocity_.z() < 0)
339 "surfaceDisplacementPointPatchVectorField::\n"
340 "surfaceDisplacementPointPatchVectorField\n"
342 " const pointPatch& p,\n"
343 " const DimensionedField<vector, pointMesh>& iF,\n"
344 " const dictionary& dict\n"
346 ) << "All components of velocity have to be positive : "
348 << "Set velocity components to a great value if no clipping"
349 << " necessary." << exit(FatalError);
354 surfaceDisplacementPointPatchVectorField::
355 surfaceDisplacementPointPatchVectorField
357 const surfaceDisplacementPointPatchVectorField& ppf,
359 const DimensionedField<vector, pointMesh>& iF,
360 const PointPatchFieldMapper& mapper
363 fixedValuePointPatchVectorField(ppf, p, iF, mapper),
364 velocity_(ppf.velocity_),
365 surfacesDict_(ppf.surfacesDict_),
366 projectMode_(ppf.projectMode_),
367 projectDir_(ppf.projectDir_),
368 wedgePlane_(ppf.wedgePlane_),
369 frozenPointsZone_(ppf.frozenPointsZone_)
373 surfaceDisplacementPointPatchVectorField::
374 surfaceDisplacementPointPatchVectorField
376 const surfaceDisplacementPointPatchVectorField& ppf
379 fixedValuePointPatchVectorField(ppf),
380 velocity_(ppf.velocity_),
381 surfacesDict_(ppf.surfacesDict_),
382 projectMode_(ppf.projectMode_),
383 projectDir_(ppf.projectDir_),
384 wedgePlane_(ppf.wedgePlane_),
385 frozenPointsZone_(ppf.frozenPointsZone_)
389 surfaceDisplacementPointPatchVectorField::
390 surfaceDisplacementPointPatchVectorField
392 const surfaceDisplacementPointPatchVectorField& ppf,
393 const DimensionedField<vector, pointMesh>& iF
396 fixedValuePointPatchVectorField(ppf, iF),
397 velocity_(ppf.velocity_),
398 surfacesDict_(ppf.surfacesDict_),
399 projectMode_(ppf.projectMode_),
400 projectDir_(ppf.projectDir_),
401 wedgePlane_(ppf.wedgePlane_),
402 frozenPointsZone_(ppf.frozenPointsZone_)
406 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
408 const searchableSurfaces&
409 surfaceDisplacementPointPatchVectorField::surfaces() const
411 if (surfacesPtr_.empty())
415 new searchableSurfaces
420 db().time().constant(), // directory
421 "triSurface", // instance
422 db().time(), // registry
430 return surfacesPtr_();
434 void surfaceDisplacementPointPatchVectorField::updateCoeffs()
441 const polyMesh& mesh = patch().boundaryMesh().mesh()();
443 vectorField currentDisplacement = this->patchInternalField();
445 // Calculate intersections with surface w.r.t points0.
446 vectorField displacement(currentDisplacement);
447 calcProjection(displacement);
449 // offset wrt current displacement
450 vectorField offset = displacement-currentDisplacement;
452 // Clip offset to maximum displacement possible: velocity*timestep
454 const scalar deltaT = mesh.time().deltaT().value();
455 const vector clipVelocity = velocity_*deltaT;
457 forAll(displacement, i)
459 vector& d = offset[i];
461 for (direction cmpt = 0; cmpt < vector::nComponents; cmpt++)
465 d[cmpt] = max(d[cmpt], -clipVelocity[cmpt]);
469 d[cmpt] = min(d[cmpt], clipVelocity[cmpt]);
474 this->operator==(currentDisplacement+offset);
476 fixedValuePointPatchVectorField::updateCoeffs();
480 void surfaceDisplacementPointPatchVectorField::write(Ostream& os) const
482 fixedValuePointPatchVectorField::write(os);
483 os.writeKeyword("velocity") << velocity_
484 << token::END_STATEMENT << nl;
485 os.writeKeyword("geometry") << surfacesDict_
486 << token::END_STATEMENT << nl;
487 os.writeKeyword("projectMode") << projectModeNames_[projectMode_]
488 << token::END_STATEMENT << nl;
489 os.writeKeyword("projectDirection") << projectDir_
490 << token::END_STATEMENT << nl;
491 os.writeKeyword("wedgePlane") << wedgePlane_
492 << token::END_STATEMENT << nl;
493 if (frozenPointsZone_ != word::null)
495 os.writeKeyword("frozenPointsZone") << frozenPointsZone_
496 << token::END_STATEMENT << nl;
501 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
503 makePointPatchTypeField
505 fixedValuePointPatchVectorField,
506 surfaceDisplacementPointPatchVectorField
510 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
512 } // End namespace Foam
514 // ************************************************************************* //