movingObject.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) 2024-2025 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 
26 #include "multiValveEngine.H"
27 #include "pointConstraints.H"
28 #include "syncTools.H"
29 
30 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
31 
33 (
34  const pointMesh& pMesh,
35  const scalarField& pDistMoving,
36  const scalarField& pDistStatic,
37  scalar dMoving,
38  scalar dMax,
39  scalar dStatic
40 )
41 {
43 
44  forAll(scale, pi)
45  {
46  // If original dMoving and dStatic regions overlay set to zero.
47  // This may happen when e.g. valve-piston distance becomes small.
48  if
49  (
50  ((pDistMoving[pi] - dMoving) <= 0) &&
51  ((pDistStatic[pi] - dStatic) <= 0)
52  )
53  {
54  dMoving = 0;
55  dStatic = 0;
56  }
57 
58  // - Near static patches
59  if (pDistStatic[pi] - dStatic <= 0)
60  {
61  scale[pi] = 0;
62  }
63  // - Near object
64  else if (pDistMoving[pi] - dMoving <= 0)
65  {
66  scale[pi] = 1;
67  }
68  // - Outside outer boundary
69  else if (dMax - pDistMoving[pi] <= 0)
70  {
71  scale[pi] = 0;
72  }
73  // Linear scaling from the moving patch:
74  // patch->dMoving: 1
75  // dMoving->min(dMax, min(dStatic - dh, dFrozenZone)): linear 1->0
76  else
77  {
78  const scalar d1 = pDistMoving[pi] - dMoving;
79  const scalar d2 = min
80  (
81  dMax - pDistMoving[pi],
82  pDistStatic[pi] - dStatic
83  );
84  scale[pi] = 1 - d1/(d1 + d2 + rootVSmall);
85  }
86  }
87 
88  // Apply optional cosine scaling to the point motion
89  if (cosineScale_ > 0)
90  {
91  scale =
92  cosineScale_ *
93  min
94  (
95  max
96  (
97  0.5
98  - 0.5
100  scalar(0)
101  ),
102  scalar(1)
103  )
104  + (1 - cosineScale_) * scale_.primitiveField();
105  }
106 
108 
109  if (debug)
110  {
111  scale_.write();
112  }
113 }
114 
115 
117 (
118  pointField& newPoints,
119  const vector& translationVector
120 )
121 {
122  // Explicit filtering of displacement to avoid pointMesh looping
123  if (mag(translationVector) < small)
124  {
125  executionCount_++;
126  return;
127  }
128 
129  forAll(newPoints, pi)
130  {
131  const point displacementVector = scale_[pi]*translationVector;
132  if (mag(displacementVector) > small)
133  {
134  newPoints[pi] += displacementVector;
135  }
136  }
137 
138  executionCount_++;
139 }
140 
141 
143 {
144  staticPatchSet_.clear();
145 
146  forAll(meshMover_.mesh().boundaryMesh(), patchI)
147  {
148  const polyPatch& pp = meshMover_.mesh().boundaryMesh()[patchI];
149 
150  // Exclude non-static patches
151  if
152  (
153  !polyPatch::constraintType(pp.type())
154  && !meshMover_.slidingPatchSet_.found(pp.index())
155  && !patchSet.found(pp.index())
156  )
157  {
158  staticPatchSet_.insert(pp.index());
159  }
160  }
161 }
162 
163 
165 {
166  // Set patch-sets
167  patchSet_ = meshMover_.mesh().boundaryMesh().patchSet(patchNames_);
168  createStaticPatchSet();
169 }
170 
171 
174 {
175  labelHashSet movingPointZones;
176 
177  if (movingPointZones_.size())
178  {
179  forAll(movingPointZones_, i)
180  {
181  const labelList indices
182  (
183  meshMover_.mesh().pointZones().findIndices(movingPointZones_[i])
184  );
185 
186  if (indices.size())
187  {
188  movingPointZones.insert(indices);
189  Info<< " pointZone " << movingPointZones_[i]
190  << " will move with the object " << name << endl;
191  }
192  else
193  {
194  Info<< " movingZone " << movingPointZones_[i]
195  << " not found in pointZones" << endl;
196  }
197  }
198  }
199 
200  return movingPointZones;
201 }
202 
203 
206 {
207  labelHashSet staticPointZones;
208 
209  if (frozenPointZones_.size())
210  {
211  forAll(frozenPointZones_, i)
212  {
213  const labelList indices
214  (
215  meshMover_.mesh().pointZones().findIndices(frozenPointZones_[i])
216  );
217 
218  if (indices.size())
219  {
220  staticPointZones.insert(indices);
221  Info<< " pointZone " << frozenPointZones_[i]
222  << " is frozen (stationary)" << endl;
223  }
224  else
225  {
226  Info<< " frozenZone " << frozenPointZones_[i]
227  << " not found in pointZones" << endl;
228  }
229  }
230  }
231 
232  if (meshMover_.frozenPointZones_.size())
233  {
234  forAll(meshMover_.frozenPointZones_, i)
235  {
236  const labelList indices
237  (
238  meshMover_.mesh().pointZones().findIndices
239  (
240  meshMover_.frozenPointZones_[i]
241  )
242  );
243 
244  if (indices.size())
245  {
246  staticPointZones.insert(indices);
247  Info<< " pointZone " << meshMover_.frozenPointZones_[i]
248  << " is frozen (stationary)" << endl;
249  }
250  else
251  {
252  Info<< " frozenZone " << meshMover_.frozenPointZones_[i]
253  << " not found in pointZones" << endl;
254  }
255  }
256  }
257 
258  return staticPointZones;
259 }
260 
261 
262 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
263 
265 (
266  const word& objectName,
267  const multiValveEngine& engine,
268  const dictionary& dict
269 )
270 :
271  meshMover_(engine),
272  name(objectName),
273  axis(dict.lookup<vector>("axis", dimless)),
274  motion_(Function1<scalar>::New("motion", unitNone, dimLength, dict)),
275  patchNames_(dict.lookup("patches")),
276  maxMotionDistance_
277  (
278  dict.lookupOrDefault<scalar>("maxMotionDistance", dimLength, great)
279  ),
280  movingFrozenLayerThickness_
281  (
282  dict.lookupOrDefault<scalar>("movingFrozenLayerThickness", dimLength, 0)
283  ),
284  staticFrozenLayerThickness_
285  (
286  dict.lookupOrDefault<scalar>("staticFrozenLayerThickness", dimLength, 0)
287  ),
288  movingPointZones_
289  (
290  dict.lookupOrDefault("movingZones", wordReList::null())
291  ),
292  frozenPointZones_
293  (
294  dict.lookupOrDefault("frozenZones", wordReList::null())
295  ),
296  scale_
297  (
298  IOobject
299  (
300  "motionScale_" + name,
301  meshMover_.mesh().time().name(),
302  meshMover_.mesh(),
303  IOobject::NO_READ,
304  IOobject::NO_WRITE
305  ),
306  pointMesh::New(meshMover_.mesh()),
308  ),
309  cosineScale_
310  (
311  dict.lookupOrDefault<scalar>("cosineScale", dimless, 0)
312  ),
313  travelInterval_
314  (
315  dict.lookupOrDefault<scalar>("travelInterval", dimLength, great)
316  ),
317  executionCount_(0),
318  position0_(-great),
319  patchSet(patchSet_)
320 {
321  Info << indent << "Setting motion for " << name << endl;
322 
323  initPatchSets();
324 
325  if (patchSet_.empty())
326  {
328  << "Empty patchSet" << exit(FatalIOError);
329  }
330 }
331 
332 
333 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
334 
336 (
337  const polyMeshMap&
338 )
339 {
340  // Reset patch sets.
341  initPatchSets();
342 
343  // scale_ is resized by the meshToMesh mapper
344  scale_ = Zero;
345 
346  // Reset count of the scale_ field updates
347  executionCount_ = 0;
348 
349  // Reset position at last scale update
350  position0_ = -great;
351 }
352 
353 
354 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
static pointConstraints & New(const word &name, const pointMesh &mesh)
Construct and return the named DemandDrivenMeshObject.
Run-time selectable general function of one variable.
Definition: Function1.H:125
Internal::FieldType & primitiveFieldRef()
Return a reference to the primitive field.
const Internal::FieldType & primitiveField() const
Return a const-reference to the primitive field.
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:109
bool empty() const
Return true if the hash table is empty.
Definition: HashTableI.H:72
void clear()
Clear all entries from table.
Definition: HashTable.C:542
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
fvMesh & mesh()
Return the fvMesh.
Definition: fvMeshMover.H:129
static autoPtr< fvMeshMover > New(fvMesh &)
Select, construct and return the fvMeshMover.
void calcScale(const pointMesh &pMesh, const scalarField &pDistMoving, const scalarField &pDistStatic, scalar dMoving, scalar dMax, scalar dStatic)
Scale the mesh point deformation with distance functions.
Definition: movingObject.C:33
void createStaticPatchSet()
Generate staticPatchSet_ based on patch entries.
Definition: movingObject.C:142
movingObject(const word &name, const multiValveEngine &engine, const dictionary &dict)
Construct from dictionary.
Definition: movingObject.C:265
pointScalarField scale_
Interpolation scale (1 at moving patches, 0 at far-field)
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
Definition: movingObject.C:336
void transformPoints(pointField &newPoints, const vector &translationVector)
Definition: movingObject.C:117
const scalar cosineScale_
Cosine scale for the boundary point motion, between 0 and 1.
A mesh mover using explicit node translation based on scaled distance functions per moving object....
label index() const
Return the index of this patch in the boundaryMesh.
void constrain(PointField< Type > &pf, const bool overrideValue=false) const
Apply boundary conditions (single-patch constraints) and.
Mesh representing a set of points created from polyMesh.
Definition: pointMesh.H:53
Class containing mesh-to-mesh mapping information.
Definition: polyMeshMap.H:51
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:70
const polyBoundaryMesh & boundaryMesh() const
Return boundaryMesh reference.
Definition: polyPatch.C:270
static bool constraintType(const word &pt)
Return true if the given type is a constraint type.
Definition: polyPatch.C:238
virtual bool write(const bool write=true) const
Write using setting from DB.
A class for handling words, derived from string.
Definition: word.H:62
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
static const zero Zero
Definition: zero.H:97
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:258
const dimensionSet dimless
messageStream Info
const dimensionSet dimLength
const unitConversion unitNone
void mag(LagrangianPatchField< scalar > &f, const LagrangianPatchField< Type > &f1)
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
IOerror FatalIOError
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:228
dimensionedScalar cos(const dimensionedScalar &ds)
dictionary dict