nonConformalCyclicPolyPatch.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) 2021-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 
29 #include "mappedPatchBaseBase.H"
30 #include "polyBoundaryMesh.H"
31 #include "polyMesh.H"
32 #include "SubField.H"
33 #include "nonConformalBoundary.H"
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
40 
43  (
44  polyPatch,
47  );
48 }
49 
52 {
53  "always",
54  "detect",
55  "never"
56 };
57 
58 
59 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
60 
62 {
64  intersectionIsValid_ = false;
65  raysIsValid_ = false;
66 }
67 
68 
70 {
71  static_cast<cyclicTransform&>(*this) =
73  (
74  name(),
75  origPatch().faceAreas(),
76  *this,
77  nbrPatchName(),
78  nbrPatch(),
79  matchTolerance()
80  );
81 }
82 
83 
85 (
86  PstreamBuffers& pBufs,
87  const pointField& p
88 )
89 {
91 
92  if (moveUpdate_ == moveUpdate::never)
93  {
94  // Do nothing
95  }
96  else if (moveUpdate_ == moveUpdate::detect)
97  {
98  intersectionIsValid_ = min(intersectionIsValid_, 1);
99  raysIsValid_ = min(raysIsValid_, 1);
100  }
101  else
102  {
103  intersectionIsValid_ = 0;
104  raysIsValid_ = 0;
105  }
106 }
107 
108 
110 {
112  intersectionIsValid_ = 0;
113  raysIsValid_ = 0;
114 }
115 
116 
118 {
120  intersectionIsValid_ = 0;
121  raysIsValid_ = 0;
122 }
123 
124 
126 {
127  cyclicPolyPatch::rename(newNames);
129 }
130 
131 
133 {
134  cyclicPolyPatch::reorder(newToOldIndex);
136 }
137 
138 
139 // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
140 
142 (
143  const word& name,
144  const label size,
145  const label start,
146  const label index,
147  const polyBoundaryMesh& bm
148 )
149 :
150  cyclicPolyPatch(name, size, start, index, bm),
151  nonConformalCoupledPolyPatch(static_cast<const polyPatch&>(*this)),
152  intersectionIsValid_(0),
153  intersection_(false),
154  raysIsValid_(0),
155  rays_(false),
156  moveUpdate_(moveUpdate::always)
157 {}
158 
159 
161 (
162  const word& name,
163  const label size,
164  const label start,
165  const label index,
166  const polyBoundaryMesh& bm,
167  const word& nbrPatchName,
168  const word& origPatchName,
170 )
171 :
173  (
174  name,
175  size,
176  start,
177  index,
178  bm,
179  nbrPatchName,
180  transform
181  ),
182  nonConformalCoupledPolyPatch(*this, origPatchName),
183  intersectionIsValid_(0),
184  intersection_(false),
185  raysIsValid_(0),
186  rays_(false),
187  moveUpdate_(moveUpdate::always)
188 {}
189 
190 
192 (
193  const word& name,
194  const dictionary& dict,
195  const label index,
196  const polyBoundaryMesh& bm
197 )
198 :
199  cyclicPolyPatch(name, dict, index, bm, true),
201  intersectionIsValid_(0),
202  intersection_(false),
203  raysIsValid_(0),
204  rays_(false),
205  moveUpdate_
206  (
207  dict.found("moveUpdate")
208  ? moveUpdateNames_.read(dict.lookup("moveUpdate"))
209  : dict.found("reMapAfterMove") // <-- backwards compatibility
210  ? (
211  dict.lookup<bool>("reMapAfterMove")
212  ? moveUpdate::always
213  : moveUpdate::never
214  )
215  : moveUpdate::always
216  )
217 {}
218 
219 
221 (
222  const nonConformalCyclicPolyPatch& pp,
223  const polyBoundaryMesh& bm
224 )
225 :
226  cyclicPolyPatch(pp, bm),
227  nonConformalCoupledPolyPatch(*this, pp),
228  intersectionIsValid_(0),
229  intersection_(false),
230  raysIsValid_(0),
231  rays_(false),
232  moveUpdate_(pp.moveUpdate_)
233 {}
234 
235 
237 (
238  const nonConformalCyclicPolyPatch& pp,
239  const polyBoundaryMesh& bm,
240  const label index,
241  const label newSize,
242  const label newStart,
243  const word& nbrPatchName,
244  const word& origPatchName
245 )
246 :
247  cyclicPolyPatch(pp, bm, index, newSize, newStart, nbrPatchName),
248  nonConformalCoupledPolyPatch(*this, origPatchName),
249  intersectionIsValid_(0),
250  intersection_(false),
251  raysIsValid_(0),
252  rays_(false),
253  moveUpdate_(pp.moveUpdate_)
254 {}
255 
256 
257 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
258 
260 {}
261 
262 
263 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
264 
267 {
268  return
269  refCast<const nonConformalCyclicPolyPatch>
270  (
272  );
273 }
274 
275 
277 {
278  return false;
279 }
280 
281 
284 {
285  if (!owner())
286  {
288  << "The non-conformal cyclic intersection is only available to "
289  << "the owner patch" << abort(FatalError);
290  }
291 
292  const bool intersectionIsValid =
293  (intersectionIsValid_ == 2)
294  || (
295  intersectionIsValid_ == 1
297  (
298  origPatch(),
299  nbrPatch().origPatch()
300  )
301  );
302 
303  if (!intersectionIsValid)
304  {
305  const polyMesh& mesh = this->mesh();
306 
308 
309  const string inRegionName =
311  ? ""
312  : " in region " + mesh.name();
313 
314  intersection_.update
315  (
316  origPatch(),
317  ncb.patchPointNormals(origPatchIndex()),
318  nbrPatch().origPatch(),
319  transform(),
320  {
321  origPatchName() + inRegionName,
322  nbrPatch().origPatchName() + inRegionName
323  },
325  );
326 
327  intersectionIsValid_ = 2;
328  }
329 
330  return intersection_;
331 }
332 
333 
336 {
337  if (!owner())
338  {
340  << "The non-conformal cyclic rays is only available to "
341  << "the owner patch" << abort(FatalError);
342  }
343 
344  const bool raysIsValid =
345  (raysIsValid_ == 2)
346  || (
347  raysIsValid_ == 1
349  (
350  origPatch(),
351  nbrPatch().origPatch()
352  )
353  );
354 
355  if (!raysIsValid)
356  {
357  const polyMesh& mesh = this->mesh();
358 
360 
361  const string inRegionName =
363  ? ""
364  : " in region " + mesh.name();
365 
366  rays_.update
367  (
369  (
370  origPatch(),
371  mesh.points(),
372  mesh.oldPoints()
373  ),
374  ncb.patchPointNormals(origPatchIndex()),
375  ncb.patchPointNormals0(origPatchIndex()),
377  (
378  nbrPatch().origPatch(),
379  mesh.points(),
380  mesh.oldPoints()
381  ),
382  transform(),
383  {
384  origPatchName() + inRegionName,
385  nbrPatch().origPatchName() + inRegionName
386  },
388  );
389 
390  raysIsValid_ = 2;
391  }
392 
393  return rays_;
394 }
395 
396 
398 (
399  const scalar fraction,
400  const label origFacei,
401  const vector& p,
402  const vector& n,
403  point& nbrP
404 ) const
405 {
406  const polyMesh& mesh = this->mesh();
407 
408  const nonConformalCyclicPolyPatch& ownerPatch =
409  owner() ? *this : nbrPatch();
410 
411  auto ownerRaysMethod =
412  owner()
415 
416  return
417  (ownerPatch.rays().*ownerRaysMethod)
418  (
420  (
421  nbrPatch().origPatch(),
422  mesh.points(),
423  mesh.oldPoints()
424  ),
425  fraction,
426  origFacei,
427  transform().invTransformPosition(p),
428  transform().invTransform(n),
429  nbrP
430  );
431 }
432 
433 
435 {
438  writeEntryIfDifferent<word>
439  (
440  os,
441  "moveUpdate",
442  moveUpdateNames_[moveUpdate::always],
443  moveUpdateNames_[moveUpdate_]
444  );
445 }
446 
447 
448 // ************************************************************************* //
bool found
label n
Macros for easy insertion into run-time selection tables.
static nonConformalBoundary & New(const word &name, const polyMesh &mesh)
Construct and return the named DemandDrivenMeshObject.
Initialise the NamedEnum HashTable from the static list of names.
Definition: NamedEnum.H:55
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
Buffers for inter-processor communications streams (UOPstream, UIPstream).
Cyclic plane patch.
const cyclicPolyPatch & nbrPatch() const
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
virtual void initMovePoints(PstreamBuffers &, const pointField &)
Initialise the patches for moving points.
virtual void rename(const wordList &newNames)
Reset the patch name.
virtual void reorder(const labelUList &newToOldIndex)
Reset the patch index.
virtual void initCalcGeometry(PstreamBuffers &)
Initialise the calculation of the patch geometry.
virtual void initTopoChange(PstreamBuffers &)
Initialise the update of the patch topology.
Cyclic plane transformation.
string str() const
Generate a string representation of the transform.
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
const word & name() const
Return reference to name.
Definition: fvMesh.H:447
static bool moving(const polyPatch &patch, const polyPatch &nbrPatch)
Return whether or not the patches have moved.
Mesh object that stores an all boundary patch and mapping to and from it and the mesh and the individ...
tmp< vectorField > patchPointNormals(const label patchi) const
Get parallel consistent point normals for the patch.
tmp< vectorField > patchPointNormals0(const label patchi) const
Get parallel consistent old-time point normals for the patch.
Non-conformal coupled poly patch. As nonConformalPolyPatch, but this patch is coupled to another non-...
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
virtual void rename(const wordList &newNames)
Reset the patch name.
virtual void reorder(const labelUList &newToOldIndex)
Reset the patch index.
Non-conformal cyclic poly patch. As nonConformalCoupledPolyPatch, but the neighbouring patch is local...
virtual void initMovePoints(PstreamBuffers &pBufs, const pointField &)
Initialise the patches for moving points.
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
remote ray(const scalar fraction, const label origFacei, const vector &p, const vector &n, point &nbrP) const
Compute a ray intersection across the coupling.
virtual void rename(const wordList &newNames)
Reset the patch name.
nonConformalCyclicPolyPatch(const word &name, const label size, const label start, const label index, const polyBoundaryMesh &bm)
Construct from components.
virtual void calcGeometry(PstreamBuffers &)
Calculate the patch geometry.
const patchToPatches::rays & rays() const
Access the rays engine.
virtual void reorder(const labelUList &newToOldIndex)
Reset the patch index.
virtual void initCalcGeometry(PstreamBuffers &)
Initialise the calculation of the patch geometry.
virtual bool coupled() const
Is this patch coupled? Returns false. For NCC patches the poly.
const patchToPatches::intersection & intersection() const
Access the intersection engine.
const nonConformalCyclicPolyPatch & nbrPatch() const
Neighbour patch.
virtual void initTopoChange(PstreamBuffers &)
Initialise the update of the patch topology.
static const NamedEnum< moveUpdate, 3 > moveUpdateNames_
Names of the move-update conditions.
label raysIsValid_
Is the rays engine up to date? Zero if out of date. One if out of.
moveUpdate
Enumeration for the condition that triggers re-calculation of the.
label intersectionIsValid_
Is the intersection engine up to date? Zero if out of date. One if.
Class to generate patchToPatch coupling geometry. A full geometric intersection is done between a fac...
remote srcToTgtRay(const primitiveOldTimePatch &tgtPatch, const scalar fraction, const label srcFacei, const vector &srcP, const vector &srcN, point &tgtP) const
Compute a ray intersection from the source side to the target.
remote tgtToSrcRay(const primitiveOldTimePatch &srcPatch, const scalar fraction, const label tgtFacei, const vector &tgtP, const vector &tgtN, point &srcP) const
Compute a ray intersection from the target side to the source.
Foam::polyBoundaryMesh.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:78
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:260
virtual const pointField & oldPoints() const
Return old points for mesh motion.
Definition: polyMesh.C:1333
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1295
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:71
virtual void clearGeom()
Clear geometry.
Definition: polyPatch.C:75
Struct for keeping processor, element (cell, face, point) index.
Definition: remote.H:57
A class for handling words, derived from string.
Definition: word.H:63
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
const unitSet fraction
const unitSet & lookup(const word &unitName)
Lookup and return the named unit from the table.
Definition: units.C:346
Namespace for OpenFOAM.
bool read(const char *, int32_t &)
Definition: int32IO.C:85
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
addToRunTimeSelectionTable(polyPatch, mergedCyclicPolyPatch, word)
void transform(GeometricField< Type, GeoMesh > &rtf, const GeometricField< tensor, GeoMesh > &trf, const GeometricField< Type, GeoMesh > &tf)
errorManip< error > abort(error &err)
Definition: errorManip.H:131
PrimitiveOldTimePatch< SubList< face >, const pointField & > primitiveOldTimePatch
Addressing for a faceList slice.
dimensioned< Type > min(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
error FatalError
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
dictionary dict
volScalarField & p