surfaceSlipDisplacementPointPatchVectorField.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2026 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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
19  for more details.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
28 #include "Time.H"
29 #include "transformField.H"
32 
33 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37 
38 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39 
40 const NamedEnum<surfaceSlipDisplacementPointPatchVectorField::projectMode, 3>
41 surfaceSlipDisplacementPointPatchVectorField::projectModeNames_
42 {
43  "nearest",
44  "pointNormal",
45  "fixedNormal"
46 };
47 
48 
49 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
50 
51 void surfaceSlipDisplacementPointPatchVectorField::calcProjection
52 (
53  vectorField& displacement
54 ) const
55 {
56  const polyMesh& mesh = patch().mesh()();
57  const pointField& localPoints = patch().localPoints();
58  const labelList& meshPoints = patch().meshPoints();
59 
60  // const scalar deltaT = mesh.time().deltaTValue();
61 
62  // Construct large enough vector in direction of projectDir so
63  // we're guaranteed to hit something.
64 
65  //- Per point projection vector:
66  const scalar projectLen = mag(mesh.bounds().max()-mesh.bounds().min());
67 
68  // For case of fixed projection vector:
69  vector projectVec(0, 0, 0);
70  if (projectMode_ == FIXEDNORMAL)
71  {
72  vector n = projectDir_/mag(projectDir_);
73  projectVec = projectLen*n;
74  }
75 
76 
77  // Get fixed points (bit of a hack)
78  const pointZone* zonePtr = nullptr;
79 
80  if (frozenPointsZone_.size() > 0)
81  {
82  const pointZoneList& pZones = mesh.pointZones();
83 
84  zonePtr = &pZones[frozenPointsZone_];
85 
86  Pout<< "surfaceSlipDisplacementPointPatchVectorField : Fixing all "
87  << zonePtr->size() << " points in pointZone " << zonePtr->name()
88  << endl;
89  }
90 
91  // Get the starting locations from the pointMeshMover
92  const pointField& points0 =
93  refCast<const pointMeshMovers::displacement>
94  (refCast<const fvMesh>(mesh).mover()).points0();
95 
96  pointField start(meshPoints.size());
97  forAll(start, i)
98  {
99  start[i] = points0[meshPoints[i]] + displacement[i];
100  }
101 
102  label nNotProjected = 0;
103 
104  if (projectMode_ == NEAREST)
105  {
106  List<pointIndexHit> nearest;
107  labelList hitSurfaces;
109  (
110  start,
111  scalarField(start.size(), sqr(projectLen)),
112  hitSurfaces,
113  nearest
114  );
115 
116  forAll(nearest, i)
117  {
118  if (zonePtr && (zonePtr->localIndex(meshPoints[i]) >= 0))
119  {
120  // Fixed point. Reset to point0 location.
121  displacement[i] = points0[meshPoints[i]] - localPoints[i];
122  }
123  else if (nearest[i].hit())
124  {
125  displacement[i] =
126  nearest[i].hitPoint()
127  - points0[meshPoints[i]];
128  }
129  else
130  {
131  nNotProjected++;
132 
133  if (debug)
134  {
135  Pout<< " point:" << meshPoints[i]
136  << " coord:" << localPoints[i]
137  << " did not find any surface within " << projectLen
138  << endl;
139  }
140  }
141  }
142  }
143  else
144  {
145  // Do tests on all points. Combine later on.
146 
147  // 1. Check if already on surface
148  List<pointIndexHit> nearest;
149  {
150  labelList nearestSurface;
152  (
153  start,
154  scalarField(start.size(), sqr(small)),
155  nearestSurface,
156  nearest
157  );
158  }
159 
160  // 2. intersection. (combined later on with information from nearest
161  // above)
162  vectorField projectVecs(start.size(), projectVec);
163 
164  if (projectMode_ == POINTNORMAL)
165  {
166  projectVecs = projectLen*patch().pointNormals();
167  }
168 
169  // Knock out any wedge component
170  scalarField offset(start.size(), 0.0);
171  if (wedgePlane_ >= 0 && wedgePlane_ < vector::nComponents)
172  {
173  forAll(offset, i)
174  {
175  offset[i] = start[i][wedgePlane_];
176  start[i][wedgePlane_] = 0;
177  projectVecs[i][wedgePlane_] = 0;
178  }
179  }
180 
181  List<pointIndexHit> rightHit;
182  {
183  labelList rightSurf;
185  (
186  start,
187  start+projectVecs,
188  rightSurf,
189  rightHit
190  );
191  }
192 
193  List<pointIndexHit> leftHit;
194  {
195  labelList leftSurf;
197  (
198  start,
199  start-projectVecs,
200  leftSurf,
201  leftHit
202  );
203  }
204 
205  // 3. Choose either -fixed, nearest, right, left.
206  forAll(displacement, i)
207  {
208  if (zonePtr && (zonePtr->localIndex(meshPoints[i]) >= 0))
209  {
210  // Fixed point. Reset to point0 location.
211  displacement[i] = points0[meshPoints[i]] - localPoints[i];
212  }
213  else if (nearest[i].hit())
214  {
215  // Found nearest.
216  displacement[i] =
217  nearest[i].hitPoint()
218  - points0[meshPoints[i]];
219  }
220  else
221  {
222  pointIndexHit interPt;
223 
224  if (rightHit[i].hit())
225  {
226  if (leftHit[i].hit())
227  {
228  if
229  (
230  magSqr(rightHit[i].hitPoint()-start[i])
231  < magSqr(leftHit[i].hitPoint()-start[i])
232  )
233  {
234  interPt = rightHit[i];
235  }
236  else
237  {
238  interPt = leftHit[i];
239  }
240  }
241  else
242  {
243  interPt = rightHit[i];
244  }
245  }
246  else
247  {
248  if (leftHit[i].hit())
249  {
250  interPt = leftHit[i];
251  }
252  }
253 
254 
255  if (interPt.hit())
256  {
257  if (wedgePlane_ >= 0 && wedgePlane_ < vector::nComponents)
258  {
259  interPt.rawPoint()[wedgePlane_] += offset[i];
260  }
261  displacement[i] = interPt.rawPoint()-points0[meshPoints[i]];
262  }
263  else
264  {
265  nNotProjected++;
266 
267  if (debug)
268  {
269  Pout<< " point:" << meshPoints[i]
270  << " coord:" << localPoints[i]
271  << " did not find any intersection between"
272  << " ray from " << start[i]-projectVecs[i]
273  << " to " << start[i]+projectVecs[i] << endl;
274  }
275  }
276  }
277  }
278  }
279 
280  reduce(nNotProjected, sumOp<label>());
281 
282  if (nNotProjected > 0)
283  {
284  Info<< "surfaceSlipDisplacement :"
285  << " on patch " << patch().name()
286  << " did not project " << nNotProjected
287  << " out of " << returnReduce(localPoints.size(), sumOp<label>())
288  << " points." << endl;
289  }
290 }
291 
292 
293 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
294 
297 (
298  const pointPatch& p,
300  const dictionary& dict
301 )
302 :
304  surfacesDict_(dict.subDict("geometry")),
305  projectMode_(projectModeNames_.read(dict.lookup("projectMode"))),
306  projectDir_(dict.lookup<vector>("projectDirection", dimless)),
307  wedgePlane_(dict.lookupOrDefault("wedgePlane", -1)),
308  frozenPointsZone_(dict.lookupOrDefault("frozenPointsZone", word::null))
309 {}
310 
311 
314 (
316  const pointPatch& p,
318  const fieldMapper&
319 )
320 :
322  surfacesDict_(ppf.surfacesDict_),
323  projectMode_(ppf.projectMode_),
324  projectDir_(ppf.projectDir_),
325  wedgePlane_(ppf.wedgePlane_),
326  frozenPointsZone_(ppf.frozenPointsZone_)
327 {}
328 
329 
332 (
335 )
336 :
337  pointPatchVectorField(ppf, iF),
338  surfacesDict_(ppf.surfacesDict_),
339  projectMode_(ppf.projectMode_),
340  projectDir_(ppf.projectDir_),
341  wedgePlane_(ppf.wedgePlane_),
342  frozenPointsZone_(ppf.frozenPointsZone_)
343 {}
344 
345 
346 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
347 
350 {
351  if (surfacesPtr_.empty())
352  {
353  surfacesPtr_.reset
354  (
356  (
357  IOobject
358  (
359  "abc", // dummy name
360  time().constant(),
362  time(),
365  ),
366  surfacesDict_,
367  true // use single region naming shortcut
368  )
369  );
370  }
371  return surfacesPtr_();
372 }
373 
374 
376 (
377  const Pstream::commsTypes commsType
378 )
379 {
380  vectorField displacement(this->patchInternalField());
381 
382  // Calculate displacement to project points onto surface
383  calcProjection(displacement);
384 
385  // Get internal field to insert values into
386  Field<vector>& iF = const_cast<Field<vector>&>(this->primitiveField());
387 
388  // setInternalField(iF, motionU);
389  setInternalField(iF, displacement);
390 
392 }
393 
394 
396 {
398  writeEntry(os, "geometry", surfacesDict_);
399  writeEntry(os, "projectMode", projectModeNames_[projectMode_]);
400  writeEntry(os, "projectDirection", projectDir_);
401  writeEntry(os, "wedgePlane", wedgePlane_);
402  if (frozenPointsZone_ != word::null)
403  {
404  writeEntry(os, "frozenPointsZone", frozenPointsZone_);
405  }
406 }
407 
408 
409 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
410 
412 (
415 );
416 
417 
418 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
419 
420 } // End namespace Foam
421 
422 // ************************************************************************* //
label n
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
Macros for easy insertion into run-time selection tables.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
virtual const fileName & name() const
Return the name of the stream.
Definition: OSstream.H:85
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
commsTypes
Types of communications.
Definition: UPstream.H:65
static const direction nComponents
Number of components in this vector space.
Definition: VectorSpace.H:105
const point & min() const
Minimum point defining the bounding box.
Definition: boundBoxI.H:88
const point & max() const
Maximum point defining the bounding box.
Definition: boundBoxI.H:94
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
Abstract base class for field mapping.
Definition: fieldMapper.H:48
Motion of the mesh specified as a list of pointMeshMovers.
Abstract base class for point-mesh patch fields.
virtual void evaluate(const Pstream::commsTypes commsType=Pstream::commsTypes::blocking)
Evaluate the patch field.
const Time & time() const
Return time.
virtual void write(Ostream &) const
Write.
tmp< Field< Type > > patchInternalField() const
Return field created from appropriate internal field values.
const Field< Type > & primitiveField() const
Return internal field reference.
const pointPatch & patch() const
Return patch.
void setInternalField(Field< Type1 > &iF, const Field< Type1 > &pF, const labelList &meshPoints) const
Given the internal field and a patch field,.
Basic pointPatch represents a set of points from the mesh.
Definition: pointPatch.H:61
virtual const word & name() const =0
Return name.
virtual const vectorField & pointNormals() const =0
Return point normals.
virtual const labelList & meshPoints() const =0
Return mesh points.
virtual const vectorField & localPoints() const =0
Return mesh points.
const pointMesh & mesh() const
Return mesh reference.
Definition: pointPatch.C:51
const pointZoneList & pointZones() const
Return point zones.
Definition: polyMesh.H:426
const boundBox & bounds() const
Return mesh bounding box.
Definition: polyMesh.H:399
Container for searchableSurfaces.
void findAnyIntersection(const pointField &start, const pointField &end, labelList &surfaces, List< pointIndexHit > &) const
Find any intersection. Return hit point information and.
void findNearest(const pointField &, const scalarField &nearestDistSqr, labelList &surfaces, List< pointIndexHit > &) const
Find nearest. Return -1 (and a miss()) or surface and nearest.
static const word & geometryDir()
Return the geometry directory name.
Displacement follows a triSurface. Use in a pointMeshMovers::displacement as a bc on the pointDisplac...
const searchableSurfaceList & surfaces() const
Surface to follow. Demand loads surfaceNames.
virtual void evaluate(const Pstream::commsTypes commsType=Pstream::commsTypes::blocking)
Update the patch field.
surfaceSlipDisplacementPointPatchVectorField(const pointPatch &, const DimensionedField< vector, pointMesh > &, const dictionary &)
Construct from patch, internal field and dictionary.
A class for handling words, derived from string.
Definition: word.H:63
static const word null
An empty word.
Definition: word.H:78
IOporosityModelList pZones(mesh)
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
const unitSet & lookup(const word &unitName)
Lookup and return the named unit from the table.
Definition: units.C:346
Namespace for OpenFOAM.
makePointPatchTypeField(pointPatchVectorField, angularOscillatingDisplacementPointPatchVectorField)
const dimensionSet & dimless
Definition: dimensions.C:138
bool read(const char *, int32_t &)
Definition: int32IO.C:85
List< label > labelList
A List of labels.
Definition: labelList.H:56
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
PointIndexHit< point > pointIndexHit
Definition: pointIndexHit.H:42
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
messageStream Info
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
tmp< DimensionedField< typename outerProduct< Type, Type >::type, GeoMesh, Field >> sqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:49
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Field< vector > vectorField
Specialisation of Field<T> for vector.
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
tmp< DimensionedField< scalar, GeoMesh, Field > > mag(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
void offset(label &lst, const label o)
tmp< DimensionedField< scalar, GeoMesh, Field > > magSqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
void writeEntry(Ostream &os, const word &key, const DimensionedFieldFunction< DimensionedFieldType > &f)
dictionary dict
volScalarField & p
Spatial transformation functions for primitive fields.