surfaceDisplacementPointPatchVectorField.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
31 #include "Time.H"
32 #include "transformField.H"
33 #include "fvMesh.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 const Foam::Enum
39 <
41 >
42 Foam::surfaceDisplacementPointPatchVectorField::projectModeNames_
43 ({
44  { projectMode::NEAREST, "nearest" },
45  { projectMode::POINTNORMAL, "pointNormal" },
46  { projectMode::FIXEDNORMAL, "fixedNormal" },
47 });
48 
49 
50 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
51 
52 void Foam::surfaceDisplacementPointPatchVectorField::calcProjection
53 (
54  vectorField& displacement
55 ) const
56 {
57  const polyMesh& mesh = patch().boundaryMesh().mesh()();
58  const pointField& localPoints = patch().localPoints();
59  const labelList& meshPoints = patch().meshPoints();
60 
61  //const scalar deltaT = mesh.time().deltaTValue();
62 
63  // Construct large enough vector in direction of projectDir so
64  // we're guaranteed to hit something.
65 
66  //- Per point projection vector:
67  const scalar projectLen = mag(mesh.bounds().max()-mesh.bounds().min());
68 
69  // For case of fixed projection vector:
70  vector projectVec(Zero);
71  if (projectMode_ == FIXEDNORMAL)
72  {
73  vector n = projectDir_/mag(projectDir_);
74  projectVec = projectLen*n;
75  }
76 
77 
78  // Get fixed points (bit of a hack)
79  const pointZone* zonePtr = nullptr;
80 
81  if (frozenPointsZone_.size() > 0)
82  {
83  const pointZoneMesh& pZones = mesh.pointZones();
84 
85  zonePtr = &pZones[frozenPointsZone_];
86 
87  Pout<< "surfaceDisplacementPointPatchVectorField : Fixing all "
88  << zonePtr->size() << " points in pointZone " << zonePtr->name()
89  << endl;
90  }
91 
92  // Get the starting locations from the motionSolver
93  const pointField& points0 = mesh.lookupObject<displacementMotionSolver>
94  (
95  "dynamicMeshDict"
96  ).points0();
97 
98 
99  pointField start(meshPoints.size());
100  forAll(start, i)
101  {
102  start[i] = points0[meshPoints[i]] + displacement[i];
103  }
104 
105  label nNotProjected = 0;
106 
107  if (projectMode_ == NEAREST)
108  {
109  List<pointIndexHit> nearest;
110  labelList hitSurfaces;
112  (
113  start,
114  scalarField(start.size(), sqr(projectLen)),
115  hitSurfaces,
116  nearest
117  );
118 
119  forAll(nearest, i)
120  {
121  if (zonePtr && (zonePtr->whichPoint(meshPoints[i]) >= 0))
122  {
123  // Fixed point. Reset to point0 location.
124  displacement[i] = points0[meshPoints[i]] - localPoints[i];
125  }
126  else if (nearest[i].hit())
127  {
128  displacement[i] =
129  nearest[i].hitPoint()
130  - points0[meshPoints[i]];
131  }
132  else
133  {
134  nNotProjected++;
135 
136  if (debug)
137  {
138  Pout<< " point:" << meshPoints[i]
139  << " coord:" << localPoints[i]
140  << " did not find any surface within " << projectLen
141  << endl;
142  }
143  }
144  }
145  }
146  else
147  {
148  // Do tests on all points. Combine later on.
149 
150  // 1. Check if already on surface
151  List<pointIndexHit> nearest;
152  {
153  labelList nearestSurface;
155  (
156  start,
157  scalarField(start.size(), sqr(SMALL)),
158  nearestSurface,
159  nearest
160  );
161  }
162 
163  // 2. intersection. (combined later on with information from nearest
164  // above)
165  vectorField projectVecs(start.size(), projectVec);
166 
167  if (projectMode_ == POINTNORMAL)
168  {
169  projectVecs = projectLen*patch().pointNormals();
170  }
171 
172  // Knock out any wedge component
173  scalarField offset(start.size(), Zero);
174  if (wedgePlane_ >= 0 && wedgePlane_ <= vector::nComponents)
175  {
176  forAll(offset, i)
177  {
178  offset[i] = start[i][wedgePlane_];
179  start[i][wedgePlane_] = 0;
180  projectVecs[i][wedgePlane_] = 0;
181  }
182  }
183 
184  List<pointIndexHit> rightHit;
185  {
186  labelList rightSurf;
188  (
189  start,
190  start+projectVecs,
191  rightSurf,
192  rightHit
193  );
194  }
195 
196  List<pointIndexHit> leftHit;
197  {
198  labelList leftSurf;
200  (
201  start,
202  start-projectVecs,
203  leftSurf,
204  leftHit
205  );
206  }
207 
208  // 3. Choose either -fixed, nearest, right, left.
209  forAll(displacement, i)
210  {
211  if (zonePtr && (zonePtr->whichPoint(meshPoints[i]) >= 0))
212  {
213  // Fixed point. Reset to point0 location.
214  displacement[i] = points0[meshPoints[i]] - localPoints[i];
215  }
216  else if (nearest[i].hit())
217  {
218  // Found nearest.
219  displacement[i] =
220  nearest[i].hitPoint()
221  - points0[meshPoints[i]];
222  }
223  else
224  {
225  pointIndexHit interPt;
226 
227  if (rightHit[i].hit())
228  {
229  if (leftHit[i].hit())
230  {
231  if
232  (
233  magSqr(rightHit[i].hitPoint()-start[i])
234  < magSqr(leftHit[i].hitPoint()-start[i])
235  )
236  {
237  interPt = rightHit[i];
238  }
239  else
240  {
241  interPt = leftHit[i];
242  }
243  }
244  else
245  {
246  interPt = rightHit[i];
247  }
248  }
249  else
250  {
251  if (leftHit[i].hit())
252  {
253  interPt = leftHit[i];
254  }
255  }
256 
257 
258  if (interPt.hit())
259  {
260  if (wedgePlane_ >= 0 && wedgePlane_ <= vector::nComponents)
261  {
262  interPt.rawPoint()[wedgePlane_] += offset[i];
263  }
264  displacement[i] = interPt.rawPoint()-points0[meshPoints[i]];
265  }
266  else
267  {
268  nNotProjected++;
269 
270  if (debug)
271  {
272  Pout<< " point:" << meshPoints[i]
273  << " coord:" << localPoints[i]
274  << " did not find any intersection between"
275  << " ray from " << start[i]-projectVecs[i]
276  << " to " << start[i]+projectVecs[i] << endl;
277  }
278  }
279  }
280  }
281  }
282 
283  reduce(nNotProjected, sumOp<label>());
284 
285  if (nNotProjected > 0)
286  {
287  Info<< "surfaceDisplacement :"
288  << " on patch " << patch().name()
289  << " did not project " << nNotProjected
290  << " out of " << returnReduce(localPoints.size(), sumOp<label>())
291  << " points." << endl;
292  }
293 }
294 
295 
296 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
297 
300 (
301  const pointPatch& p,
303 )
304 :
305  fixedValuePointPatchVectorField(p, iF),
306  velocity_(Zero),
307  projectMode_(NEAREST),
308  projectDir_(Zero),
309  wedgePlane_(-1)
310 {}
311 
312 
315 (
316  const pointPatch& p,
318  const dictionary& dict
319 )
320 :
321  fixedValuePointPatchVectorField(p, iF, dict),
322  velocity_(dict.get<vector>("velocity")),
323  surfacesDict_(dict.subDict("geometry")),
324  projectMode_(projectModeNames_.get("projectMode", dict)),
325  projectDir_(dict.get<vector>("projectDirection")),
326  wedgePlane_(dict.getOrDefault("wedgePlane", -1)),
327  frozenPointsZone_(dict.getOrDefault("frozenPointsZone", word::null))
328 {
329  if (velocity_.x() < 0 || velocity_.y() < 0 || velocity_.z() < 0)
330  {
332  << "All components of velocity have to be positive : "
333  << velocity_ << nl
334  << "Set velocity components to a great value if no clipping"
335  << " necessary." << exit(FatalError);
336  }
337 }
338 
339 
342 (
344  const pointPatch& p,
346  const pointPatchFieldMapper& mapper
347 )
348 :
349  fixedValuePointPatchVectorField(ppf, p, iF, mapper),
350  velocity_(ppf.velocity_),
351  surfacesDict_(ppf.surfacesDict_),
352  projectMode_(ppf.projectMode_),
353  projectDir_(ppf.projectDir_),
354  wedgePlane_(ppf.wedgePlane_),
355  frozenPointsZone_(ppf.frozenPointsZone_)
356 {}
357 
358 
361 (
363 )
364 :
365  fixedValuePointPatchVectorField(ppf),
366  velocity_(ppf.velocity_),
367  surfacesDict_(ppf.surfacesDict_),
368  projectMode_(ppf.projectMode_),
369  projectDir_(ppf.projectDir_),
370  wedgePlane_(ppf.wedgePlane_),
371  frozenPointsZone_(ppf.frozenPointsZone_)
372 {}
373 
374 
377 (
380 )
381 :
382  fixedValuePointPatchVectorField(ppf, iF),
383  velocity_(ppf.velocity_),
384  surfacesDict_(ppf.surfacesDict_),
385  projectMode_(ppf.projectMode_),
386  projectDir_(ppf.projectDir_),
387  wedgePlane_(ppf.wedgePlane_),
388  frozenPointsZone_(ppf.frozenPointsZone_)
389 {}
390 
391 
392 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
393 
396 {
397  if (!surfacesPtr_)
398  {
399  surfacesPtr_.reset
400  (
402  (
403  IOobject
404  (
405  "abc", // dummy name
406  db().time().constant(), // directory
407  "triSurface", // instance
408  db().time(), // registry
411  ),
412  surfacesDict_,
413  true // allow single-region shortcut
414  )
415  );
416  }
417 
418  return *surfacesPtr_;
419 }
420 
421 
423 {
424  if (this->updated())
425  {
426  return;
427  }
428 
429  const polyMesh& mesh = patch().boundaryMesh().mesh()();
430 
431  vectorField currentDisplacement(this->patchInternalField());
432 
433  // Calculate intersections with surface w.r.t points0.
434  vectorField displacement(currentDisplacement);
435  calcProjection(displacement);
436 
437  // offset wrt current displacement
438  vectorField offset(displacement-currentDisplacement);
439 
440  // Clip offset to maximum displacement possible: velocity*timestep
441 
442  const scalar deltaT = mesh.time().deltaTValue();
443  const vector clipVelocity = velocity_*deltaT;
444 
445  forAll(displacement, i)
446  {
447  vector& d = offset[i];
448 
449  for (direction cmpt = 0; cmpt < vector::nComponents; cmpt++)
450  {
451  if (d[cmpt] < 0)
452  {
453  d[cmpt] = max(d[cmpt], -clipVelocity[cmpt]);
454  }
455  else
456  {
457  d[cmpt] = min(d[cmpt], clipVelocity[cmpt]);
458  }
459  }
460  }
461 
462  this->operator==(currentDisplacement+offset);
463 
464  fixedValuePointPatchVectorField::updateCoeffs();
465 }
466 
467 
469 {
471  os.writeEntry("velocity", velocity_);
472  os.writeEntry("geometry", surfacesDict_);
473  os.writeEntry("projectMode", projectModeNames_[projectMode_]);
474  os.writeEntry("projectDirection", projectDir_);
475  os.writeEntry("wedgePlane", wedgePlane_);
476 
478  (
479  "frozenPointsZone",
480  word::null,
481  frozenPointsZone_
482  );
483 }
484 
485 
486 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
487 
488 namespace Foam
489 {
490 
492 (
493  fixedValuePointPatchVectorField,
495 );
496 
497 } // End namespace Foam
498 
499 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::surfaceDisplacementPointPatchVectorField::surfaceDisplacementPointPatchVectorField
surfaceDisplacementPointPatchVectorField(const pointPatch &, const DimensionedField< vector, pointMesh > &)
Construct from patch and internal field.
Definition: surfaceDisplacementPointPatchVectorField.C:300
Foam::IOobject::NO_WRITE
Definition: IOobject.H:195
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Foam::Ostream::writeEntryIfDifferent
Ostream & writeEntryIfDifferent(const word &key, const T &value1, const T &value2)
Write a keyword/value entry only when the two values differ.
Definition: Ostream.H:248
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:52
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::surfaceDisplacementPointPatchVectorField::projectMode
projectMode
Definition: surfaceDisplacementPointPatchVectorField.H:85
Foam::Enum
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: IOstreamOption.H:57
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
Foam::surfaceDisplacementPointPatchVectorField::updateCoeffs
virtual void updateCoeffs()
Update the coefficients associated with the patch field.
Definition: surfaceDisplacementPointPatchVectorField.C:422
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::dictionary::get
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:107
Foam::pointPatch
Basic pointPatch represents a set of points from the mesh.
Definition: pointPatch.H:58
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Foam::pointZoneMesh
ZoneMesh< pointZone, polyMesh > pointZoneMesh
A ZoneMesh with the type pointZone.
Definition: pointZoneMeshFwd.H:44
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
transformField.H
Spatial transformation functions for primitive fields.
Foam::pointPatchFieldMapper
Foam::pointPatchFieldMapper.
Definition: pointPatchFieldMapper.H:48
Foam::TimeState::deltaTValue
scalar deltaTValue() const noexcept
Return time step value.
Definition: TimeStateI.H:43
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::vectorField
Field< vector > vectorField
Specialisation of Field<T> for vector.
Definition: primitiveFieldsFwd.H:54
Foam::magSqr
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
pZones
IOporosityModelList pZones(mesh)
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::searchableSurfaces::findAnyIntersection
void findAnyIntersection(const pointField &start, const pointField &end, labelList &surfaces, List< pointIndexHit > &) const
Find any intersection. Return hit point information and.
Definition: searchableSurfaces.C:331
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:51
Foam::makePointPatchTypeField
makePointPatchTypeField(pointPatchVectorField, solidBodyMotionDisplacementPointPatchVectorField)
Foam::Field< vector >
Foam::operator==
tmp< faMatrix< Type > > operator==(const faMatrix< Type > &, const faMatrix< Type > &)
Foam::searchableSurfaces::findNearest
void findNearest(const pointField &, const scalarField &nearestDistSqr, labelList &surfaces, List< pointIndexHit > &) const
Find nearest. Return -1 (and a miss()) or surface and nearest.
Definition: searchableSurfaces.C:396
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::OSstream::name
virtual const fileName & name() const
Get the name of the stream.
Definition: OSstream.H:107
surfaceDisplacementPointPatchVectorField.H
Foam::surfaceDisplacementPointPatchVectorField::NEAREST
Definition: surfaceDisplacementPointPatchVectorField.H:87
Foam::dictionary::subDict
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition: dictionary.C:460
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
os
OBJstream os(runTime.globalPath()/outputName)
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
fvMesh.H
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
displacementMotionSolver.H
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::surfaceDisplacementPointPatchVectorField::FIXEDNORMAL
Definition: surfaceDisplacementPointPatchVectorField.H:89
Time.H
points0
pointField points0(pointIOField(IOobject("points", mesh.time().constant(), polyMesh::meshSubDir, mesh, IOobject::MUST_READ, IOobject::NO_WRITE, false)))
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::sqr
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Definition: dimensionedSymmTensor.C:51
Foam::pointIndexHit
PointIndexHit< point > pointIndexHit
A PointIndexHit for 3D points.
Definition: pointIndexHit.H:46
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::foamVersion::patch
const std::string patch
OpenFOAM patch number as a std::string.
Foam::Vector< scalar >
Foam::searchableSurfaces
Container for searchableSurfaces. The collection is specified as a dictionary. For example,...
Definition: searchableSurfaces.H:92
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::direction
uint8_t direction
Definition: direction.H:52
Foam::word::null
static const word null
An empty word.
Definition: word.H:80
Foam::Ostream::writeEntry
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:236
Foam::vtk::write
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
Definition: foamVtkOutputTemplates.C:36
Foam::fvMesh::time
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:280
Foam::surfaceDisplacementPointPatchVectorField
Displacement fixed by projection onto triSurface. Use in a displacementMotionSolver as a bc on the po...
Definition: surfaceDisplacementPointPatchVectorField.H:76
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::surfaceDisplacementPointPatchVectorField::POINTNORMAL
Definition: surfaceDisplacementPointPatchVectorField.H:88
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:148
constant
constant condensation/saturation model.
Foam::VectorSpace< Vector< scalar >, scalar, 3 >::nComponents
static constexpr direction nComponents
Number of components in this vector space.
Definition: VectorSpace.H:101
Foam::surfaceDisplacementPointPatchVectorField::surfaces
const searchableSurfaces & surfaces() const
Surface to follow. Demand loads surfaceNames.
Definition: surfaceDisplacementPointPatchVectorField.C:395
Foam::DimensionedField
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Definition: DimensionedField.H:54
Foam::IOobject::MUST_READ
Definition: IOobject.H:185
Foam::surfaceDisplacementPointPatchVectorField::write
virtual void write(Ostream &) const
Write.
Definition: surfaceDisplacementPointPatchVectorField.C:468