Loading...
Searching...
No Matches
edgeSlipDisplacementPointPatchVectorField.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) 2024 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
30#include "Time.H"
31#include "transformField.H"
33#include "featureEdgeMesh.H"
34
35// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
36
38(
39 const objectRegistry& obr,
40 const dictionary& dict
41)
42{
43 const Time& tm = obr.time();
44
45 const fileName featFileName(dict.get<fileName>("file", keyType::LITERAL));
46
47 if (tm.foundObject<edgeMesh>(featFileName))
48 {
49 return;
50 }
51
52 IOobject extFeatObj
53 (
54 featFileName, // name
55 tm.constant(), // instance
56 "extendedFeatureEdgeMesh", // local
57 obr, // registry
61 );
62
63 //const fileName fName(typeFilePath<extendedFeatureEdgeMesh>(extFeatObj));
64 const fileName fName(extFeatObj.typeFilePath<extendedFeatureEdgeMesh>());
65
66 if (!fName.empty() && extendedEdgeMesh::canRead(fName))
67 {
68 Info<< "Reading edgeMesh from " << extFeatObj.objectRelPath() << endl;
69 auto* eMeshPtr = new extendedFeatureEdgeMesh(extFeatObj);
70 eMeshPtr->store();
71 }
72 else
73 {
74 // Try reading as edgeMesh
75
76 IOobject featObj
77 (
78 featFileName, // name
79 tm.constant(), // instance
80 "triSurface", // local
81 obr, // registry
85 );
86
87 Info<< "Reading edgeMesh from " << featObj.objectRelPath() << endl;
88 const fileName fName(featObj.typeFilePath<featureEdgeMesh>());
89
90 if (fName.empty())
91 {
93 << "Could not open " << featObj.objectPath()
95 }
96
97 // Read as edgeMesh
98 auto* eMeshPtr = new featureEdgeMesh(featObj);
99 eMeshPtr->store();
100 }
101}
102
103
104void Foam::edgeSlipDisplacementPointPatchVectorField::calcProjection
105(
106 vectorField& displacement
107) const
108{
109 const polyMesh& mesh = patch().boundaryMesh().mesh()();
110 const labelList& meshPoints = patch().meshPoints();
111
112 //const scalar deltaT = mesh.time().deltaTValue();
113
114 // Construct large enough vector in direction of projectDir so
115 // we're guaranteed to hit something.
116
117 //- Per point projection vector:
118 const scalar projectLen = mesh.bounds().mag();
119
120
121
122 // Get fixed points (bit of a hack)
123 const pointZone* zonePtr = nullptr;
124
125 if (frozenPointsZone_.size() > 0)
126 {
127 const pointZoneMesh& pZones = mesh.pointZones();
128
129 zonePtr = &pZones[frozenPointsZone_];
130
131 Info<< "edgeSlipDisplacementPointPatchVectorField : Fixing all "
132 << zonePtr->size() << " points in pointZone " << zonePtr->name()
133 << endl;
134 }
135
136 // Get the starting locations from the motionSolver
137 const pointField& points0 = mesh.lookupObject<displacementMotionSolver>
138 (
139 "dynamicMeshDict"
140 ).points0();
141
142
143 pointField start(meshPoints.size());
144 forAll(start, i)
145 {
146 start[i] = points0[meshPoints[i]] + displacement[i];
147 }
148
149 const auto& tree = edgeTree();
150
151 label nNotProjected = 0;
152 forAll(meshPoints, i)
153 {
154 const label meshPointi = meshPoints[i];
155 const point& pt = mesh.points()[meshPointi];
156
157 if (zonePtr && (zonePtr->whichPoint(meshPointi) >= 0))
158 {
159 // Fixed point. Reset to point0 location.
160 displacement[i] = points0[meshPointi] - pt;
161 }
162 else
163 {
164 pointIndexHit nearest = tree.findNearest(start[i], sqr(projectLen));
165 if (nearest.hit())
166 {
167 displacement[i] = nearest.point() - points0[meshPointi];
168 }
169 else
170 {
171 nNotProjected++;
172
173 if (debug)
174 {
175 Pout<< " point:" << meshPointi
176 << " coord:" << pt
177 << " did not find any surface within " << projectLen
178 << endl;
179 }
180 }
181 }
182 }
183
184 reduce(nNotProjected, sumOp<label>());
185
186 if (nNotProjected > 0)
187 {
188 Info<< "edgeSlipDisplacement :"
189 << " on patch " << patch().name()
190 << " did not project " << nNotProjected
191 << " out of " << returnReduce(meshPoints.size(), sumOp<label>())
192 << " points." << endl;
193 }
195
196
197// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
198
201(
202 const pointPatch& p,
204)
205:
207 velocity_(Zero)
208{}
209
210
213(
214 const pointPatch& p,
216 const dictionary& dict
217)
218:
220 velocity_(dict.get<vector>("velocity")),
221 featFileName_(dict.get<fileName>("file", keyType::LITERAL)),
222 frozenPointsZone_(dict.getOrDefault("frozenPointsZone", word::null))
238 velocity_(ppf.velocity_),
239 featFileName_(ppf.featFileName_),
240 frozenPointsZone_(ppf.frozenPointsZone_)
241{}
242
243
246(
248)
249:
251 velocity_(ppf.velocity_),
252 featFileName_(ppf.featFileName_),
253 frozenPointsZone_(ppf.frozenPointsZone_)
254{}
255
256
259(
262)
263:
264 pointPatchVectorField(ppf, iF),
265 velocity_(ppf.velocity_),
266 featFileName_(ppf.featFileName_),
267 frozenPointsZone_(ppf.frozenPointsZone_)
268{}
270
271// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
272
275{
276 if (!edgeTreePtr_)
277 {
278 const Time& tm = this->patch().boundaryMesh().mesh().time();
279 const auto& eMesh = tm.lookupObject<edgeMesh>(featFileName_);
280
281 const pointField& points = eMesh.points();
282 const edgeList& edges = eMesh.edges();
283
284 // Calculate bb of all points
286
287 // Random number generator. Bit dodgy since not exactly random ;-)
288 Random rndGen(65431);
289
290 // Slightly extended bb. Slightly off-centred just so on symmetric
291 // geometry there are less face/edge aligned items.
292 bb.inflate(rndGen, 1e-4, ROOTVSMALL);
293
294 edgeTreePtr_.reset
295 (
297 (
298 treeDataEdge(edges, points), // All edges
299
300 bb, // overall search domain
301 8, // maxLevel
302 10, // leafsize
303 3.0 // duplicity
304 )
305 );
306 }
308 return edgeTreePtr_();
309}
310
311
313{
314 if (this->updated())
315 {
316 return;
317 }
318
319 const vectorField currentDisplacement(this->patchInternalField());
320
321 // Calculate displacement to project points onto surface
322 vectorField displacement(currentDisplacement);
323 calcProjection(displacement);
324
325
326 // offset wrt current displacement
327 vectorField offset(displacement-currentDisplacement);
328
329 // Clip offset to maximum displacement possible: velocity*timestep
330
331 const Time& tm = this->patch().boundaryMesh().mesh().time();
332 const scalar deltaT = tm.deltaTValue();
333 const vector clipVelocity = velocity_*deltaT;
334
335 forAll(displacement, i)
336 {
337 vector& d = offset[i];
338
339 const scalar magD(mag(d));
340 if (magD > ROOTVSMALL)
341 {
342 d /= magD;
343 d *= min(magD, mag(clipVelocity));
344 }
345 }
346
347 if (debug)
348 {
349 Pout<< type() << " :"
350 << " on patch " << patch().name()
351 << " of field " << this->internalField().name()
352 << " projection"
353 << " min:" << gMin(displacement)
354 << " max:" << gMaxMagSqr(displacement)
355 << " average:" << gAverage(displacement)
356 << endl;
357 }
358
359 // Get internal field to insert values into
360 Field<vector>& iF = const_cast<Field<vector>&>(this->primitiveField());
361
362 setInInternalField(iF, (currentDisplacement+offset)());
365}
366
367
369(
370 Ostream& os
371) const
372{
374 os.writeEntry("file", featFileName_);
375 os.writeEntryIfDifferent<word>
376 (
377 "frozenPointsZone",
379 frozenPointsZone_
380 );
381 os.writeEntry("velocity", velocity_);
382}
383
384
385// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
386
387namespace Foam
388{
389
391(
394);
395
396} // End namespace Foam
397
398// ************************************************************************* //
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...
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
Definition Field.H:172
@ REGISTER
Request registration (bool: true).
@ MUST_READ
Reading required.
@ NO_WRITE
Ignore writing from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition IOobject.H:191
fileName typeFilePath(const bool search=true) const
Call localFilePath or globalFilePath for given type depending on its is_globalIOobject trait.
fileName objectRelPath() const
The object path relative to the case.
Definition IOobject.C:581
fileName objectPath() const
The complete path + object name.
Definition IOobjectI.H:313
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
Random number generator.
Definition Random.H:56
const word & constant() const noexcept
Return constant name.
Definition TimePathsI.H:131
scalar deltaTValue() const noexcept
Return time step value.
Definition TimeStateI.H:49
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition Time.H:75
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
void inflate(const scalar factor)
Expand box by factor*mag(span) in all dimensions.
Definition boundBoxI.H:381
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
Mesh data needed to do the Finite Area discretisation.
Definition edgeFaMesh.H:50
Displacement follows an edgeMesh. Use in a displacementMotionSolver as a bc on the pointDisplacement ...
static void read(const objectRegistry &obr, const dictionary &dict)
Read (& store) geometry. Exposed so point attraction can reuse it.
edgeSlipDisplacementPointPatchVectorField(const pointPatch &, const DimensionedField< vector, pointMesh > &)
Construct from patch and internal field.
virtual void updateCoeffs()
Update the coefficients associated with the patch field.
static bool canRead(const fileName &name, bool verbose=false)
Can we read this file format?
A class for handling file names.
Definition fileName.H:75
Non-pointer based hierarchical recursive searching.
A class for handling keywords in dictionaries.
Definition keyType.H:69
@ LITERAL
String literal.
Definition keyType.H:82
Registry of regIOobjects.
bool foundObject(const word &name, const bool recursive=false) const
Contains the named Type?
const Time & time() const noexcept
Return time registry.
const Type & lookupObject(const word &name, const bool recursive=false) const
Lookup and return const reference to the object of the given Type. Fatal if not found or the wrong ty...
const pointPatch & patch() const noexcept
Return the patch.
bool updated() const noexcept
True if the boundary condition has already been updated.
Foam::pointPatchFieldMapper.
void patchInternalField(const UList< Type1 > &internalData, const labelUList &addressing, UList< Type1 > &pfld) const
void setInInternalField(Field< Type1 > &iF, const Field< Type1 > &pF, const labelUList &meshPoints) const
const Field< vector > & primitiveField() const noexcept
virtual void write(Ostream &os) const
Write.
const DimensionedField< vector, pointMesh > & internalField() const noexcept
Basic pointPatch represents a set of points from the mesh.
Definition pointPatch.H:67
A subset of mesh points.
Definition pointZone.H:64
label whichPoint(const label meshPointID) const
The local index of the given mesh point, -1 if not in the zone.
Definition pointZone.H:295
Mesh consisting of general polyhedral cells.
Definition polyMesh.H:79
virtual const pointField & points() const
Return raw points.
Definition polyMesh.C:1063
Standard boundBox with extra functionality for use in octree.
Holds data for octree to work on an edges subset.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
A class for handling words, derived from Foam::string.
Definition word.H:66
static const word null
An empty word.
Definition word.H:84
const word & name() const noexcept
The zone name.
volScalarField & p
dynamicFvMesh & mesh
IOporosityModelList pZones(mesh)
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition error.H:629
OBJstream os(runTime.globalPath()/outputName)
const pointField & points
Namespace for handling debugging switches.
Definition debug.C:45
const std::string patch
OpenFOAM patch number as a std::string.
Namespace for OpenFOAM.
List< edge > edgeList
List of edge.
Definition edgeList.H:32
Type gAverage(const FieldField< Field, Type > &f, const label comm)
The global arithmetic average of a FieldField.
ZoneMesh< pointZone, polyMesh > pointZoneMesh
A ZoneMesh with pointZone content on a polyMesh.
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition int32.H:127
List< label > labelList
A List of labels.
Definition List.H:62
dimensionedSymmTensor sqr(const dimensionedVector &dv)
messageStream Info
Information stream (stdout output on master, null elsewhere).
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition POSIX.C:801
T returnReduce(const T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
Type gMaxMagSqr(const UList< Type > &f, const label comm)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void reduce(T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce).
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:26
Field< vector > vectorField
Specialisation of Field<T> for vector.
pointPatchField< vector > pointPatchVectorField
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
vector point
Point is a vector.
Definition point.H:37
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
Type gMin(const FieldField< Field, Type > &f)
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
vectorField pointField
pointField is a vectorField.
Vector< scalar > vector
Definition vector.H:57
PointIndexHit< point > pointIndexHit
A PointIndexHit with a 3D point.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
#define makePointPatchTypeField(PatchTypeField, typePatchTypeField)
Define a concrete pointPatchField type and add to run-time tables Example, (pointPatchScalarField,...
dictionary dict
Tree tree(triangles.begin(), triangles.end())
volScalarField & e
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299
Spatial transformation functions for primitive fields.
Random rndGen
pointField points0(pointIOField(IOobject("points", mesh.time().constant(), polyMesh::meshSubDir, mesh, IOobject::MUST_READ, IOobject::NO_WRITE, IOobject::NO_REGISTER)))