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-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 
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  const word& patchType
149 )
150 :
151  cyclicPolyPatch(name, size, start, index, bm, patchType),
152  nonConformalCoupledPolyPatch(static_cast<const polyPatch&>(*this)),
153  intersectionIsValid_(0),
154  intersection_(false),
155  raysIsValid_(0),
156  rays_(false),
157  moveUpdate_(moveUpdate::always)
158 {}
159 
160 
162 (
163  const word& name,
164  const label size,
165  const label start,
166  const label index,
167  const polyBoundaryMesh& bm,
168  const word& patchType,
169  const word& nbrPatchName,
170  const word& origPatchName,
172 )
173 :
175  (
176  name,
177  size,
178  start,
179  index,
180  bm,
181  patchType,
182  nbrPatchName,
183  transform
184  ),
185  nonConformalCoupledPolyPatch(*this, origPatchName),
186  intersectionIsValid_(0),
187  intersection_(false),
188  raysIsValid_(0),
189  rays_(false),
190  moveUpdate_(moveUpdate::always)
191 {}
192 
193 
195 (
196  const word& name,
197  const dictionary& dict,
198  const label index,
199  const polyBoundaryMesh& bm,
200  const word& patchType
201 )
202 :
203  cyclicPolyPatch(name, dict, index, bm, patchType, true),
205  intersectionIsValid_(0),
206  intersection_(false),
207  raysIsValid_(0),
208  rays_(false),
209  moveUpdate_
210  (
211  dict.found("moveUpdate")
212  ? moveUpdateNames_.read(dict.lookup("moveUpdate"))
213  : dict.found("reMapAfterMove") // <-- backwards compatibility
214  ? (
215  dict.lookup<bool>("reMapAfterMove")
216  ? moveUpdate::always
217  : moveUpdate::never
218  )
219  : moveUpdate::always
220  )
221 {}
222 
223 
225 (
226  const nonConformalCyclicPolyPatch& pp,
227  const polyBoundaryMesh& bm
228 )
229 :
230  cyclicPolyPatch(pp, bm),
231  nonConformalCoupledPolyPatch(*this, pp),
232  intersectionIsValid_(0),
233  intersection_(false),
234  raysIsValid_(0),
235  rays_(false),
236  moveUpdate_(pp.moveUpdate_)
237 {}
238 
239 
241 (
242  const nonConformalCyclicPolyPatch& pp,
243  const polyBoundaryMesh& bm,
244  const label index,
245  const label newSize,
246  const label newStart,
247  const word& nbrPatchName,
248  const word& origPatchName
249 )
250 :
251  cyclicPolyPatch(pp, bm, index, newSize, newStart, nbrPatchName),
252  nonConformalCoupledPolyPatch(*this, origPatchName),
253  intersectionIsValid_(0),
254  intersection_(false),
255  raysIsValid_(0),
256  rays_(false),
257  moveUpdate_(pp.moveUpdate_)
258 {}
259 
260 
261 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
262 
264 {}
265 
266 
267 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
268 
271 {
272  return
273  refCast<const nonConformalCyclicPolyPatch>
274  (
276  );
277 }
278 
279 
281 {
282  return false;
283 }
284 
285 
288 {
289  if (!owner())
290  {
292  << "The non-conformal cyclic intersection is only available to "
293  << "the owner patch" << abort(FatalError);
294  }
295 
296  const bool intersectionIsValid =
297  (intersectionIsValid_ == 2)
298  || (
299  intersectionIsValid_ == 1
301  (
302  origPatch(),
303  nbrPatch().origPatch()
304  )
305  );
306 
307  if (!intersectionIsValid)
308  {
309  const polyMesh& mesh = boundaryMesh().mesh();
310 
312 
313  const string inRegionName =
315  ? ""
316  : " in region " + mesh.name();
317 
318  intersection_.update
319  (
320  origPatch(),
321  ncb.patchPointNormals(origPatchIndex()),
322  nbrPatch().origPatch(),
323  transform(),
324  {
325  origPatchName() + inRegionName,
326  nbrPatch().origPatchName() + inRegionName
327  },
329  );
330 
331  intersectionIsValid_ = 2;
332  }
333 
334  return intersection_;
335 }
336 
337 
340 {
341  if (!owner())
342  {
344  << "The non-conformal cyclic rays is only available to "
345  << "the owner patch" << abort(FatalError);
346  }
347 
348  const bool raysIsValid =
349  (raysIsValid_ == 2)
350  || (
351  raysIsValid_ == 1
353  (
354  origPatch(),
355  nbrPatch().origPatch()
356  )
357  );
358 
359  if (!raysIsValid)
360  {
361  const polyMesh& mesh = boundaryMesh().mesh();
362 
364 
365  const string inRegionName =
367  ? ""
368  : " in region " + mesh.name();
369 
370  rays_.update
371  (
373  (
374  origPatch(),
375  mesh.points(),
376  mesh.oldPoints()
377  ),
378  ncb.patchPointNormals(origPatchIndex()),
379  ncb.patchPointNormals0(origPatchIndex()),
381  (
382  nbrPatch().origPatch(),
383  mesh.points(),
384  mesh.oldPoints()
385  ),
386  transform(),
387  {
388  origPatchName() + inRegionName,
389  nbrPatch().origPatchName() + inRegionName
390  },
392  );
393 
394  raysIsValid_ = 2;
395  }
396 
397  return rays_;
398 }
399 
400 
402 (
403  const scalar fraction,
404  const label origFacei,
405  const vector& p,
406  const vector& n,
407  point& nbrP
408 ) const
409 {
410  const polyMesh& mesh = boundaryMesh().mesh();
411 
412  const nonConformalCyclicPolyPatch& ownerPatch =
413  owner() ? *this : nbrPatch();
414 
415  auto ownerRaysMethod =
416  owner()
419 
420  return
421  (ownerPatch.rays().*ownerRaysMethod)
422  (
424  (
425  nbrPatch().origPatch(),
426  mesh.points(),
427  mesh.oldPoints()
428  ),
429  fraction,
430  origFacei,
431  transform().invTransformPosition(p),
432  transform().invTransform(n),
433  nbrP
434  );
435 }
436 
437 
439 {
442  writeEntryIfDifferent<word>
443  (
444  os,
445  "moveUpdate",
446  moveUpdateNames_[moveUpdate::always],
447  moveUpdateNames_[moveUpdate_]
448  );
449 }
450 
451 
452 // ************************************************************************* //
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:434
const polyMesh & mesh() const
Return reference to polyMesh.
Definition: fvMesh.H:443
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.
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.
nonConformalCyclicPolyPatch(const word &name, const label size, const label start, const label index, const polyBoundaryMesh &bm, const word &patchType)
Construct from components.
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:80
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:270
virtual const pointField & oldPoints() const
Return old points for mesh motion.
Definition: polyMesh.C:1369
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1331
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:70
virtual void clearGeom()
Clear geometry.
Definition: polyPatch.C:76
Struct for keeping processor, element (cell, face, point) index.
Definition: remote.H:57
A class for handling words, derived from string.
Definition: word.H:62
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
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)
errorManip< error > abort(error &err)
Definition: errorManip.H:131
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
PrimitiveOldTimePatch< SubList< face >, const pointField & > primitiveOldTimePatch
Addressing for a faceList slice.
dimensionSet transform(const dimensionSet &)
Definition: dimensionSet.C:501
defineTypeNameAndDebug(combustionModel, 0)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
error FatalError
dictionary dict
volScalarField & p