PatchEdgeFaceWave.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 | Copyright (C) 2011-2015 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 "PatchEdgeFaceWave.H"
27 #include "polyMesh.H"
28 #include "globalMeshData.H"
29 #include "PatchTools.H"
30 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
33 template
34 <
35  class PrimitivePatchType,
36  class Type,
37  class TrackingData
38 >
40 propagationTol_ = 0.01;
41 
42 template
43 <
44  class PrimitivePatchType,
45  class Type,
46  class TrackingData
47 >
50 dummyTrackData_ = 12345;
51 
52 
53 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
54 
55 // Update info for edgeI, at position pt, with information from
56 // neighbouring face.
57 // Updates:
58 // - changedEdge_, changedEdges_,
59 // - statistics: nEvals_, nUnvisitedEdges_
60 template
61 <
62  class PrimitivePatchType,
63  class Type,
64  class TrackingData
65 >
68 (
69  const label edgeI,
70  const label neighbourFaceI,
71  const Type& neighbourInfo,
72  Type& edgeInfo
73 )
74 {
75  nEvals_++;
76 
77  bool wasValid = edgeInfo.valid(td_);
78 
79  bool propagate =
80  edgeInfo.updateEdge
81  (
82  mesh_,
83  patch_,
84  edgeI,
85  neighbourFaceI,
86  neighbourInfo,
87  propagationTol_,
88  td_
89  );
90 
91  if (propagate)
92  {
93  if (!changedEdge_[edgeI])
94  {
95  changedEdge_[edgeI] = true;
96  changedEdges_.append(edgeI);
97  }
98  }
99 
100  if (!wasValid && edgeInfo.valid(td_))
101  {
102  --nUnvisitedEdges_;
103  }
104 
105  return propagate;
106 }
107 
108 
109 // Update info for faceI, at position pt, with information from
110 // neighbouring edge.
111 // Updates:
112 // - changedFace_, changedFaces_,
113 // - statistics: nEvals_, nUnvisitedFace_
114 template
115 <
116  class PrimitivePatchType,
117  class Type,
118  class TrackingData
119 >
122 (
123  const label faceI,
124  const label neighbourEdgeI,
125  const Type& neighbourInfo,
126  Type& faceInfo
127 )
128 {
129  nEvals_++;
130 
131  bool wasValid = faceInfo.valid(td_);
132 
133  bool propagate =
134  faceInfo.updateFace
135  (
136  mesh_,
137  patch_,
138  faceI,
139  neighbourEdgeI,
140  neighbourInfo,
141  propagationTol_,
142  td_
143  );
144 
145  if (propagate)
146  {
147  if (!changedFace_[faceI])
148  {
149  changedFace_[faceI] = true;
150  changedFaces_.append(faceI);
151  }
152  }
153 
154  if (!wasValid && faceInfo.valid(td_))
155  {
156  --nUnvisitedFaces_;
157  }
158 
159  return propagate;
160 }
161 
162 
163 template
164 <
165  class PrimitivePatchType,
166  class Type,
167  class TrackingData
168 >
171 {
172  const globalMeshData& globalData = mesh_.globalData();
173  const mapDistribute& map = globalData.globalEdgeSlavesMap();
174  const PackedBoolList& cppOrientation = globalData.globalEdgeOrientation();
175 
176  // Convert patch-edge data into cpp-edge data
177  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
178 
179  //- Construct with all data in consistent orientation
180  List<Type> cppEdgeData(map.constructSize());
181 
182  forAll(patchEdges_, i)
183  {
184  label patchEdgeI = patchEdges_[i];
185  label coupledEdgeI = coupledEdges_[i];
186 
187  if (changedEdge_[patchEdgeI])
188  {
189  const Type& data = allEdgeInfo_[patchEdgeI];
190 
191  // Patch-edge data needs to be converted into coupled-edge data
192  // (optionally flipped) and consistent in orientation with
193  // master of coupled edge (optionally flipped)
194  bool sameOrientation =
195  (
196  sameEdgeOrientation_[i]
197  == cppOrientation[coupledEdgeI]
198  );
199 
200  cppEdgeData[coupledEdgeI].updateEdge
201  (
202  mesh_,
203  patch_,
204  data,
205  sameOrientation,
206  propagationTol_,
207  td_
208  );
209  }
210  }
211 
212 
213  // Synchronise
214  // ~~~~~~~~~~~
215 
216  globalData.syncData
217  (
218  cppEdgeData,
219  globalData.globalEdgeSlaves(),
220  globalData.globalEdgeTransformedSlaves(),
221  map,
222  globalData.globalTransforms(),
224  (
225  mesh_,
226  patch_,
227  propagationTol_,
228  td_
229  ),
231  (
232  mesh_,
233  patch_,
234  propagationTol_,
235  td_
236  )
237  );
238 
239 
240  // Back from cpp-edge to patch-edge data
241  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
242 
243  forAll(patchEdges_, i)
244  {
245  label patchEdgeI = patchEdges_[i];
246  label coupledEdgeI = coupledEdges_[i];
247 
248  const Type& data = cppEdgeData[coupledEdgeI];
249 
250  if (data.valid(td_))
251  {
252  bool sameOrientation =
253  (
254  sameEdgeOrientation_[i]
255  == cppOrientation[coupledEdgeI]
256  );
257 
258  allEdgeInfo_[patchEdgeI].updateEdge
259  (
260  mesh_,
261  patch_,
262  data,
263  sameOrientation,
264  propagationTol_,
265  td_
266  );
267 
268  if (!changedEdge_[patchEdgeI])
269  {
270  changedEdges_.append(patchEdgeI);
271  changedEdge_[patchEdgeI] = true;
272  }
273  }
274  }
275 }
276 
277 
278 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
279 
280 // Iterate, propagating changedEdgesInfo across patch, until no change (or
281 // maxIter reached). Initial edge values specified.
282 template
283 <
284  class PrimitivePatchType,
285  class Type,
286  class TrackingData
287 >
290 (
291  const polyMesh& mesh,
292  const PrimitivePatchType& patch,
293  const labelList& changedEdges,
294  const List<Type>& changedEdgesInfo,
295 
296  UList<Type>& allEdgeInfo,
297  UList<Type>& allFaceInfo,
298 
299  const label maxIter,
300  TrackingData& td
301 )
302 :
303  mesh_(mesh),
304  patch_(patch),
305  allEdgeInfo_(allEdgeInfo),
306  allFaceInfo_(allFaceInfo),
307  td_(td),
308  changedEdge_(patch_.nEdges()),
309  changedEdges_(patch_.size()),
310  changedFace_(patch_.size()),
311  changedFaces_(patch_.size()),
312  nEvals_(0),
313  nUnvisitedEdges_(patch_.nEdges()),
314  nUnvisitedFaces_(patch_.size())
315 {
316  // Calculate addressing between patch_ and mesh.globalData().coupledPatch()
317  // for ease of synchronisation
318  PatchTools::matchEdges
319  (
320  patch_,
321  mesh_.globalData().coupledPatch(),
322 
323  patchEdges_,
324  coupledEdges_,
325  sameEdgeOrientation_
326  );
327 
328 
329  if (allEdgeInfo_.size() != patch_.nEdges())
330  {
332  << "size of edgeInfo work array is not equal to the number"
333  << " of edges in the patch" << endl
334  << " edgeInfo :" << allEdgeInfo_.size() << endl
335  << " patch.nEdges:" << patch_.nEdges()
336  << exit(FatalError);
337  }
338  if (allFaceInfo_.size() != patch_.size())
339  {
341  << "size of edgeInfo work array is not equal to the number"
342  << " of faces in the patch" << endl
343  << " faceInfo :" << allFaceInfo_.size() << endl
344  << " patch.size:" << patch_.size()
345  << exit(FatalError);
346  }
347 
348 
349  // Set from initial changed edges data
350  setEdgeInfo(changedEdges, changedEdgesInfo);
351 
352  if (debug)
353  {
354  Pout<< "Seed edges : " << changedEdges_.size() << endl;
355  }
356 
357  // Iterate until nothing changes
358  label iter = iterate(maxIter);
359 
360  if ((maxIter > 0) && (iter >= maxIter))
361  {
363  << "Maximum number of iterations reached. Increase maxIter." << endl
364  << " maxIter:" << maxIter << endl
365  << " changedEdges:" << changedEdges_.size() << endl
366  << " changedFaces:" << changedFaces_.size() << endl
367  << exit(FatalError);
368  }
369 }
370 
371 
372 template
373 <
374  class PrimitivePatchType,
375  class Type,
376  class TrackingData
377 >
380 (
381  const polyMesh& mesh,
382  const PrimitivePatchType& patch,
383  UList<Type>& allEdgeInfo,
384  UList<Type>& allFaceInfo,
385  TrackingData& td
386 )
387 :
388  mesh_(mesh),
389  patch_(patch),
390  allEdgeInfo_(allEdgeInfo),
391  allFaceInfo_(allFaceInfo),
392  td_(td),
393  changedEdge_(patch_.nEdges()),
394  changedEdges_(patch_.nEdges()),
395  changedFace_(patch_.size()),
396  changedFaces_(patch_.size()),
397  nEvals_(0),
398  nUnvisitedEdges_(patch_.nEdges()),
399  nUnvisitedFaces_(patch_.size())
400 {
401  // Calculate addressing between patch_ and mesh.globalData().coupledPatch()
402  // for ease of synchronisation
403  PatchTools::matchEdges
404  (
405  patch_,
406  mesh_.globalData().coupledPatch(),
407 
408  patchEdges_,
409  coupledEdges_,
410  sameEdgeOrientation_
411  );
412 }
413 
414 
415 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
416 
417 template
418 <
419  class PrimitivePatchType,
420  class Type,
421  class TrackingData
422 >
425 {
426  return nUnvisitedEdges_;
427 }
428 
429 
430 template
431 <
432  class PrimitivePatchType,
433  class Type,
434  class TrackingData
435 >
438 {
439  return nUnvisitedFaces_;
440 }
441 
442 
443 // Copy edge information into member data
444 template
445 <
446  class PrimitivePatchType,
447  class Type,
448  class TrackingData
449 >
452 (
453  const labelList& changedEdges,
454  const List<Type>& changedEdgesInfo
455 )
456 {
457  forAll(changedEdges, changedEdgeI)
458  {
459  label edgeI = changedEdges[changedEdgeI];
460 
461  bool wasValid = allEdgeInfo_[edgeI].valid(td_);
462 
463  // Copy info for edgeI
464  allEdgeInfo_[edgeI] = changedEdgesInfo[changedEdgeI];
465 
466  // Maintain count of unset edges
467  if (!wasValid && allEdgeInfo_[edgeI].valid(td_))
468  {
469  --nUnvisitedEdges_;
470  }
471 
472  // Mark edgeI as changed, both on list and on edge itself.
473 
474  if (!changedEdge_[edgeI])
475  {
476  changedEdge_[edgeI] = true;
477  changedEdges_.append(edgeI);
478  }
479  }
480 }
481 
482 
483 // Propagate information from face to edge. Return number of edges changed.
484 template
485 <
486  class PrimitivePatchType,
487  class Type,
488  class TrackingData
489 >
492 {
493  changedEdges_.clear();
494  changedEdge_ = false;
495 
496  forAll(changedFaces_, changedFaceI)
497  {
498  label faceI = changedFaces_[changedFaceI];
499 
500  if (!changedFace_[faceI])
501  {
503  << "face " << faceI
504  << " not marked as having been changed" << nl
505  << "This might be caused by multiple occurences of the same"
506  << " seed edge." << abort(FatalError);
507  }
508 
509  const Type& neighbourWallInfo = allFaceInfo_[faceI];
510 
511  // Evaluate all connected edges
512  const labelList& fEdges = patch_.faceEdges()[faceI];
513 
514  forAll(fEdges, fEdgeI)
515  {
516  label edgeI = fEdges[fEdgeI];
517 
518  Type& currentWallInfo = allEdgeInfo_[edgeI];
519 
520  if (!currentWallInfo.equal(neighbourWallInfo, td_))
521  {
522  updateEdge
523  (
524  edgeI,
525  faceI,
526  neighbourWallInfo,
527  currentWallInfo
528  );
529  }
530  }
531  }
532 
533 
534  syncEdges();
535 
536 
537  if (debug)
538  {
539  Pout<< "Changed edges : " << changedEdges_.size() << endl;
540  }
541 
542  return returnReduce(changedEdges_.size(), sumOp<label>());
543 }
544 
545 
546 // Propagate information from edge to face. Return number of faces changed.
547 template
548 <
549  class PrimitivePatchType,
550  class Type,
551  class TrackingData
552 >
555 {
556  changedFaces_.clear();
557  changedFace_ = false;
558 
559  const labelListList& edgeFaces = patch_.edgeFaces();
560 
561  forAll(changedEdges_, changedEdgeI)
562  {
563  label edgeI = changedEdges_[changedEdgeI];
564 
565  if (!changedEdge_[edgeI])
566  {
568  << "edge " << edgeI
569  << " not marked as having been changed" << nl
570  << "This might be caused by multiple occurences of the same"
571  << " seed edge." << abort(FatalError);
572  }
573 
574  const Type& neighbourWallInfo = allEdgeInfo_[edgeI];
575 
576  // Evaluate all connected faces
577 
578  const labelList& eFaces = edgeFaces[edgeI];
579  forAll(eFaces, eFaceI)
580  {
581  label faceI = eFaces[eFaceI];
582 
583  Type& currentWallInfo = allFaceInfo_[faceI];
584 
585  if (!currentWallInfo.equal(neighbourWallInfo, td_))
586  {
587  updateFace
588  (
589  faceI,
590  edgeI,
591  neighbourWallInfo,
592  currentWallInfo
593  );
594  }
595  }
596  }
597 
598  if (debug)
599  {
600  Pout<< "Changed faces : " << changedFaces_.size() << endl;
601  }
602 
603  return returnReduce(changedFaces_.size(), sumOp<label>());
604 }
605 
606 
607 // Iterate
608 template
609 <
610  class PrimitivePatchType,
611  class Type,
612  class TrackingData
613 >
615 iterate
616 (
617  const label maxIter
618 )
619 {
620  // Make sure coupled edges contain same info
621  syncEdges();
622 
623  nEvals_ = 0;
624 
625  label iter = 0;
626 
627  while (iter < maxIter)
628  {
629  if (debug)
630  {
631  Pout<< "Iteration " << iter << endl;
632  }
633 
634  label nFaces = edgeToFace();
635 
636  if (debug)
637  {
638  Pout<< "Total changed faces : " << nFaces << endl;
639  }
640 
641  if (nFaces == 0)
642  {
643  break;
644  }
645 
646  label nEdges = faceToEdge();
647 
648  if (debug)
649  {
650  Pout<< "Total changed edges : " << nEdges << nl
651  << "Total evaluations : " << nEvals_ << nl
652  << "Remaining unvisited edges : " << nUnvisitedEdges_ << nl
653  << "Remaining unvisited faces : " << nUnvisitedFaces_ << nl
654  << endl;
655  }
656 
657  if (nEdges == 0)
658  {
659  break;
660  }
661 
662  iter++;
663  }
664 
665  return iter;
666 }
667 
668 
669 // ************************************************************************* //
Foam::updateOp
Update operation.
Definition: PatchEdgeFaceWave.H:267
Foam::PackedBoolList
A bit-packed bool list.
Definition: PackedBoolList.H:63
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:86
Foam::PatchEdgeFaceWave::syncEdges
void syncEdges()
Update coupled edges.
Definition: PatchEdgeFaceWave.C:170
Foam::globalMeshData::globalEdgeSlavesMap
const mapDistribute & globalEdgeSlavesMap() const
Definition: globalMeshData.C:2245
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
globalMeshData.H
Foam::transformOp
Transform operation.
Definition: PatchEdgeFaceWave.H:307
Foam::PatchEdgeFaceWave::updateEdge
bool updateEdge(const label edgeI, const label neighbourFaceI, const Type &neighbourInfo, Type &edgeInfo)
Updates edgeInfo with information from neighbour. Updates all.
Definition: PatchEdgeFaceWave.C:68
Foam::PatchEdgeFaceWave
Wave propagation of information along patch. Every iteration information goes through one layer of fa...
Definition: PatchEdgeFaceWave.H:69
Foam::PatchEdgeFaceWave::PatchEdgeFaceWave
PatchEdgeFaceWave(const PatchEdgeFaceWave &)
Disallow default bitwise copy construct.
Foam::PatchEdgeFaceWave::faceToEdge
label faceToEdge()
Propagate from face to edge. Returns total number of edges.
Definition: PatchEdgeFaceWave.C:491
Foam::PatchEdgeFaceWave::updateFace
bool updateFace(const label faceI, const label neighbourEdgeI, const Type &neighbourInfo, Type &faceInfo)
Updates faceInfo with information from neighbour. Updates all.
Definition: PatchEdgeFaceWave.C:122
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
polyMesh.H
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
PatchEdgeFaceWave.H
Foam::label
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
Foam::List::append
void append(const T &)
Append an element at the end of the list.
Foam::nl
static const char nl
Definition: Ostream.H:260
Foam::globalMeshData::globalEdgeOrientation
const PackedBoolList & globalEdgeOrientation() const
Is my edge same orientation as master edge.
Definition: globalMeshData.C:2235
Foam::globalMeshData::globalTransforms
const globalIndexAndTransform & globalTransforms() const
Global transforms numbering.
Definition: globalMeshData.C:2160
Foam::mapDistribute
Class containing processor-to-processor mapping information.
Definition: mapDistribute.H:152
Foam::PatchEdgeFaceWave::edgeToFace
label edgeToFace()
Propagate from edge to face. Returns total number of faces.
Definition: PatchEdgeFaceWave.C:554
Foam::PatchEdgeFaceWave::getUnsetFaces
label getUnsetFaces() const
Get number of unvisited faces, i.e. faces that were not (yet)
Definition: PatchEdgeFaceWave.C:437
Foam::globalMeshData::globalEdgeSlaves
const labelListList & globalEdgeSlaves() const
Definition: globalMeshData.C:2214
Foam::globalMeshData::syncData
static void syncData(List< Type > &pointData, const labelListList &slaves, const labelListList &transformedSlaves, const mapDistribute &slavesMap, const globalIndexAndTransform &, const CombineOp &cop, const TransformOp &top)
Helper: synchronise data with transforms.
Definition: globalMeshDataTemplates.C:34
Foam::FatalError
error FatalError
Foam::globalMeshData
Various mesh related information for a parallel run. Upon construction, constructs all info using par...
Definition: globalMeshData.H:106
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::PatchEdgeFaceWave::setEdgeInfo
void setEdgeInfo(const labelList &changedEdges, const List< Type > &changedEdgesInfo)
Copy initial data into allEdgeInfo_.
Definition: PatchEdgeFaceWave.C:452
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::mapDistributeBase::constructSize
label constructSize() const
Constructed data size.
Definition: mapDistributeBase.H:244
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
Foam::sumOp
Definition: ops.H:162
Foam::Pout
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
Foam::globalMeshData::globalEdgeTransformedSlaves
const labelListList & globalEdgeTransformedSlaves() const
Definition: globalMeshData.C:2224
Foam::List< Type >
Foam::UList< Type >
Foam::PatchEdgeFaceWave::iterate
label iterate(const label maxIter)
Iterate until no changes or maxIter reached. Returns actual.
Definition: PatchEdgeFaceWave.C:616
Foam::data
Database for solution data, solver performance and other reduced data.
Definition: data.H:52
Foam::PatchEdgeFaceWave::getUnsetEdges
label getUnsetEdges() const
Definition: PatchEdgeFaceWave.C:424