extrudeToRegionMesh.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 | Copyright (C) 2015 OpenCFD Ltd.
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 Application
25  extrudeToRegionMesh
26 
27 Description
28  Extrude faceZones (internal or boundary faces) or faceSets (boundary faces
29  only) into a separate mesh (as a different region).
30 
31  - used to e.g. extrude baffles (extrude internal faces) or create
32  liquid film regions.
33  - if extruding internal faces:
34  - create baffles in original mesh with mappedWall patches
35  - if extruding boundary faces:
36  - convert boundary faces to mappedWall patches
37  - extrude edges of faceZone as a <zone>_sidePatch
38  - extrude edges inbetween different faceZones as a
39  (nonuniformTransform)cyclic <zoneA>_<zoneB>
40  - extrudes into master direction (i.e. away from the owner cell
41  if flipMap is false)
42 
43 \verbatim
44 
45 Internal face extrusion
46 -----------------------
47 
48  +-------------+
49  | |
50  | |
51  +---AAAAAAA---+
52  | |
53  | |
54  +-------------+
55 
56  AAA=faceZone to extrude.
57 
58 
59 For the case of no flipMap the extrusion starts at owner and extrudes
60 into the space of the neighbour:
61 
62  +CCCCCCC+
63  | | <= extruded mesh
64  +BBBBBBB+
65 
66  +-------------+
67  | |
68  | (neighbour) |
69  |___CCCCCCC___| <= original mesh (with 'baffles' added)
70  | BBBBBBB |
71  |(owner side) |
72  | |
73  +-------------+
74 
75  BBB=mapped between owner on original mesh and new extrusion.
76  (zero offset)
77  CCC=mapped between neighbour on original mesh and new extrusion
78  (offset due to the thickness of the extruded mesh)
79 
80 For the case of flipMap the extrusion is the other way around: from the
81 neighbour side into the owner side.
82 
83 
84 Boundary face extrusion
85 -----------------------
86 
87  +--AAAAAAA--+
88  | |
89  | |
90  +-----------+
91 
92  AAA=faceZone to extrude. E.g. slave side is owner side (no flipmap)
93 
94 becomes
95 
96  +CCCCCCC+
97  | | <= extruded mesh
98  +BBBBBBB+
99 
100  +--BBBBBBB--+
101  | | <= original mesh
102  | |
103  +-----------+
104 
105  BBB=mapped between original mesh and new extrusion
106  CCC=polypatch
107 
108 
109 Notes:
110  - when extruding cyclics with only one cell inbetween it does not
111  detect this as a cyclic since the face is the same face. It will
112  only work if the coupled edge extrudes a different face so if there
113  are more than 1 cell inbetween.
114 
115 \endverbatim
116 
117 \*---------------------------------------------------------------------------*/
118 
119 #include "argList.H"
120 #include "fvMesh.H"
121 #include "polyTopoChange.H"
122 #include "OFstream.H"
123 #include "meshTools.H"
124 #include "mappedWallPolyPatch.H"
125 #include "createShellMesh.H"
126 #include "syncTools.H"
127 #include "cyclicPolyPatch.H"
128 #include "wedgePolyPatch.H"
130 #include "extrudeModel.H"
131 #include "globalIndex.H"
132 #include "faceSet.H"
133 
134 #include "volFields.H"
135 #include "surfaceFields.H"
136 #include "pointFields.H"
137 //#include "ReadFields.H"
138 #include "fvMeshTools.H"
139 #include "OBJstream.H"
140 #include "PatchTools.H"
141 
142 using namespace Foam;
143 
144 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
145 
146 label findPatchID(const List<polyPatch*>& newPatches, const word& name)
147 {
148  forAll(newPatches, i)
149  {
150  if (newPatches[i]->name() == name)
151  {
152  return i;
153  }
154  }
155  return -1;
156 }
157 
158 
159 template<class PatchType>
160 label addPatch
161 (
162  const polyBoundaryMesh& patches,
163  const word& patchName,
164  DynamicList<polyPatch*>& newPatches
165 )
166 {
167  label patchI = findPatchID(newPatches, patchName);
168 
169  if (patchI != -1)
170  {
171  if (isA<PatchType>(*newPatches[patchI]))
172  {
173  // Already there
174  return patchI;
175  }
176  else
177  {
179  << "Already have patch " << patchName
180  << " but of type " << newPatches[patchI]->type()
181  << exit(FatalError);
182  }
183  }
184 
185 
186  patchI = newPatches.size();
187 
188  label startFaceI = 0;
189  if (patchI > 0)
190  {
191  const polyPatch& pp = *newPatches.last();
192  startFaceI = pp.start()+pp.size();
193  }
194 
195 
196  newPatches.append
197  (
199  (
200  PatchType::typeName,
201  patchName,
202  0, // size
203  startFaceI, // nFaces
204  patchI,
205  patches
206  ).ptr()
207  );
208 
209  return patchI;
210 }
211 
212 
213 template<class PatchType>
214 label addPatch
215 (
216  const polyBoundaryMesh& patches,
217  const word& patchName,
218  const dictionary& dict,
219  DynamicList<polyPatch*>& newPatches
220 )
221 {
222  label patchI = findPatchID(newPatches, patchName);
223 
224  if (patchI != -1)
225  {
226  if (isA<PatchType>(*newPatches[patchI]))
227  {
228  // Already there
229  return patchI;
230  }
231  else
232  {
234  << "Already have patch " << patchName
235  << " but of type " << newPatches[patchI]->type()
236  << exit(FatalError);
237  }
238  }
239 
240 
241  patchI = newPatches.size();
242 
243  label startFaceI = 0;
244  if (patchI > 0)
245  {
246  const polyPatch& pp = *newPatches.last();
247  startFaceI = pp.start()+pp.size();
248  }
249 
250  dictionary patchDict(dict);
251  patchDict.set("type", PatchType::typeName);
252  patchDict.set("nFaces", 0);
253  patchDict.set("startFace", startFaceI);
254 
255  newPatches.append
256  (
258  (
259  patchName,
260  patchDict,
261  patchI,
262  patches
263  ).ptr()
264  );
265 
266  return patchI;
267 }
268 
269 
270 // Remove zero-sized patches
271 void deleteEmptyPatches(fvMesh& mesh)
272 {
274 
275  wordList masterNames;
276  if (Pstream::master())
277  {
278  masterNames = patches.names();
279  }
280  Pstream::scatter(masterNames);
281 
282 
283  labelList oldToNew(patches.size(), -1);
284  label usedI = 0;
285  label notUsedI = patches.size();
286 
287  // Add all the non-empty, non-processor patches
288  forAll(masterNames, masterI)
289  {
290  label patchI = patches.findPatchID(masterNames[masterI]);
291 
292  if (patchI != -1)
293  {
294  if (isA<processorPolyPatch>(patches[patchI]))
295  {
296  // Similar named processor patch? Not 'possible'.
297  if (patches[patchI].size() == 0)
298  {
299  Pout<< "Deleting processor patch " << patchI
300  << " name:" << patches[patchI].name()
301  << endl;
302  oldToNew[patchI] = --notUsedI;
303  }
304  else
305  {
306  oldToNew[patchI] = usedI++;
307  }
308  }
309  else
310  {
311  // Common patch.
312  if (returnReduce(patches[patchI].size(), sumOp<label>()) == 0)
313  {
314  Pout<< "Deleting patch " << patchI
315  << " name:" << patches[patchI].name()
316  << endl;
317  oldToNew[patchI] = --notUsedI;
318  }
319  else
320  {
321  oldToNew[patchI] = usedI++;
322  }
323  }
324  }
325  }
326 
327  // Add remaining patches at the end
328  forAll(patches, patchI)
329  {
330  if (oldToNew[patchI] == -1)
331  {
332  // Unique to this processor. Note: could check that these are
333  // only processor patches.
334  if (patches[patchI].size() == 0)
335  {
336  Pout<< "Deleting processor patch " << patchI
337  << " name:" << patches[patchI].name()
338  << endl;
339  oldToNew[patchI] = --notUsedI;
340  }
341  else
342  {
343  oldToNew[patchI] = usedI++;
344  }
345  }
346  }
347 
348  fvMeshTools::reorderPatches(mesh, oldToNew, usedI, true);
349 }
350 
351 
353 {
354  // Create dummy system/fv*
355  {
356  IOobject io
357  (
358  "fvSchemes",
359  mesh.time().system(),
360  regionName,
361  mesh,
364  false
365  );
366 
367  Info<< "Testing:" << io.objectPath() << endl;
368 
369  if (!io.headerOk())
370  {
371  Info<< "Writing dummy " << regionName/io.name() << endl;
372  dictionary dummyDict;
373  dictionary divDict;
374  dummyDict.add("divSchemes", divDict);
375  dictionary gradDict;
376  dummyDict.add("gradSchemes", gradDict);
377  dictionary laplDict;
378  dummyDict.add("laplacianSchemes", laplDict);
379 
380  IOdictionary(io, dummyDict).regIOobject::write();
381  }
382  }
383  {
384  IOobject io
385  (
386  "fvSolution",
387  mesh.time().system(),
388  regionName,
389  mesh,
392  false
393  );
394 
395  if (!io.headerOk())
396  {
397  Info<< "Writing dummy " << regionName/io.name() << endl;
398  dictionary dummyDict;
399  IOdictionary(io, dummyDict).regIOobject::write();
400  }
401  }
402 }
403 
404 
405 // Check zone either all internal or all external faces
406 void checkZoneInside
407 (
408  const polyMesh& mesh,
409  const wordList& zoneNames,
410  const labelList& zoneID,
411  const labelList& extrudeMeshFaces,
412  const boolList& isInternal
413 )
414 {
415  forAll(zoneNames, i)
416  {
417  if (isInternal[i])
418  {
419  Info<< "Zone " << zoneNames[i] << " has internal faces" << endl;
420  }
421  else
422  {
423  Info<< "Zone " << zoneNames[i] << " has boundary faces" << endl;
424  }
425  }
426 
427  forAll(extrudeMeshFaces, i)
428  {
429  label faceI = extrudeMeshFaces[i];
430  label zoneI = zoneID[i];
431  if (isInternal[zoneI] != mesh.isInternalFace(faceI))
432  {
434  << "Zone " << zoneNames[zoneI]
435  << " is not consistently all internal or all boundary faces."
436  << " Face " << faceI << " at " << mesh.faceCentres()[faceI]
437  << " is the first occurrence."
438  << exit(FatalError);
439  }
440  }
441 }
442 
443 
444 // To combineReduce a labelList. Filters out duplicates.
445 class uniqueEqOp
446 {
447 
448 public:
449 
450  void operator()(labelList& x, const labelList& y) const
451  {
452  if (x.empty())
453  {
454  if (y.size())
455  {
456  x = y;
457  }
458  }
459  else
460  {
461  forAll(y, yi)
462  {
463  if (findIndex(x, y[yi]) == -1)
464  {
465  label sz = x.size();
466  x.setSize(sz+1);
467  x[sz] = y[yi];
468  }
469  }
470  }
471  }
472 };
473 
474 
475 // Calculate global pp faces per pp edge.
476 labelListList globalEdgeFaces
477 (
478  const polyMesh& mesh,
479  const globalIndex& globalFaces,
480  const primitiveFacePatch& pp,
481  const labelList& ppMeshEdges
482 )
483 {
484  // From mesh edge to global pp face labels.
485  labelListList globalEdgeFaces(ppMeshEdges.size());
486 
487  const labelListList& edgeFaces = pp.edgeFaces();
488 
489  forAll(edgeFaces, edgeI)
490  {
491  const labelList& eFaces = edgeFaces[edgeI];
492 
493  // Store pp face and processor as unique tag.
494  labelList& globalEFaces = globalEdgeFaces[edgeI];
495  globalEFaces.setSize(eFaces.size());
496  forAll(eFaces, i)
497  {
498  globalEFaces[i] = globalFaces.toGlobal(eFaces[i]);
499  }
500  }
501 
502  // Synchronise across coupled edges.
504  (
505  mesh,
506  ppMeshEdges,
507  globalEdgeFaces,
508  uniqueEqOp(),
509  labelList() // null value
510  );
511 
512  return globalEdgeFaces;
513 }
514 
515 
516 // Find a patch face that is not extruded. Return -1 if not found.
517 label findUncoveredPatchFace
518 (
519  const fvMesh& mesh,
520  const UIndirectList<label>& extrudeMeshFaces,// mesh faces that are extruded
521  const label meshEdgeI // mesh edge
522 )
523 {
524  // Make set of extruded faces.
525  labelHashSet extrudeFaceSet(extrudeMeshFaces.size());
526  forAll(extrudeMeshFaces, i)
527  {
528  extrudeFaceSet.insert(extrudeMeshFaces[i]);
529  }
530 
531  const polyBoundaryMesh& pbm = mesh.boundaryMesh();
532  const labelList& eFaces = mesh.edgeFaces()[meshEdgeI];
533  forAll(eFaces, i)
534  {
535  label faceI = eFaces[i];
536  label patchI = pbm.whichPatch(faceI);
537 
538  if
539  (
540  patchI != -1
541  && !pbm[patchI].coupled()
542  && !extrudeFaceSet.found(faceI)
543  )
544  {
545  return faceI;
546  }
547  }
548  return -1;
549 }
550 
551 
552 // Same as findUncoveredPatchFace, except explicitly checks for cyclic faces
553 label findUncoveredCyclicPatchFace
554 (
555  const fvMesh& mesh,
556  const UIndirectList<label>& extrudeMeshFaces,// mesh faces that are extruded
557  const label meshEdgeI // mesh edge
558 )
559 {
560  // Make set of extruded faces.
561  labelHashSet extrudeFaceSet(extrudeMeshFaces.size());
562  forAll(extrudeMeshFaces, i)
563  {
564  extrudeFaceSet.insert(extrudeMeshFaces[i]);
565  }
566 
567  const polyBoundaryMesh& pbm = mesh.boundaryMesh();
568  const labelList& eFaces = mesh.edgeFaces()[meshEdgeI];
569  forAll(eFaces, i)
570  {
571  label faceI = eFaces[i];
572  label patchI = pbm.whichPatch(faceI);
573 
574  if
575  (
576  patchI != -1
577  && isA<cyclicPolyPatch>(pbm[patchI])
578  && !extrudeFaceSet.found(faceI)
579  )
580  {
581  return faceI;
582  }
583  }
584  return -1;
585 }
586 
587 
588 // Calculate per edge min and max zone
589 void calcEdgeMinMaxZone
590 (
591  const fvMesh& mesh,
592  const primitiveFacePatch& extrudePatch,
593  const labelList& extrudeMeshEdges,
594  const labelList& zoneID,
595  const mapDistribute& extrudeEdgeFacesMap,
596  const labelListList& extrudeEdgeGlobalFaces,
597 
598  labelList& minZoneID,
599  labelList& maxZoneID
600 )
601 {
602  // Get zoneIDs in extrudeEdgeGlobalFaces order
603  labelList mappedZoneID(zoneID);
604  extrudeEdgeFacesMap.distribute(mappedZoneID);
605 
606  // Get min and max zone per edge
607  minZoneID.setSize(extrudeEdgeGlobalFaces.size(), labelMax);
608  maxZoneID.setSize(extrudeEdgeGlobalFaces.size(), labelMin);
609 
610  forAll(extrudeEdgeGlobalFaces, edgeI)
611  {
612  const labelList& eFaces = extrudeEdgeGlobalFaces[edgeI];
613  if (eFaces.size())
614  {
615  forAll(eFaces, i)
616  {
617  label zoneI = mappedZoneID[eFaces[i]];
618  minZoneID[edgeI] = min(minZoneID[edgeI], zoneI);
619  maxZoneID[edgeI] = max(maxZoneID[edgeI], zoneI);
620  }
621  }
622  }
624  (
625  mesh,
626  extrudeMeshEdges,
627  minZoneID,
628  minEqOp<label>(),
629  labelMax // null value
630  );
632  (
633  mesh,
634  extrudeMeshEdges,
635  maxZoneID,
636  maxEqOp<label>(),
637  labelMin // null value
638  );
639 }
640 
641 
642 // Count the number of faces in patches that need to be created. Calculates:
643 // zoneSidePatch[zoneI] : the number of side faces to be created
644 // zoneZonePatch[zoneA,zoneB] : the number of faces inbetween zoneA and B
645 // Since this only counts we're not taking the processor patches into
646 // account.
647 void countExtrudePatches
648 (
649  const fvMesh& mesh,
650  const label nZones,
651  const primitiveFacePatch& extrudePatch,
652  const labelList& extrudeMeshFaces,
653  const labelList& extrudeMeshEdges,
654 
655  const labelListList& extrudeEdgeGlobalFaces,
656  const labelList& minZoneID,
657  const labelList& maxZoneID,
658 
659  labelList& zoneSidePatch,
660  labelList& zoneZonePatch
661 )
662 {
663  // Check on master edge for use of zones. Since we only want to know
664  // whether they are being used at all no need to accurately count on slave
665  // edge as well. Just add all together at the end of this routine so it
666  // gets detected at least.
667 
668  forAll(extrudePatch.edgeFaces(), edgeI)
669  {
670  const labelList& eFaces = extrudePatch.edgeFaces()[edgeI];
671 
672  if (eFaces.size() == 2)
673  {
674  // Internal edge - check if inbetween different zones.
675  if (minZoneID[edgeI] != maxZoneID[edgeI])
676  {
677  zoneZonePatch[minZoneID[edgeI]*nZones+maxZoneID[edgeI]]++;
678  }
679  }
680  else if
681  (
682  eFaces.size() == 1
683  && extrudeEdgeGlobalFaces[edgeI].size() == 2
684  )
685  {
686  // Coupled edge - check if inbetween different zones.
687  if (minZoneID[edgeI] != maxZoneID[edgeI])
688  {
689  const edge& e = extrudePatch.edges()[edgeI];
690  const pointField& pts = extrudePatch.localPoints();
692  << "Edge " << edgeI
693  << "at " << pts[e[0]] << pts[e[1]]
694  << " is a coupled edge and inbetween two different zones "
695  << minZoneID[edgeI] << " and " << maxZoneID[edgeI] << endl
696  << " This is currently not supported." << endl;
697 
698  zoneZonePatch[minZoneID[edgeI]*nZones+maxZoneID[edgeI]]++;
699  }
700  }
701  else
702  {
703  // One or more than two edge-faces.
704  // Check whether we are on a mesh edge with external patches. If
705  // so choose any uncovered one. If none found put face in
706  // undetermined zone 'side' patch
707 
708  label faceI = findUncoveredPatchFace
709  (
710  mesh,
711  UIndirectList<label>(extrudeMeshFaces, eFaces),
712  extrudeMeshEdges[edgeI]
713  );
714 
715  if (faceI == -1)
716  {
717  zoneSidePatch[minZoneID[edgeI]]++;
718  }
719  }
720  }
721  // Synchronise decistion. Actual numbers are not important, just make
722  // sure that they're > 0 on all processors.
724  Pstream::listCombineScatter(zoneSidePatch);
726  Pstream::listCombineScatter(zoneZonePatch);
727 }
728 
729 
730 void addCouplingPatches
731 (
732  const fvMesh& mesh,
733  const word& regionName,
734  const word& shellRegionName,
735  const wordList& zoneNames,
736  const wordList& zoneShadowNames,
737  const boolList& isInternal,
738  const labelList& zoneIDs,
739 
740  DynamicList<polyPatch*>& newPatches,
741  labelList& interRegionTopPatch,
742  labelList& interRegionBottomPatch
743 )
744 {
745  Pout<< "Adding coupling patches:" << nl << nl
746  << "patchID\tpatch\ttype" << nl
747  << "-------\t-----\t----"
748  << endl;
749 
750  interRegionTopPatch.setSize(zoneNames.size(), -1);
751  interRegionBottomPatch.setSize(zoneNames.size(), -1);
752 
753  label nOldPatches = newPatches.size();
754  forAll(zoneNames, zoneI)
755  {
756  word interName
757  (
758  regionName
759  +"_to_"
760  +shellRegionName
761  +'_'
762  +zoneNames[zoneI]
763  );
764 
765  if (isInternal[zoneI])
766  {
767  interRegionTopPatch[zoneI] = addPatch<mappedWallPolyPatch>
768  (
769  mesh.boundaryMesh(),
770  interName + "_top",
771  newPatches
772  );
773  Pout<< interRegionTopPatch[zoneI]
774  << '\t' << newPatches[interRegionTopPatch[zoneI]]->name()
775  << '\t' << newPatches[interRegionTopPatch[zoneI]]->type()
776  << nl;
777 
778  interRegionBottomPatch[zoneI] = addPatch<mappedWallPolyPatch>
779  (
780  mesh.boundaryMesh(),
781  interName + "_bottom",
782  newPatches
783  );
784  Pout<< interRegionBottomPatch[zoneI]
785  << '\t' << newPatches[interRegionBottomPatch[zoneI]]->name()
786  << '\t' << newPatches[interRegionBottomPatch[zoneI]]->type()
787  << nl;
788  }
789  else if (zoneShadowNames.size() == 0)
790  {
791  interRegionTopPatch[zoneI] = addPatch<polyPatch>
792  (
793  mesh.boundaryMesh(),
794  zoneNames[zoneI] + "_top",
795  newPatches
796  );
797  Pout<< interRegionTopPatch[zoneI]
798  << '\t' << newPatches[interRegionTopPatch[zoneI]]->name()
799  << '\t' << newPatches[interRegionTopPatch[zoneI]]->type()
800  << nl;
801 
802  interRegionBottomPatch[zoneI] = addPatch<mappedWallPolyPatch>
803  (
804  mesh.boundaryMesh(),
805  interName,
806  newPatches
807  );
808  Pout<< interRegionBottomPatch[zoneI]
809  << '\t' << newPatches[interRegionBottomPatch[zoneI]]->name()
810  << '\t' << newPatches[interRegionBottomPatch[zoneI]]->type()
811  << nl;
812  }
813  else //patch using shadow face zones.
814  {
815  interRegionTopPatch[zoneI] = addPatch<mappedWallPolyPatch>
816  (
817  mesh.boundaryMesh(),
818  zoneShadowNames[zoneI] + "_top",
819  newPatches
820  );
821  Pout<< interRegionTopPatch[zoneI]
822  << '\t' << newPatches[interRegionTopPatch[zoneI]]->name()
823  << '\t' << newPatches[interRegionTopPatch[zoneI]]->type()
824  << nl;
825 
826  interRegionBottomPatch[zoneI] = addPatch<mappedWallPolyPatch>
827  (
828  mesh.boundaryMesh(),
829  interName,
830  newPatches
831  );
832  Pout<< interRegionBottomPatch[zoneI]
833  << '\t' << newPatches[interRegionBottomPatch[zoneI]]->name()
834  << '\t' << newPatches[interRegionBottomPatch[zoneI]]->type()
835  << nl;
836  }
837  }
838  Pout<< "Added " << newPatches.size()-nOldPatches
839  << " inter-region patches." << nl
840  << endl;
841 }
842 
843 
844 // Sets sidePatch[edgeI] to interprocessor or cyclic patch. Adds any
845 // coupled patches if necessary.
846 void addCoupledPatches
847 (
848  const fvMesh& mesh,
849  const primitiveFacePatch& extrudePatch,
850  const labelList& extrudeMeshFaces,
851  const labelList& extrudeMeshEdges,
852  const mapDistribute& extrudeEdgeFacesMap,
853  const labelListList& extrudeEdgeGlobalFaces,
854 
855  labelList& sidePatchID,
856  DynamicList<polyPatch*>& newPatches
857 )
858 {
859  // Calculate opposite processor for coupled edges (only if shared by
860  // two procs). Note: could have saved original globalEdgeFaces structure.
861 
862  // Get procID in extrudeEdgeGlobalFaces order
863  labelList procID(extrudeEdgeGlobalFaces.size(), Pstream::myProcNo());
864  extrudeEdgeFacesMap.distribute(procID);
865 
866  labelList minProcID(extrudeEdgeGlobalFaces.size(), labelMax);
867  labelList maxProcID(extrudeEdgeGlobalFaces.size(), labelMin);
868 
869  forAll(extrudeEdgeGlobalFaces, edgeI)
870  {
871  const labelList& eFaces = extrudeEdgeGlobalFaces[edgeI];
872  if (eFaces.size())
873  {
874  forAll(eFaces, i)
875  {
876  label procI = procID[eFaces[i]];
877  minProcID[edgeI] = min(minProcID[edgeI], procI);
878  maxProcID[edgeI] = max(maxProcID[edgeI], procI);
879  }
880  }
881  }
883  (
884  mesh,
885  extrudeMeshEdges,
886  minProcID,
887  minEqOp<label>(),
888  labelMax // null value
889  );
891  (
892  mesh,
893  extrudeMeshEdges,
894  maxProcID,
895  maxEqOp<label>(),
896  labelMin // null value
897  );
898 
899  Pout<< "Adding processor or cyclic patches:" << nl << nl
900  << "patchID\tpatch" << nl
901  << "-------\t-----"
902  << endl;
903 
904  label nOldPatches = newPatches.size();
905 
906  sidePatchID.setSize(extrudePatch.edgeFaces().size(), -1);
907  forAll(extrudePatch.edgeFaces(), edgeI)
908  {
909  const labelList& eFaces = extrudePatch.edgeFaces()[edgeI];
910 
911  if
912  (
913  eFaces.size() == 1
914  && extrudeEdgeGlobalFaces[edgeI].size() == 2
915  )
916  {
917  // coupled boundary edge. Find matching patch.
918  label nbrProcI = minProcID[edgeI];
919  if (nbrProcI == Pstream::myProcNo())
920  {
921  nbrProcI = maxProcID[edgeI];
922  }
923 
924 
925  if (nbrProcI == Pstream::myProcNo())
926  {
927  // Cyclic patch since both procs the same. This cyclic should
928  // already exist in newPatches so no adding necessary.
929 
930  label faceI = findUncoveredCyclicPatchFace
931  (
932  mesh,
933  UIndirectList<label>(extrudeMeshFaces, eFaces),
934  extrudeMeshEdges[edgeI]
935  );
936 
937  if (faceI != -1)
938  {
940 
941  label newPatchI = findPatchID
942  (
943  newPatches,
944  patches[patches.whichPatch(faceI)].name()
945  );
946 
947  sidePatchID[edgeI] = newPatchI;
948  }
949  else
950  {
952  << "Unable to determine coupled patch addressing"
953  << abort(FatalError);
954  }
955  }
956  else
957  {
958  // Rrocessor patch
959 
960  word name =
961  "procBoundary"
963  + "to"
964  + Foam::name(nbrProcI);
965 
966  sidePatchID[edgeI] = findPatchID(newPatches, name);
967 
968  if (sidePatchID[edgeI] == -1)
969  {
970  dictionary patchDict;
971  patchDict.add("myProcNo", Pstream::myProcNo());
972  patchDict.add("neighbProcNo", nbrProcI);
973 
974  sidePatchID[edgeI] = addPatch<processorPolyPatch>
975  (
976  mesh.boundaryMesh(),
977  name,
978  patchDict,
979  newPatches
980  );
981 
982  Pout<< sidePatchID[edgeI] << '\t' << name
983  << nl;
984  }
985  }
986  }
987  }
988  Pout<< "Added " << newPatches.size()-nOldPatches
989  << " coupled patches." << nl
990  << endl;
991 }
992 
993 
994 void addZoneSidePatches
995 (
996  const fvMesh& mesh,
997  const wordList& zoneNames,
998  const word& oneDPolyPatchType,
999 
1000  DynamicList<polyPatch*>& newPatches,
1001  labelList& zoneSidePatch
1002 )
1003 {
1004  Pout<< "Adding patches for sides on zones:" << nl << nl
1005  << "patchID\tpatch" << nl
1006  << "-------\t-----"
1007  << endl;
1008 
1009  label nOldPatches = newPatches.size();
1010 
1011  forAll(zoneSidePatch, zoneI)
1012  {
1013  if (oneDPolyPatchType != word::null)
1014  {
1015  // Reuse single empty patch.
1016  word patchName;
1017  if (oneDPolyPatchType == "empty")
1018  {
1019  patchName = "oneDEmptyPatch";
1020  zoneSidePatch[zoneI] = addPatch<emptyPolyPatch>
1021  (
1022  mesh.boundaryMesh(),
1023  patchName,
1024  newPatches
1025  );
1026  }
1027  else if (oneDPolyPatchType == "wedge")
1028  {
1029  patchName = "oneDWedgePatch";
1030  zoneSidePatch[zoneI] = addPatch<wedgePolyPatch>
1031  (
1032  mesh.boundaryMesh(),
1033  patchName,
1034  newPatches
1035  );
1036  }
1037  else
1038  {
1040  << "Type " << oneDPolyPatchType << " does not exist "
1041  << exit(FatalError);
1042  }
1043 
1044  Pout<< zoneSidePatch[zoneI] << '\t' << patchName << nl;
1045  }
1046  else if (zoneSidePatch[zoneI] > 0)
1047  {
1048  word patchName = zoneNames[zoneI] + "_" + "side";
1049 
1050  zoneSidePatch[zoneI] = addPatch<polyPatch>
1051  (
1052  mesh.boundaryMesh(),
1053  patchName,
1054  newPatches
1055  );
1056 
1057  Pout<< zoneSidePatch[zoneI] << '\t' << patchName << nl;
1058  }
1059  }
1060  Pout<< "Added " << newPatches.size()-nOldPatches << " zone-side patches."
1061  << nl << endl;
1062 }
1063 
1064 
1065 void addInterZonePatches
1066 (
1067  const fvMesh& mesh,
1068  const wordList& zoneNames,
1069  const bool oneD,
1070 
1071  labelList& zoneZonePatch_min,
1072  labelList& zoneZonePatch_max,
1073  DynamicList<polyPatch*>& newPatches
1074 )
1075 {
1076  Pout<< "Adding inter-zone patches:" << nl << nl
1077  << "patchID\tpatch" << nl
1078  << "-------\t-----"
1079  << endl;
1080 
1081  dictionary transformDict;
1082  transformDict.add
1083  (
1084  "transform",
1086  );
1087 
1088  label nOldPatches = newPatches.size();
1089 
1090  if (!oneD)
1091  {
1092  forAll(zoneZonePatch_min, minZone)
1093  {
1094  for (label maxZone = minZone; maxZone < zoneNames.size(); maxZone++)
1095  {
1096  label index = minZone*zoneNames.size()+maxZone;
1097 
1098  if (zoneZonePatch_min[index] > 0)
1099  {
1100  word minToMax =
1101  zoneNames[minZone]
1102  + "_to_"
1103  + zoneNames[maxZone];
1104  word maxToMin =
1105  zoneNames[maxZone]
1106  + "_to_"
1107  + zoneNames[minZone];
1108 
1109  {
1110  transformDict.set("neighbourPatch", maxToMin);
1111  zoneZonePatch_min[index] =
1112  addPatch<nonuniformTransformCyclicPolyPatch>
1113  (
1114  mesh.boundaryMesh(),
1115  minToMax,
1116  transformDict,
1117  newPatches
1118  );
1119  Pout<< zoneZonePatch_min[index] << '\t' << minToMax
1120  << nl;
1121  }
1122  {
1123  transformDict.set("neighbourPatch", minToMax);
1124  zoneZonePatch_max[index] =
1125  addPatch<nonuniformTransformCyclicPolyPatch>
1126  (
1127  mesh.boundaryMesh(),
1128  maxToMin,
1129  transformDict,
1130  newPatches
1131  );
1132  Pout<< zoneZonePatch_max[index] << '\t' << maxToMin
1133  << nl;
1134  }
1135 
1136  }
1137  }
1138  }
1139  }
1140  Pout<< "Added " << newPatches.size()-nOldPatches << " inter-zone patches."
1141  << nl << endl;
1142 }
1143 
1144 
1145 tmp<pointField> calcOffset
1146 (
1147  const primitiveFacePatch& extrudePatch,
1148  const createShellMesh& extruder,
1149  const polyPatch& pp
1150 )
1151 {
1153 
1154  tmp<pointField> toffsets(new pointField(fc.size()));
1155  pointField& offsets = toffsets();
1156 
1157  forAll(fc, i)
1158  {
1159  label meshFaceI = pp.start()+i;
1160  label patchFaceI = mag(extruder.faceToFaceMap()[meshFaceI])-1;
1161  point patchFc = extrudePatch[patchFaceI].centre
1162  (
1163  extrudePatch.points()
1164  );
1165  offsets[i] = patchFc - fc[i];
1166  }
1167  return toffsets;
1168 }
1169 
1170 
1171 void setCouplingInfo
1172 (
1173  fvMesh& mesh,
1174  const labelList& zoneToPatch,
1175  const word& sampleRegion,
1177  const List<pointField>& offsets
1178 )
1179 {
1181 
1182  List<polyPatch*> newPatches(patches.size(), static_cast<polyPatch*>(NULL));
1183 
1184  forAll(zoneToPatch, zoneI)
1185  {
1186  label patchI = zoneToPatch[zoneI];
1187 
1188  if (patchI != -1)
1189  {
1190  const polyPatch& pp = patches[patchI];
1191 
1192  if (isA<mappedWallPolyPatch>(pp))
1193  {
1194  newPatches[patchI] = new mappedWallPolyPatch
1195  (
1196  pp.name(),
1197  pp.size(),
1198  pp.start(),
1199  patchI,
1200  sampleRegion, // sampleRegion
1201  mode, // sampleMode
1202  pp.name(), // samplePatch
1203  offsets[zoneI], // offset
1204  patches
1205  );
1206  }
1207  }
1208  }
1209 
1210  forAll(newPatches, patchI)
1211  {
1212  if (!newPatches[patchI])
1213  {
1214  newPatches[patchI] = patches[patchI].clone(patches).ptr();
1215  }
1216  }
1217 
1219  mesh.addFvPatches(newPatches, true);
1220 }
1221 
1222 
1223 // Extrude and write geometric properties
1224 void extrudeGeometricProperties
1225 (
1226  const polyMesh& mesh,
1227  const primitiveFacePatch& extrudePatch,
1228  const createShellMesh& extruder,
1229  const polyMesh& regionMesh,
1230  const extrudeModel& model
1231 )
1232 {
1233  const pointIOField patchFaceCentres
1234  (
1235  IOobject
1236  (
1237  "patchFaceCentres",
1238  mesh.pointsInstance(),
1239  mesh.meshSubDir,
1240  mesh,
1242  )
1243  );
1244 
1245  const pointIOField patchEdgeCentres
1246  (
1247  IOobject
1248  (
1249  "patchEdgeCentres",
1250  mesh.pointsInstance(),
1251  mesh.meshSubDir,
1252  mesh,
1254  )
1255  );
1256 
1257  //forAll(extrudePatch.edges(), edgeI)
1258  //{
1259  // const edge& e = extrudePatch.edges()[edgeI];
1260  // Pout<< "Edge:" << e.centre(extrudePatch.localPoints()) << nl
1261  // << "read:" << patchEdgeCentres[edgeI]
1262  // << endl;
1263  //}
1264 
1265 
1266  // Determine edge normals on original patch
1267  labelList patchEdges;
1268  labelList coupledEdges;
1269  PackedBoolList sameEdgeOrientation;
1271  (
1272  extrudePatch,
1274  patchEdges,
1275  coupledEdges,
1276  sameEdgeOrientation
1277  );
1278 
1279  pointField patchEdgeNormals
1280  (
1282  (
1283  mesh,
1284  extrudePatch,
1285  patchEdges,
1286  coupledEdges
1287  )
1288  );
1289 
1290 
1291  pointIOField faceCentres
1292  (
1293  IOobject
1294  (
1295  "faceCentres",
1296  regionMesh.pointsInstance(),
1297  regionMesh.meshSubDir,
1298  regionMesh,
1301  false
1302  ),
1303  regionMesh.nFaces()
1304  );
1305 
1306 
1307  // Work out layers. Guaranteed in columns so no fancy parallel bits.
1308 
1309 
1310  forAll(extruder.faceToFaceMap(), faceI)
1311  {
1312  if (extruder.faceToFaceMap()[faceI] != 0)
1313  {
1314  // 'horizontal' face
1315  label patchFaceI = mag(extruder.faceToFaceMap()[faceI])-1;
1316 
1317  label cellI = regionMesh.faceOwner()[faceI];
1318  if (regionMesh.isInternalFace(faceI))
1319  {
1320  cellI = max(cellI, regionMesh.faceNeighbour()[faceI]);
1321  }
1322 
1323  // Calculate layer from cell numbering (see createShellMesh)
1324  label layerI = (cellI % model.nLayers());
1325 
1326  if
1327  (
1328  !regionMesh.isInternalFace(faceI)
1329  && extruder.faceToFaceMap()[faceI] > 0
1330  )
1331  {
1332  // Top face
1333  layerI++;
1334  }
1335 
1336 
1337  // Recalculate based on extrusion model
1338  faceCentres[faceI] = model
1339  (
1340  patchFaceCentres[patchFaceI],
1341  extrudePatch.faceNormals()[patchFaceI],
1342  layerI
1343  );
1344  }
1345  else
1346  {
1347  // 'vertical face
1348  label patchEdgeI = extruder.faceToEdgeMap()[faceI];
1349  label layerI =
1350  (
1351  regionMesh.faceOwner()[faceI]
1352  % model.nLayers()
1353  );
1354 
1355  // Extrude patch edge centre to this layer
1356  point pt0 = model
1357  (
1358  patchEdgeCentres[patchEdgeI],
1359  patchEdgeNormals[patchEdgeI],
1360  layerI
1361  );
1362  // Extrude patch edge centre to next layer
1363  point pt1 = model
1364  (
1365  patchEdgeCentres[patchEdgeI],
1366  patchEdgeNormals[patchEdgeI],
1367  layerI+1
1368  );
1369 
1370  // Interpolate
1371  faceCentres[faceI] = 0.5*(pt0+pt1);
1372  }
1373  }
1374 
1375  pointIOField cellCentres
1376  (
1377  IOobject
1378  (
1379  "cellCentres",
1380  regionMesh.pointsInstance(),
1381  regionMesh.meshSubDir,
1382  regionMesh,
1385  false
1386  ),
1387  regionMesh.nCells()
1388  );
1389 
1390  forAll(extruder.cellToFaceMap(), cellI)
1391  {
1392  label patchFaceI = extruder.cellToFaceMap()[cellI];
1393 
1394  // Calculate layer from cell numbering (see createShellMesh)
1395  label layerI = (cellI % model.nLayers());
1396 
1397  // Recalculate based on extrusion model
1398  point pt0 = model
1399  (
1400  patchFaceCentres[patchFaceI],
1401  extrudePatch.faceNormals()[patchFaceI],
1402  layerI
1403  );
1404  point pt1 = model
1405  (
1406  patchFaceCentres[patchFaceI],
1407  extrudePatch.faceNormals()[patchFaceI],
1408  layerI+1
1409  );
1410 
1411  // Interpolate
1412  cellCentres[cellI] = 0.5*(pt0+pt1);
1413  }
1414 
1415 
1416  // Bit of checking
1417  if (false)
1418  {
1419  OBJstream faceStr(regionMesh.time().path()/"faceCentres.obj");
1420  OBJstream cellStr(regionMesh.time().path()/"cellCentres.obj");
1421 
1422  forAll(faceCentres, faceI)
1423  {
1424  Pout<< "Model :" << faceCentres[faceI] << endl
1425  << "regionMesh:" << regionMesh.faceCentres()[faceI] << endl;
1426  faceStr.write
1427  (
1428  linePointRef
1429  (
1430  faceCentres[faceI],
1431  regionMesh.faceCentres()[faceI]
1432  )
1433  );
1434  }
1435  forAll(cellCentres, cellI)
1436  {
1437  Pout<< "Model :" << cellCentres[cellI] << endl
1438  << "regionMesh:" << regionMesh.cellCentres()[cellI] << endl;
1439  cellStr.write
1440  (
1441  linePointRef
1442  (
1443  cellCentres[cellI],
1444  regionMesh.cellCentres()[cellI]
1445  )
1446  );
1447  }
1448  }
1449 
1450 
1451 
1452  Info<< "Writing geometric properties for mesh " << regionMesh.name()
1453  << " to " << regionMesh.pointsInstance() << nl
1454  << endl;
1455 
1456  bool ok = faceCentres.write() && cellCentres.write();
1457 
1458  if (!ok)
1459  {
1461  << "Failed writing " << faceCentres.objectPath()
1462  << " and " << cellCentres.objectPath()
1463  << exit(FatalError);
1464  }
1465 }
1466 
1467 
1468 
1469 
1470 int main(int argc, char *argv[])
1471 {
1472  argList::addNote("Create region mesh by extruding a faceZone or faceSet");
1473 
1474  #include "addRegionOption.H"
1475  #include "addOverwriteOption.H"
1476  #include "addDictOption.H"
1477  #include "setRootCase.H"
1478  #include "createTime.H"
1479  #include "createNamedMesh.H"
1480 
1481  if (mesh.boundaryMesh().checkParallelSync(true))
1482  {
1483  List<wordList> allNames(Pstream::nProcs());
1484  allNames[Pstream::myProcNo()] = mesh.boundaryMesh().names();
1485  Pstream::gatherList(allNames);
1486  Pstream::scatterList(allNames);
1487 
1489  << "Patches are not synchronised on all processors."
1490  << " Per processor patches " << allNames
1491  << exit(FatalError);
1492  }
1493 
1494 
1495  const word oldInstance = mesh.pointsInstance();
1496  bool overwrite = args.optionFound("overwrite");
1497 
1498 
1499  const word dictName("extrudeToRegionMeshDict");
1500 
1501  #include "setSystemMeshDictionaryIO.H"
1502 
1504 
1505 
1506  // Point generator
1508 
1509 
1510  // Region
1511  const word shellRegionName(dict.lookup("region"));
1512 
1513  // Faces to extrude - either faceZones or faceSets (boundary faces only)
1514  wordList zoneNames;
1515  wordList zoneShadowNames;
1516 
1517  bool hasZones = dict.found("faceZones");
1518  if (hasZones)
1519  {
1520  dict.lookup("faceZones") >> zoneNames;
1521  dict.readIfPresent("faceZonesShadow", zoneShadowNames);
1522 
1523  // Check
1524  if (dict.found("faceSets"))
1525  {
1527  << "Please supply faces to extrude either through 'faceZones'"
1528  << " or 'faceSets' entry. Found both."
1529  << exit(FatalIOError);
1530  }
1531  }
1532  else
1533  {
1534  dict.lookup("faceSets") >> zoneNames;
1535  dict.readIfPresent("faceSetsShadow", zoneShadowNames);
1536  }
1537 
1538 
1539  mappedPatchBase::sampleMode sampleMode =
1541 
1542  const Switch oneD(dict.lookup("oneD"));
1543  Switch oneDNonManifoldEdges(false);
1544  word oneDPatchType(emptyPolyPatch::typeName);
1545  if (oneD)
1546  {
1547  oneDNonManifoldEdges = dict.lookupOrDefault("nonManifold", false);
1548  dict.lookup("oneDPolyPatchType") >> oneDPatchType;
1549  }
1550 
1551  const Switch adaptMesh(dict.lookup("adaptMesh"));
1552 
1553  if (hasZones)
1554  {
1555  Info<< "Extruding zones " << zoneNames
1556  << " on mesh " << regionName
1557  << " into shell mesh " << shellRegionName
1558  << endl;
1559  }
1560  else
1561  {
1562  Info<< "Extruding faceSets " << zoneNames
1563  << " on mesh " << regionName
1564  << " into shell mesh " << shellRegionName
1565  << endl;
1566  }
1567 
1568  if (shellRegionName == regionName)
1569  {
1571  << "Cannot extrude into same region as mesh." << endl
1572  << "Mesh region : " << regionName << endl
1573  << "Shell region : " << shellRegionName
1574  << exit(FatalIOError);
1575  }
1576 
1577 
1578  if (oneD)
1579  {
1580  if (oneDNonManifoldEdges)
1581  {
1582  Info<< "Extruding as 1D columns with sides in patch type "
1583  << oneDPatchType
1584  << " and connected points (except on non-manifold areas)."
1585  << endl;
1586  }
1587  else
1588  {
1589  Info<< "Extruding as 1D columns with sides in patch type "
1590  << oneDPatchType
1591  << " and duplicated points (overlapping volumes)."
1592  << endl;
1593  }
1594  }
1595 
1596 
1597 
1598 
1600  //IOobjectList objects(mesh, runTime.timeName());
1601  //
1603  //
1604  //PtrList<volScalarField> vsFlds;
1605  //ReadFields(mesh, objects, vsFlds);
1606  //
1607  //PtrList<volVectorField> vvFlds;
1608  //ReadFields(mesh, objects, vvFlds);
1609  //
1610  //PtrList<volSphericalTensorField> vstFlds;
1611  //ReadFields(mesh, objects, vstFlds);
1612  //
1613  //PtrList<volSymmTensorField> vsymtFlds;
1614  //ReadFields(mesh, objects, vsymtFlds);
1615  //
1616  //PtrList<volTensorField> vtFlds;
1617  //ReadFields(mesh, objects, vtFlds);
1618  //
1620  //
1621  //PtrList<surfaceScalarField> ssFlds;
1622  //ReadFields(mesh, objects, ssFlds);
1623  //
1624  //PtrList<surfaceVectorField> svFlds;
1625  //ReadFields(mesh, objects, svFlds);
1626  //
1627  //PtrList<surfaceSphericalTensorField> sstFlds;
1628  //ReadFields(mesh, objects, sstFlds);
1629  //
1630  //PtrList<surfaceSymmTensorField> ssymtFlds;
1631  //ReadFields(mesh, objects, ssymtFlds);
1632  //
1633  //PtrList<surfaceTensorField> stFlds;
1634  //ReadFields(mesh, objects, stFlds);
1635  //
1637  //
1638  //PtrList<pointScalarField> psFlds;
1639  //ReadFields(pointMesh::New(mesh), objects, psFlds);
1640  //
1641  //PtrList<pointVectorField> pvFlds;
1642  //ReadFields(pointMesh::New(mesh), objects, pvFlds);
1643 
1644 
1645 
1646  // Create dummy fv* files
1647  createDummyFvMeshFiles(mesh, shellRegionName);
1648 
1649 
1650  word meshInstance;
1651  if (!overwrite)
1652  {
1653  runTime++;
1654  meshInstance = runTime.timeName();
1655  }
1656  else
1657  {
1658  meshInstance = oldInstance;
1659  }
1660  Info<< "Writing meshes to " << meshInstance << nl << endl;
1661 
1662 
1664 
1665 
1666  // Extract faces to extrude
1667  // ~~~~~~~~~~~~~~~~~~~~~~~~
1668  // Note: zoneID are regions of extrusion. They are not mesh.faceZones
1669  // indices.
1670 
1671  // From extrude zone to mesh zone (or -1 if extruding faceSets)
1672  labelList meshZoneID;
1673  // Per extrude zone whether contains internal or external faces
1674  boolList isInternal(zoneNames.size(), false);
1675 
1676  labelList extrudeMeshFaces;
1677  faceList zoneFaces;
1678  labelList zoneID;
1679  boolList zoneFlipMap;
1680  // Shadow
1681  labelList zoneShadowIDs; // from extrude shadow zone to mesh zone
1682  labelList extrudeMeshShadowFaces;
1683  boolList zoneShadowFlipMap;
1684  labelList zoneShadowID;
1685 
1686  if (hasZones)
1687  {
1688  const faceZoneMesh& faceZones = mesh.faceZones();
1689 
1690  meshZoneID.setSize(zoneNames.size());
1691  forAll(zoneNames, i)
1692  {
1693  meshZoneID[i] = faceZones.findZoneID(zoneNames[i]);
1694  if (meshZoneID[i] == -1)
1695  {
1697  << "Cannot find zone " << zoneNames[i] << endl
1698  << "Valid zones are " << faceZones.names()
1699  << exit(FatalIOError);
1700  }
1701  }
1702  // Collect per face information
1703  label nExtrudeFaces = 0;
1704  forAll(meshZoneID, i)
1705  {
1706  nExtrudeFaces += faceZones[meshZoneID[i]].size();
1707  }
1708  extrudeMeshFaces.setSize(nExtrudeFaces);
1709  zoneFaces.setSize(nExtrudeFaces);
1710  zoneID.setSize(nExtrudeFaces);
1711  zoneFlipMap.setSize(nExtrudeFaces);
1712  nExtrudeFaces = 0;
1713  forAll(meshZoneID, i)
1714  {
1715  const faceZone& fz = faceZones[meshZoneID[i]];
1716  const primitiveFacePatch& fzp = fz();
1717  forAll(fz, j)
1718  {
1719  extrudeMeshFaces[nExtrudeFaces] = fz[j];
1720  zoneFaces[nExtrudeFaces] = fzp[j];
1721  zoneID[nExtrudeFaces] = i;
1722  zoneFlipMap[nExtrudeFaces] = fz.flipMap()[j];
1723  nExtrudeFaces++;
1724 
1725  if (mesh.isInternalFace(fz[j]))
1726  {
1727  isInternal[i] = true;
1728  }
1729  }
1730  }
1731 
1732  // Shadow zone
1733  // ~~~~~~~~~~~
1734 
1735  if (zoneShadowNames.size())
1736  {
1737  zoneShadowIDs.setSize(zoneShadowNames.size());
1738  forAll(zoneShadowNames, i)
1739  {
1740  zoneShadowIDs[i] = faceZones.findZoneID(zoneShadowNames[i]);
1741  if (zoneShadowIDs[i] == -1)
1742  {
1744  << "Cannot find zone " << zoneShadowNames[i] << endl
1745  << "Valid zones are " << faceZones.names()
1746  << exit(FatalIOError);
1747  }
1748  }
1749 
1750  label nShadowFaces = 0;
1751  forAll(zoneShadowIDs, i)
1752  {
1753  nShadowFaces += faceZones[zoneShadowIDs[i]].size();
1754  }
1755 
1756  extrudeMeshShadowFaces.setSize(nShadowFaces);
1757  zoneShadowFlipMap.setSize(nShadowFaces);
1758  zoneShadowID.setSize(nShadowFaces);
1759 
1760  nShadowFaces = 0;
1761  forAll(zoneShadowIDs, i)
1762  {
1763  const faceZone& fz = faceZones[zoneShadowIDs[i]];
1764  forAll(fz, j)
1765  {
1766  extrudeMeshShadowFaces[nShadowFaces] = fz[j];
1767  zoneShadowFlipMap[nShadowFaces] = fz.flipMap()[j];
1768  zoneShadowID[nShadowFaces] = i;
1769  nShadowFaces++;
1770  }
1771  }
1772  }
1773  }
1774  else
1775  {
1776  meshZoneID.setSize(zoneNames.size(), -1);
1777  // Load faceSets
1778  PtrList<faceSet> zones(zoneNames.size());
1779  forAll(zoneNames, i)
1780  {
1781  Info<< "Loading faceSet " << zoneNames[i] << endl;
1782  zones.set(i, new faceSet(mesh, zoneNames[i]));
1783  }
1784 
1785 
1786  // Collect per face information
1787  label nExtrudeFaces = 0;
1788  forAll(zones, i)
1789  {
1790  nExtrudeFaces += zones[i].size();
1791  }
1792  extrudeMeshFaces.setSize(nExtrudeFaces);
1793  zoneFaces.setSize(nExtrudeFaces);
1794  zoneID.setSize(nExtrudeFaces);
1795  zoneFlipMap.setSize(nExtrudeFaces);
1796 
1797  nExtrudeFaces = 0;
1798  forAll(zones, i)
1799  {
1800  const faceSet& fz = zones[i];
1801  forAllConstIter(faceSet, fz, iter)
1802  {
1803  label faceI = iter.key();
1804  if (mesh.isInternalFace(faceI))
1805  {
1807  << "faceSet " << fz.name()
1808  << "contains internal faces."
1809  << " This is not permitted."
1810  << exit(FatalIOError);
1811  }
1812  extrudeMeshFaces[nExtrudeFaces] = faceI;
1813  zoneFaces[nExtrudeFaces] = mesh.faces()[faceI];
1814  zoneID[nExtrudeFaces] = i;
1815  zoneFlipMap[nExtrudeFaces] = false;
1816  nExtrudeFaces++;
1817 
1818  if (mesh.isInternalFace(faceI))
1819  {
1820  isInternal[i] = true;
1821  }
1822  }
1823  }
1824 
1825 
1826  // Shadow zone
1827  // ~~~~~~~~~~~
1828 
1829  PtrList<faceSet> shadowZones(zoneShadowNames.size());
1830  if (zoneShadowNames.size())
1831  {
1832  zoneShadowIDs.setSize(zoneShadowNames.size(), -1);
1833  forAll(zoneShadowNames, i)
1834  {
1835  shadowZones.set(i, new faceSet(mesh, zoneShadowNames[i]));
1836  }
1837 
1838  label nShadowFaces = 0;
1839  forAll(shadowZones, i)
1840  {
1841  nShadowFaces += shadowZones[i].size();
1842  }
1843 
1844  if (nExtrudeFaces != nShadowFaces)
1845  {
1847  << "Extruded faces " << nExtrudeFaces << endl
1848  << "is different from shadow faces. " << nShadowFaces
1849  << "This is not permitted " << endl
1850  << exit(FatalIOError);
1851  }
1852 
1853  extrudeMeshShadowFaces.setSize(nShadowFaces);
1854  zoneShadowFlipMap.setSize(nShadowFaces);
1855  zoneShadowID.setSize(nShadowFaces);
1856 
1857  nShadowFaces = 0;
1858  forAll(shadowZones, i)
1859  {
1860  const faceSet& fz = shadowZones[i];
1861  forAllConstIter(faceSet, fz, iter)
1862  {
1863  label faceI = iter.key();
1864  if (mesh.isInternalFace(faceI))
1865  {
1867  << "faceSet " << fz.name()
1868  << "contains internal faces."
1869  << " This is not permitted."
1870  << exit(FatalIOError);
1871  }
1872  extrudeMeshShadowFaces[nShadowFaces] = faceI;
1873  zoneShadowFlipMap[nShadowFaces] = false;
1874  zoneShadowID[nShadowFaces] = i;
1875  nShadowFaces++;
1876  }
1877  }
1878  }
1879  }
1880  const primitiveFacePatch extrudePatch(zoneFaces.xfer(), mesh.points());
1881 
1882 
1884  Pstream::listCombineScatter(isInternal);
1885 
1886  // Check zone either all internal or all external faces
1887  checkZoneInside(mesh, zoneNames, zoneID, extrudeMeshFaces, isInternal);
1888 
1889 
1890 
1891  const pointField& extrudePoints = extrudePatch.localPoints();
1892  const faceList& extrudeFaces = extrudePatch.localFaces();
1893  const labelListList& edgeFaces = extrudePatch.edgeFaces();
1894 
1895 
1896  Info<< "extrudePatch :"
1897  << " faces:" << extrudePatch.size()
1898  << " points:" << extrudePatch.nPoints()
1899  << " edges:" << extrudePatch.nEdges()
1900  << nl
1901  << endl;
1902 
1903 
1904  // Determine per-extrude-edge info
1905  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1906 
1907  // Corresponding mesh edges
1908  const labelList extrudeMeshEdges
1909  (
1910  extrudePatch.meshEdges
1911  (
1912  mesh.edges(),
1913  mesh.pointEdges()
1914  )
1915  );
1916 
1917  const globalIndex globalExtrudeFaces(extrudePatch.size());
1918 
1919  // Global pp faces per pp edge.
1920  labelListList extrudeEdgeGlobalFaces
1921  (
1922  globalEdgeFaces
1923  (
1924  mesh,
1925  globalExtrudeFaces,
1926  extrudePatch,
1927  extrudeMeshEdges
1928  )
1929  );
1930  List<Map<label> > compactMap;
1931  const mapDistribute extrudeEdgeFacesMap
1932  (
1933  globalExtrudeFaces,
1934  extrudeEdgeGlobalFaces,
1935  compactMap
1936  );
1937 
1938 
1939  // Determine min and max zone per edge
1940  labelList edgeMinZoneID;
1941  labelList edgeMaxZoneID;
1942  calcEdgeMinMaxZone
1943  (
1944  mesh,
1945  extrudePatch,
1946  extrudeMeshEdges,
1947  zoneID,
1948  extrudeEdgeFacesMap,
1949  extrudeEdgeGlobalFaces,
1950 
1951  edgeMinZoneID,
1952  edgeMaxZoneID
1953  );
1954 
1955 
1956 
1957 
1958  DynamicList<polyPatch*> regionPatches(patches.size());
1959  // Copy all non-local patches since these are used on boundary edges of
1960  // the extrusion
1961  forAll(patches, patchI)
1962  {
1963  if (!isA<processorPolyPatch>(patches[patchI]))
1964  {
1965  label newPatchI = regionPatches.size();
1966  regionPatches.append
1967  (
1968  patches[patchI].clone
1969  (
1970  patches,
1971  newPatchI,
1972  0, // size
1973  0 // start
1974  ).ptr()
1975  );
1976  }
1977  }
1978 
1979 
1980  // Add interface patches
1981  // ~~~~~~~~~~~~~~~~~~~~~
1982 
1983  // From zone to interface patch (region side)
1984  labelList interRegionTopPatch;
1985  labelList interRegionBottomPatch;
1986 
1987  addCouplingPatches
1988  (
1989  mesh,
1990  regionName,
1991  shellRegionName,
1992  zoneNames,
1993  zoneShadowNames,
1994  isInternal,
1995  meshZoneID,
1996 
1997  regionPatches,
1998  interRegionTopPatch,
1999  interRegionBottomPatch
2000  );
2001 
2002 
2003  // From zone to interface patch (mesh side)
2004  labelList interMeshTopPatch;
2005  labelList interMeshBottomPatch;
2006 
2007  if (adaptMesh)
2008  {
2009  // Add coupling patches to mesh
2010 
2011  // Clone existing patches
2012  DynamicList<polyPatch*> newPatches(patches.size());
2013  forAll(patches, patchI)
2014  {
2015  newPatches.append(patches[patchI].clone(patches).ptr());
2016  }
2017 
2018  // Add new patches
2019  addCouplingPatches
2020  (
2021  mesh,
2022  regionName,
2023  shellRegionName,
2024  zoneNames,
2025  zoneShadowNames,
2026  isInternal,
2027  meshZoneID,
2028 
2029  newPatches,
2030  interMeshTopPatch,
2031  interMeshBottomPatch
2032  );
2033 
2034  // Add to mesh
2035  mesh.clearOut();
2037  mesh.addFvPatches(newPatches, true);
2038 
2040  }
2041 
2042 
2043  // Patch per extruded face
2044  labelList extrudeTopPatchID(extrudePatch.size());
2045  labelList extrudeBottomPatchID(extrudePatch.size());
2046 
2047  forAll(zoneID, faceI)
2048  {
2049  extrudeTopPatchID[faceI] = interRegionTopPatch[zoneID[faceI]];
2050  extrudeBottomPatchID[faceI] = interRegionBottomPatch[zoneID[faceI]];
2051  }
2052 
2053 
2054 
2055  // Count how many patches on special edges of extrudePatch are necessary
2056  // - zoneXXX_sides
2057  // - zoneXXX_zoneYYY
2058  labelList zoneSidePatch(zoneNames.size(), 0);
2059  // Patch to use for minZone
2060  labelList zoneZonePatch_min(zoneNames.size()*zoneNames.size(), 0);
2061  // Patch to use for maxZone
2062  labelList zoneZonePatch_max(zoneNames.size()*zoneNames.size(), 0);
2063 
2064  countExtrudePatches
2065  (
2066  mesh,
2067  zoneNames.size(),
2068 
2069  extrudePatch, // patch
2070  extrudeMeshFaces, // mesh face per patch face
2071  extrudeMeshEdges, // mesh edge per patch edge
2072 
2073  extrudeEdgeGlobalFaces, // global indexing per patch edge
2074  edgeMinZoneID, // minZone per patch edge
2075  edgeMaxZoneID, // maxZone per patch edge
2076 
2077  zoneSidePatch, // per zone-side num edges that extrude into it
2078  zoneZonePatch_min // per zone-zone num edges that extrude into it
2079  );
2080 
2081  // Now we'll have:
2082  // zoneSidePatch[zoneA] : number of faces needed on the side of zoneA
2083  // zoneZonePatch_min[zoneA,zoneB] : number of faces needed inbetween A,B
2084 
2085 
2086  // Add the zone-side patches.
2087  addZoneSidePatches
2088  (
2089  mesh,
2090  zoneNames,
2091  (oneD ? oneDPatchType : word::null),
2092 
2093  regionPatches,
2094  zoneSidePatch
2095  );
2096 
2097 
2098  // Add the patches inbetween zones
2099  addInterZonePatches
2100  (
2101  mesh,
2102  zoneNames,
2103  oneD,
2104 
2105  zoneZonePatch_min,
2106  zoneZonePatch_max,
2107  regionPatches
2108  );
2109 
2110 
2111  // Sets sidePatchID[edgeI] to interprocessor patch. Adds any
2112  // interprocessor or cyclic patches if necessary.
2113  labelList sidePatchID;
2114  addCoupledPatches
2115  (
2116  mesh,
2117  extrudePatch,
2118  extrudeMeshFaces,
2119  extrudeMeshEdges,
2120  extrudeEdgeFacesMap,
2121  extrudeEdgeGlobalFaces,
2122 
2123  sidePatchID,
2124  regionPatches
2125  );
2126 
2127 
2128 // // Add all the newPatches to the mesh and fields
2129 // // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2130 // {
2131 // forAll(newPatches, patchI)
2132 // {
2133 // Pout<< "Adding patch " << patchI
2134 // << " name:" << newPatches[patchI]->name()
2135 // << endl;
2136 // }
2137 // //label nOldPatches = mesh.boundary().size();
2138 // mesh.clearOut();
2139 // mesh.removeFvBoundary();
2140 // mesh.addFvPatches(newPatches, true);
2141 // //// Add calculated fvPatchFields for the added patches
2142 // //for
2143 // //(
2144 // // label patchI = nOldPatches;
2145 // // patchI < mesh.boundary().size();
2146 // // patchI++
2147 // //)
2148 // //{
2149 // // Pout<< "ADDing calculated to patch " << patchI
2150 // // << endl;
2151 // // addCalculatedPatchFields(mesh);
2152 // //}
2153 // //Pout<< "** Added " << mesh.boundary().size()-nOldPatches
2154 // // << " patches." << endl;
2155 // }
2156 
2157 
2158  // Set patches to use for edges to be extruded into boundary faces
2159  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2160  // In order of edgeFaces: per edge, per originating face the
2161  // patch to use for the side face (from the extruded edge).
2162  // If empty size create an internal face.
2163  labelListList extrudeEdgePatches(extrudePatch.nEdges());
2164 
2165  // Is edge a non-manifold edge
2166  PackedBoolList nonManifoldEdge(extrudePatch.nEdges());
2167 
2168  // Note: logic has to be same as in countExtrudePatches.
2169  forAll(edgeFaces, edgeI)
2170  {
2171  const labelList& eFaces = edgeFaces[edgeI];
2172 
2173  labelList& ePatches = extrudeEdgePatches[edgeI];
2174 
2175  if (oneD)
2176  {
2177  ePatches.setSize(eFaces.size());
2178  forAll(eFaces, i)
2179  {
2180  ePatches[i] = zoneSidePatch[zoneID[eFaces[i]]];
2181  }
2182 
2183  if (oneDNonManifoldEdges)
2184  {
2185  //- Set nonManifoldEdge[edgeI] for non-manifold edges only
2186  // The other option is to have non-manifold edges everywhere
2187  // and generate space overlapping columns of cells.
2188  if (eFaces.size() != 2)
2189  {
2190  nonManifoldEdge[edgeI] = 1;
2191  }
2192  }
2193  else
2194  {
2195  nonManifoldEdge[edgeI] = 1;
2196  }
2197  }
2198  else if (eFaces.size() == 2)
2199  {
2200  label zone0 = zoneID[eFaces[0]];
2201  label zone1 = zoneID[eFaces[1]];
2202 
2203  if (zone0 != zone1) // || (cos(angle) > blabla))
2204  {
2205  label minZone = min(zone0,zone1);
2206  label maxZone = max(zone0,zone1);
2207  label index = minZone*zoneNames.size()+maxZone;
2208 
2209  ePatches.setSize(eFaces.size());
2210 
2211  if (zone0 == minZone)
2212  {
2213  ePatches[0] = zoneZonePatch_min[index];
2214  ePatches[1] = zoneZonePatch_max[index];
2215  }
2216  else
2217  {
2218  ePatches[0] = zoneZonePatch_max[index];
2219  ePatches[1] = zoneZonePatch_min[index];
2220  }
2221 
2222  nonManifoldEdge[edgeI] = 1;
2223  }
2224  }
2225  else if (sidePatchID[edgeI] != -1)
2226  {
2227  // Coupled extrusion
2228  ePatches.setSize(eFaces.size());
2229  forAll(eFaces, i)
2230  {
2231  ePatches[i] = sidePatchID[edgeI];
2232  }
2233  }
2234  else
2235  {
2236  label faceI = findUncoveredPatchFace
2237  (
2238  mesh,
2239  UIndirectList<label>(extrudeMeshFaces, eFaces),
2240  extrudeMeshEdges[edgeI]
2241  );
2242 
2243  if (faceI != -1)
2244  {
2245  label newPatchI = findPatchID
2246  (
2247  regionPatches,
2248  patches[patches.whichPatch(faceI)].name()
2249  );
2250  ePatches.setSize(eFaces.size(), newPatchI);
2251  }
2252  else
2253  {
2254  ePatches.setSize(eFaces.size());
2255  forAll(eFaces, i)
2256  {
2257  ePatches[i] = zoneSidePatch[zoneID[eFaces[i]]];
2258  }
2259  }
2260  nonManifoldEdge[edgeI] = 1;
2261  }
2262  }
2263 
2264 
2265 
2266  // Assign point regions
2267  // ~~~~~~~~~~~~~~~~~~~~
2268 
2269  // Per face, per point the region number.
2270  faceList pointGlobalRegions;
2271  faceList pointLocalRegions;
2272  labelList localToGlobalRegion;
2273 
2275  (
2276  mesh.globalData(),
2277  extrudePatch,
2278  nonManifoldEdge,
2279  false, // keep cyclic separated regions apart
2280 
2281  pointGlobalRegions,
2282  pointLocalRegions,
2283  localToGlobalRegion
2284  );
2285 
2286  // Per local region an originating point
2287  labelList localRegionPoints(localToGlobalRegion.size());
2288  forAll(pointLocalRegions, faceI)
2289  {
2290  const face& f = extrudePatch.localFaces()[faceI];
2291  const face& pRegions = pointLocalRegions[faceI];
2292  forAll(pRegions, fp)
2293  {
2294  localRegionPoints[pRegions[fp]] = f[fp];
2295  }
2296  }
2297 
2298  // Calculate region normals by reducing local region normals
2299  pointField localRegionNormals(localToGlobalRegion.size());
2300  {
2301  pointField localSum(localToGlobalRegion.size(), vector::zero);
2302 
2303  forAll(pointLocalRegions, faceI)
2304  {
2305  const face& pRegions = pointLocalRegions[faceI];
2306  forAll(pRegions, fp)
2307  {
2308  label localRegionI = pRegions[fp];
2309  localSum[localRegionI] += extrudePatch.faceNormals()[faceI];
2310  }
2311  }
2312 
2313  Map<point> globalSum(2*localToGlobalRegion.size());
2314 
2315  forAll(localSum, localRegionI)
2316  {
2317  label globalRegionI = localToGlobalRegion[localRegionI];
2318  globalSum.insert(globalRegionI, localSum[localRegionI]);
2319  }
2320 
2321  // Reduce
2323  Pstream::mapCombineScatter(globalSum);
2324 
2325  forAll(localToGlobalRegion, localRegionI)
2326  {
2327  label globalRegionI = localToGlobalRegion[localRegionI];
2328  localRegionNormals[localRegionI] = globalSum[globalRegionI];
2329  }
2330  localRegionNormals /= mag(localRegionNormals);
2331  }
2332 
2333 
2334  // For debugging: dump hedgehog plot of normals
2335  if (false)
2336  {
2337  OFstream str(runTime.path()/"localRegionNormals.obj");
2338  label vertI = 0;
2339 
2340  scalar thickness = model().sumThickness(1);
2341 
2342  forAll(pointLocalRegions, faceI)
2343  {
2344  const face& f = extrudeFaces[faceI];
2345 
2346  forAll(f, fp)
2347  {
2348  label region = pointLocalRegions[faceI][fp];
2349  const point& pt = extrudePoints[f[fp]];
2350 
2351  meshTools::writeOBJ(str, pt);
2352  vertI++;
2354  (
2355  str,
2356  pt+thickness*localRegionNormals[region]
2357  );
2358  vertI++;
2359  str << "l " << vertI-1 << ' ' << vertI << nl;
2360  }
2361  }
2362  }
2363 
2364 
2365  // Use model to create displacements of first layer
2366  vectorField firstDisp(localRegionNormals.size());
2367  forAll(firstDisp, regionI)
2368  {
2369  //const point& regionPt = regionCentres[regionI];
2370  const point& regionPt = extrudePatch.points()
2371  [
2372  extrudePatch.meshPoints()
2373  [
2374  localRegionPoints[regionI]
2375  ]
2376  ];
2377  const vector& n = localRegionNormals[regionI];
2378  firstDisp[regionI] = model()(regionPt, n, 1) - regionPt;
2379  }
2380 
2381 
2382  // Create a new mesh
2383  // ~~~~~~~~~~~~~~~~~
2384 
2385  createShellMesh extruder
2386  (
2387  extrudePatch,
2388  pointLocalRegions,
2389  localRegionPoints
2390  );
2391 
2392 
2393  autoPtr<mapPolyMesh> shellMap;
2394  fvMesh regionMesh
2395  (
2396  IOobject
2397  (
2398  shellRegionName,
2399  meshInstance,
2400  runTime,
2403  false
2404  ),
2405  xferCopy(pointField()),
2406  xferCopy(faceList()),
2407  xferCopy(labelList()),
2408  xferCopy(labelList()),
2409  false
2410  );
2411 
2412  // Add the new patches
2413  forAll(regionPatches, patchI)
2414  {
2415  polyPatch* ppPtr = regionPatches[patchI];
2416  regionPatches[patchI] = ppPtr->clone(regionMesh.boundaryMesh()).ptr();
2417  delete ppPtr;
2418  }
2419  regionMesh.clearOut();
2420  regionMesh.removeFvBoundary();
2421  regionMesh.addFvPatches(regionPatches, true);
2422 
2423  {
2424  polyTopoChange meshMod(regionPatches.size());
2425 
2426  extruder.setRefinement
2427  (
2428  firstDisp, // first displacement
2429  model().expansionRatio(),
2430  model().nLayers(), // nLayers
2431  extrudeTopPatchID,
2432  extrudeBottomPatchID,
2433  extrudeEdgePatches,
2434  meshMod
2435  );
2436 
2437  // Enforce actual point posititions according to extrudeModel (model)
2438  // (extruder.setRefinement only does fixed expansionRatio)
2439  // The regionPoints and nLayers are looped in the same way as in
2440  // createShellMesh
2441  DynamicList<point>& newPoints = const_cast<DynamicList<point>&>
2442  (
2443  meshMod.points()
2444  );
2445  label meshPointI = extrudePatch.localPoints().size();
2446  forAll(localRegionPoints, regionI)
2447  {
2448  label pointI = localRegionPoints[regionI];
2449  point pt = extrudePatch.localPoints()[pointI];
2450  const vector& n = localRegionNormals[regionI];
2451 
2452  for (label layerI = 1; layerI <= model().nLayers(); layerI++)
2453  {
2454  newPoints[meshPointI++] = model()(pt, n, layerI);
2455  }
2456  }
2457 
2458  shellMap = meshMod.changeMesh
2459  (
2460  regionMesh, // mesh to change
2461  false // inflate
2462  );
2463  }
2464 
2465  // Necessary?
2466  regionMesh.setInstance(meshInstance);
2467 
2468 
2469  // Update numbering on extruder.
2470  extruder.updateMesh(shellMap);
2471 
2472 
2473  // Calculate offsets from shell mesh back to original mesh
2474  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2475 
2476  List<pointField> topOffsets(zoneNames.size());
2477  List<pointField> bottomOffsets(zoneNames.size());
2478 
2479  forAll(regionMesh.boundaryMesh(), patchI)
2480  {
2481  const polyPatch& pp = regionMesh.boundaryMesh()[patchI];
2482 
2483  if (isA<mappedWallPolyPatch>(pp))
2484  {
2485  if (findIndex(interRegionTopPatch, patchI) != -1)
2486  {
2487  label zoneI = findIndex(interRegionTopPatch, patchI);
2488  topOffsets[zoneI] = calcOffset(extrudePatch, extruder, pp);
2489  }
2490  else if (findIndex(interRegionBottomPatch, patchI) != -1)
2491  {
2492  label zoneI = findIndex(interRegionBottomPatch, patchI);
2493  bottomOffsets[zoneI] = calcOffset(extrudePatch, extruder, pp);
2494  }
2495  }
2496  }
2497 
2498 
2499  // Change top and bottom boundary conditions on regionMesh
2500  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2501 
2502  {
2503  // Correct top patches for offset
2504  setCouplingInfo
2505  (
2506  regionMesh,
2507  interRegionTopPatch,
2508  regionName, // name of main mesh
2509  sampleMode, // sampleMode
2510  topOffsets
2511  );
2512 
2513  // Correct bottom patches for offset
2514  setCouplingInfo
2515  (
2516  regionMesh,
2517  interRegionBottomPatch,
2518  regionName,
2519  sampleMode, // sampleMode
2520  bottomOffsets
2521  );
2522 
2523  // Remove any unused patches
2524  deleteEmptyPatches(regionMesh);
2525  }
2526 
2527  // Change top and bottom boundary conditions on main mesh
2528  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2529 
2530  if (adaptMesh)
2531  {
2532  // Correct top patches for offset
2533  setCouplingInfo
2534  (
2535  mesh,
2536  interMeshTopPatch,
2537  shellRegionName, // name of shell mesh
2538  sampleMode, // sampleMode
2539  -topOffsets
2540  );
2541 
2542  // Correct bottom patches for offset
2543  setCouplingInfo
2544  (
2545  mesh,
2546  interMeshBottomPatch,
2547  shellRegionName,
2548  sampleMode,
2549  -bottomOffsets
2550  );
2551  }
2552 
2553 
2554 
2555  // Write addressing from region mesh back to originating patch
2556  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2557 
2558  labelIOList cellToPatchFaceAddressing
2559  (
2560  IOobject
2561  (
2562  "cellToPatchFaceAddressing",
2563  regionMesh.facesInstance(),
2564  regionMesh.meshSubDir,
2565  regionMesh,
2568  false
2569  ),
2570  extruder.cellToFaceMap()
2571  );
2572  cellToPatchFaceAddressing.note() = "cell to patch face addressing";
2573 
2574  labelIOList faceToPatchFaceAddressing
2575  (
2576  IOobject
2577  (
2578  "faceToPatchFaceAddressing",
2579  regionMesh.facesInstance(),
2580  regionMesh.meshSubDir,
2581  regionMesh,
2584  false
2585  ),
2586  extruder.faceToFaceMap()
2587  );
2588  faceToPatchFaceAddressing.note() =
2589  "front/back face + turning index to patch face addressing";
2590 
2591  labelIOList faceToPatchEdgeAddressing
2592  (
2593  IOobject
2594  (
2595  "faceToPatchEdgeAddressing",
2596  regionMesh.facesInstance(),
2597  regionMesh.meshSubDir,
2598  regionMesh,
2601  false
2602  ),
2603  extruder.faceToEdgeMap()
2604  );
2605  faceToPatchEdgeAddressing.note() =
2606  "side face to patch edge addressing";
2607 
2608  labelIOList pointToPatchPointAddressing
2609  (
2610  IOobject
2611  (
2612  "pointToPatchPointAddressing",
2613  regionMesh.facesInstance(),
2614  regionMesh.meshSubDir,
2615  regionMesh,
2618  false
2619  ),
2620  extruder.pointToPointMap()
2621  );
2622  pointToPatchPointAddressing.note() =
2623  "point to patch point addressing";
2624 
2625 
2626  Info<< "Writing mesh " << regionMesh.name()
2627  << " to " << regionMesh.facesInstance() << nl
2628  << endl;
2629 
2630  bool ok =
2631  regionMesh.write()
2632  && cellToPatchFaceAddressing.write()
2633  && faceToPatchFaceAddressing.write()
2634  && faceToPatchEdgeAddressing.write()
2635  && pointToPatchPointAddressing.write();
2636 
2637  if (!ok)
2638  {
2640  << "Failed writing mesh " << regionMesh.name()
2641  << " at location " << regionMesh.facesInstance()
2642  << exit(FatalError);
2643  }
2644 
2645 
2646  // See if we need to extrude coordinates as well
2647  {
2648  autoPtr<pointIOField> patchFaceCentresPtr;
2649 
2650  IOobject io
2651  (
2652  "patchFaceCentres",
2653  mesh.pointsInstance(),
2654  mesh.meshSubDir,
2655  mesh,
2657  );
2658  if (io.headerOk())
2659  {
2660  // Read patchFaceCentres and patchEdgeCentres
2661  Info<< "Reading patch face,edge centres : "
2662  << io.name() << " and patchEdgeCentres" << endl;
2663 
2664  extrudeGeometricProperties
2665  (
2666  mesh,
2667  extrudePatch,
2668  extruder,
2669  regionMesh,
2670  model()
2671  );
2672  }
2673  }
2674 
2675 
2676 
2677 
2678  // Insert baffles into original mesh
2679  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2680 
2681  autoPtr<mapPolyMesh> addBafflesMap;
2682 
2683  if (adaptMesh)
2684  {
2685  polyTopoChange meshMod(mesh);
2686 
2687  // Modify faces to be in bottom (= always coupled) patch
2688  forAll(extrudeMeshFaces, zoneFaceI)
2689  {
2690  label meshFaceI = extrudeMeshFaces[zoneFaceI];
2691  label zoneI = zoneID[zoneFaceI];
2692  bool flip = zoneFlipMap[zoneFaceI];
2693  const face& f = mesh.faces()[meshFaceI];
2694 
2695  if (!flip)
2696  {
2697  meshMod.modifyFace
2698  (
2699  f, // modified face
2700  meshFaceI, // label of face being modified
2701  mesh.faceOwner()[meshFaceI],// owner
2702  -1, // neighbour
2703  false, // face flip
2704  interMeshBottomPatch[zoneI],// patch for face
2705  meshZoneID[zoneI], // zone for face
2706  flip // face flip in zone
2707  );
2708  }
2709  else if (mesh.isInternalFace(meshFaceI))
2710  {
2711  meshMod.modifyFace
2712  (
2713  f.reverseFace(), // modified face
2714  meshFaceI, // label of modified face
2715  mesh.faceNeighbour()[meshFaceI],// owner
2716  -1, // neighbour
2717  true, // face flip
2718  interMeshBottomPatch[zoneI], // patch for face
2719  meshZoneID[zoneI], // zone for face
2720  !flip // face flip in zone
2721  );
2722  }
2723  }
2724 
2725  if (zoneShadowNames.size() > 0) //if there is a top faceZone specified
2726  {
2727  forAll(extrudeMeshFaces, zoneFaceI)
2728  {
2729  label meshFaceI = extrudeMeshShadowFaces[zoneFaceI];
2730  label zoneI = zoneShadowID[zoneFaceI];
2731  bool flip = zoneShadowFlipMap[zoneFaceI];
2732  const face& f = mesh.faces()[meshFaceI];
2733 
2734  if (!flip)
2735  {
2736  meshMod.modifyFace
2737  (
2738  f, // modified face
2739  meshFaceI, // face being modified
2740  mesh.faceOwner()[meshFaceI],// owner
2741  -1, // neighbour
2742  false, // face flip
2743  interMeshTopPatch[zoneI], // patch for face
2744  meshZoneID[zoneI], // zone for face
2745  flip // face flip in zone
2746  );
2747  }
2748  else if (mesh.isInternalFace(meshFaceI))
2749  {
2750  meshMod.modifyFace
2751  (
2752  f.reverseFace(), // modified face
2753  meshFaceI, // label modified face
2754  mesh.faceNeighbour()[meshFaceI],// owner
2755  -1, // neighbour
2756  true, // face flip
2757  interMeshTopPatch[zoneI], // patch for face
2758  meshZoneID[zoneI], // zone for face
2759  !flip // face flip in zone
2760  );
2761  }
2762  }
2763  }
2764  else
2765  {
2766  // Add faces (using same points) to be in top patch
2767  forAll(extrudeMeshFaces, zoneFaceI)
2768  {
2769  label meshFaceI = extrudeMeshFaces[zoneFaceI];
2770  label zoneI = zoneID[zoneFaceI];
2771  bool flip = zoneFlipMap[zoneFaceI];
2772  const face& f = mesh.faces()[meshFaceI];
2773 
2774  if (!flip)
2775  {
2776  if (mesh.isInternalFace(meshFaceI))
2777  {
2778  meshMod.addFace
2779  (
2780  f.reverseFace(), // modified face
2781  mesh.faceNeighbour()[meshFaceI],// owner
2782  -1, // neighbour
2783  -1, // master point
2784  -1, // master edge
2785  meshFaceI, // master face
2786  true, // flip flux
2787  interMeshTopPatch[zoneI], // patch for face
2788  -1, // zone for face
2789  false //face flip in zone
2790  );
2791  }
2792  }
2793  else
2794  {
2795  meshMod.addFace
2796  (
2797  f, // face
2798  mesh.faceOwner()[meshFaceI], // owner
2799  -1, // neighbour
2800  -1, // master point
2801  -1, // master edge
2802  meshFaceI, // master face
2803  false, // flip flux
2804  interMeshTopPatch[zoneI], // patch for face
2805  -1, // zone for face
2806  false // zone flip
2807  );
2808  }
2809  }
2810  }
2811 
2812  // Change the mesh. Change points directly (no inflation).
2813  addBafflesMap = meshMod.changeMesh(mesh, false);
2814 
2815  // Update fields
2816  mesh.updateMesh(addBafflesMap);
2817 
2818 
2819 //XXXXXX
2820 // Update maps! e.g. faceToPatchFaceAddressing
2821 //XXXXXX
2822 
2823  // Move mesh (since morphing might not do this)
2824  if (addBafflesMap().hasMotionPoints())
2825  {
2826  mesh.movePoints(addBafflesMap().preMotionPoints());
2827  }
2828 
2829  mesh.setInstance(meshInstance);
2830 
2831  // Remove any unused patches
2832  deleteEmptyPatches(mesh);
2833 
2834  Info<< "Writing mesh " << mesh.name()
2835  << " to " << mesh.facesInstance() << nl
2836  << endl;
2837 
2838  if (!mesh.write())
2839  {
2841  << "Failed writing mesh " << mesh.name()
2842  << " at location " << mesh.facesInstance()
2843  << exit(FatalError);
2844  }
2845  }
2846 
2847  Info << "End\n" << endl;
2848 
2849  return 0;
2850 }
2851 
2852 
2853 // ************************************************************************* //
Foam::Pstream::mapCombineGather
static void mapCombineGather(const List< commsStruct > &comms, Container &Values, const CombineOp &cop, const int tag, const label comm)
Definition: combineGatherScatter.C:535
Foam::createShellMesh::faceToEdgeMap
const labelList & faceToEdgeMap() const
From region side-face to patch edge. -1 for non-edge faces.
Definition: createShellMesh.H:146
volFields.H
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
Foam::IOdictionary
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:53
Foam::polyMesh::points
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:979
Foam::createShellMesh::pointToPointMap
const labelList & pointToPointMap() const
From region point to patch point.
Definition: createShellMesh.H:152
Foam::IOobject
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:91
meshTools.H
Foam::coupledPolyPatch::transformTypeNames
static const NamedEnum< transformType, 5 > transformTypeNames
Definition: coupledPolyPatch.H:67
Foam::PackedBoolList
A bit-packed bool list.
Definition: PackedBoolList.H:63
Foam::extrudeModel::sumThickness
scalar sumThickness(const label layer) const
Helper: calculate cumulative relative thickness for layer.
Definition: extrudeModel.C:71
Foam::Switch
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:60
mappedWallPolyPatch.H
createDummyFvMeshFiles
void createDummyFvMeshFiles(const polyMesh &mesh, const word &regionName)
Definition: extrudeMesh.C:79
Foam::PrimitivePatch::points
const Field< PointType > & points() const
Return reference to global points.
Definition: PrimitivePatchTemplate.H:282
Foam::PrimitivePatch::edgeFaces
const labelListList & edgeFaces() const
Return edge-face addressing.
Definition: PrimitivePatchTemplate.C:292
Foam::Vector< scalar >::zero
static const Vector zero
Definition: Vector.H:80
Foam::word
A class for handling words, derived from string.
Definition: word.H:59
Foam::IOField< vector >
Foam::labelList
List< label > labelList
A List of labels.
Definition: labelList.H:56
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::OBJstream
OFstream which keeps track of vertices.
Definition: OBJstream.H:53
Foam::polyBoundaryMesh
Foam::polyBoundaryMesh.
Definition: polyBoundaryMesh.H:60
Foam::PrimitivePatch::edges
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
Definition: PrimitivePatchTemplate.C:212
Foam::UIndirectList::size
label size() const
Return the number of elements in the list.
Definition: UIndirectListI.H:43
Foam::IOobject::AUTO_WRITE
@ AUTO_WRITE
Definition: IOobject.H:117
Foam::argList::addNote
static void addNote(const string &)
Add extra notes for the usage information.
Definition: argList.C:139
Foam::extrudeModel
Top level extrusion model class.
Definition: extrudeModel.H:51
cyclicPolyPatch.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:118
Foam::findIndex
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurence of given element and return index,.
Foam::DynamicList
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:56
Foam::meshTools::writeOBJ
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of point.
Definition: meshTools.C:203
Foam::List::xfer
Xfer< List< T > > xfer()
Transfer contents to the Xfer container.
Definition: ListI.H:90
Foam::dictionary::readIfPresent
bool readIfPresent(const word &, T &, bool recursive=false, bool patternMatch=true) const
Find an entry if present, and assign to T.
Definition: dictionaryTemplates.C:94
Foam::fvMesh::addFvPatches
void addFvPatches(const List< polyPatch * > &, const bool validBoundary=true)
Add boundary patches. Constructor helper.
Definition: fvMesh.C:462
wedgePolyPatch.H
Foam::Pstream::scatterList
static void scatterList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Scatter data. Reverse of gatherList.
Definition: gatherScatterList.C:205
Foam::PrimitivePatch::localPoints
const Field< PointType > & localPoints() const
Return pointField of points in patch.
Definition: PrimitivePatchTemplate.C:432
addOverwriteOption.H
Foam::primitiveMesh::edgeFaces
const labelListList & edgeFaces() const
Definition: primitiveMeshEdgeFaces.C:31
globalIndex.H
Foam::labelMax
static const label labelMax
Definition: label.H:62
Foam::UPstream::nProcs
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:387
Foam::PrimitivePatch::nEdges
label nEdges() const
Return number of edges in patch.
Definition: PrimitivePatchTemplate.H:299
Foam::objectRegistry::time
const Time & time() const
Return time.
Definition: objectRegistry.H:117
Foam::polyMesh::meshSubDir
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:309
polyTopoChange.H
Foam::dictionary::lookup
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:449
Foam::PrimitivePatch::meshEdges
labelList meshEdges(const edgeList &allEdges, const labelListList &cellEdges, const labelList &faceCells) const
Return labels of patch edges in the global edge list using.
Definition: PrimitivePatchMeshEdges.C:41
Foam::polyTopoChange
Direct mesh changes based on v1.3 polyTopoChange syntax.
Definition: polyTopoChange.H:97
Foam::edge
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
Foam::maxEqOp
Definition: ops.H:77
Foam::dictionary::lookupOrDefault
T lookupOrDefault(const word &, const T &, bool recursive=false, bool patternMatch=true) const
Find and return a T,.
Definition: dictionaryTemplates.C:33
Foam::polyMesh::facesInstance
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: polyMesh.C:778
Foam::Map
A HashTable to objects of type <T> with a label key.
Definition: PrimitivePatchTemplate.H:68
Foam::regIOobject::write
virtual bool write() const
Write using setting from DB.
Definition: regIOobjectWrite.C:126
Foam::faceSet
A list of face labels.
Definition: faceSet.H:48
Foam::Pstream::scatter
static void scatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Scatter data. Distribute without modification. Reverse of gather.
Definition: gatherScatter.C:147
Foam::fvMesh::removeFvBoundary
void removeFvBoundary()
Remove boundary patches. Warning: fvPatchFields hold ref to.
Definition: fvMesh.C:480
Foam::IOobject::MUST_READ
@ MUST_READ
Definition: IOobject.H:108
Foam::FatalIOError
IOerror FatalIOError
Foam::fvMesh::movePoints
virtual tmp< scalarField > movePoints(const pointField &)
Move points, returns volumes swept by faces in motion.
Definition: fvMesh.C:726
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:421
Foam::polyMesh::clearOut
void clearOut()
Clear all geometry and addressing unnecessary for CFD.
Definition: polyMeshClear.C:173
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
surfaceFields.H
Foam::surfaceFields.
Foam::createShellMesh::faceToFaceMap
const labelList & faceToFaceMap() const
From region face to patch face. Contains turning index:
Definition: createShellMesh.H:140
Foam::primitiveMesh::edges
const edgeList & edges() const
Return mesh edges. Uses calcEdges.
Definition: primitiveMeshEdges.C:353
Foam::mag
dimensioned< scalar > mag(const dimensioned< Type > &)
Foam::primitiveMesh::pointEdges
const labelListList & pointEdges() const
Definition: primitiveMeshPointEdges.C:96
Foam::HashSet< label, Hash< label > >
Foam::extrudeModel::New
static autoPtr< extrudeModel > New(const dictionary &)
Select null constructed.
Definition: extrudeModelNew.C:31
syncTools.H
Foam::extrudeModel::nLayers
label nLayers() const
Definition: extrudeModel.C:59
setSystemMeshDictionaryIO.H
Foam::mode
mode_t mode(const fileName &)
Return the file mode.
Definition: POSIX.C:573
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
Foam::IOobject::NO_WRITE
@ NO_WRITE
Definition: IOobject.H:118
Foam::polyBoundaryMesh::names
wordList names() const
Return a list of patch names.
Definition: polyBoundaryMesh.C:527
forAllConstIter
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:39
OFstream.H
Foam::polyMesh::faceZones
const faceZoneMesh & faceZones() const
Return face zone mesh.
Definition: polyMesh.H:463
addDictOption.H
Foam::SubField
Pre-declare related SubField type.
Definition: Field.H:61
Foam::primitiveMesh::nCells
label nCells() const
Definition: primitiveMeshI.H:64
Foam::fvMesh::write
virtual bool write() const
Write mesh using IO settings from time.
Definition: fvMesh.C:873
dictName
const word dictName("particleTrackDict")
Foam::createShellMesh::updateMesh
void updateMesh(const mapPolyMesh &)
Update any locally stored mesh information.
Definition: createShellMesh.C:906
Foam::polyMesh::pointsInstance
const fileName & pointsInstance() const
Return the current instance directory for points.
Definition: polyMesh.C:772
n
label n
Definition: TABSMDCalcMethod2.H:31
regionName
Foam::word regionName
Definition: createNamedDynamicFvMesh.H:1
createShellMesh.H
Foam::polyBoundaryMesh::checkParallelSync
bool checkParallelSync(const bool report=false) const
Check whether all procs have all patches and in same order. Return.
Definition: polyBoundaryMesh.C:859
Foam::labelMin
static const label labelMin
Definition: label.H:61
Foam::mappedPatchBase::sampleModeNames_
static const NamedEnum< sampleMode, 6 > sampleModeNames_
Definition: mappedPatchBase.H:127
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::dictionary::found
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:304
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::TimePaths::system
const word & system() const
Return system name.
Definition: TimePaths.H:120
Foam::coupledPolyPatch::NOORDERING
@ NOORDERING
Definition: coupledPolyPatch.H:64
Foam::faceZone
A subset of mesh faces organised as a primitive patch.
Definition: faceZone.H:64
Foam::Ostream::write
virtual Ostream & write(const token &)=0
Write next token to stream.
Foam::IOobject::NO_READ
@ NO_READ
Definition: IOobject.H:111
Foam::nl
static const char nl
Definition: Ostream.H:260
Foam::Info
messageStream Info
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
Foam::minEqOp
Definition: ops.H:78
extrudeModel.H
argList.H
Foam::mapDistribute
Class containing processor-to-processor mapping information.
Definition: mapDistribute.H:152
Foam::polyMesh::faceOwner
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1017
faceSet.H
addRegionOption.H
Foam::fvMesh::updateMesh
virtual void updateMesh(const mapPolyMesh &mpm)
Update mesh corresponding to the given map.
Definition: fvMesh.C:802
Foam::ZoneMesh< faceZone, polyMesh >
Foam::polyBoundaryMesh::whichPatch
label whichPatch(const label faceIndex) const
Return patch index for a given face label.
Definition: polyBoundaryMesh.C:703
Foam::IOobject::name
const word & name() const
Return name.
Definition: IOobject.H:273
main
int main(int argc, char *argv[])
Definition: postCalc.C:54
Foam::PtrList
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: List.H:61
Foam::fvMeshTools::reorderPatches
static void reorderPatches(fvMesh &, const labelList &oldToNew, const label nPatches, const bool validBoundary)
Reorder and remove trailing patches. If validBoundary call is parallel.
Definition: fvMeshTools.C:327
findPatchID
label findPatchID(const polyBoundaryMesh &patches, const word &name)
Definition: extrudeMesh.C:132
Foam::orEqOp
Definition: ops.H:82
Foam::mapDistribute::distribute
void distribute(List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Distribute data using default commsType.
Definition: mapDistributeTemplates.C:155
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::PrimitivePatch::nPoints
label nPoints() const
Return number of points supporting patch faces.
Definition: PrimitivePatchTemplate.H:293
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:137
createNamedMesh.H
Foam::polyPatch::New
static autoPtr< polyPatch > New(const word &patchType, const word &name, const label size, const label start, const label index, const polyBoundaryMesh &bm)
Return a pointer to a new patch created on freestore from.
Definition: polyPatchNew.C:32
Foam::createShellMesh::setRefinement
void setRefinement(const pointField &firstLayerThickness, const scalar expansionRatio, const label nLayers, const labelList &topPatchID, const labelList &bottomPatchID, const labelListList &extrudeEdgePatches, polyTopoChange &meshMod)
Play commands into polyTopoChange to create layer mesh.
Definition: createShellMesh.C:446
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
Foam::plusEqOp
Definition: ops.H:71
Foam::createShellMesh::cellToFaceMap
const labelList & cellToFaceMap() const
From region cell to patch face. Consecutively added so.
Definition: createShellMesh.H:129
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
fvMesh.H
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::globalIndex
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:63
Foam::ZoneMesh::findZoneID
label findZoneID(const word &zoneName) const
Find zone index given a name.
Definition: ZoneMesh.C:348
Foam::e
const double e
Elementary charge.
Definition: doubleFloat.H:94
Foam::polyPatch::start
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:312
Foam::mappedWallPolyPatch
Determines a mapping between patch face centres and mesh cell or face centres and processors they're ...
Definition: mappedWallPolyPatch.H:57
Foam::ZoneMesh::names
wordList names() const
Return a list of zone names.
Definition: ZoneMesh.C:263
Foam::DynamicList::append
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Foam::polyPatch::clone
virtual autoPtr< polyPatch > clone(const polyBoundaryMesh &bm) const
Construct and return a clone, resetting the boundary mesh.
Definition: polyPatch.H:231
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::OFstream
Output to file stream.
Definition: OFstream.H:81
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:405
Foam::UPstream::master
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:399
Foam::polyMesh::setInstance
void setInstance(const fileName &)
Set the instance for mesh files.
Definition: polyMeshIO.C:32
Foam::Pstream::listCombineGather
static void listCombineGather(const List< commsStruct > &comms, List< T > &Value, const CombineOp &cop, const int tag, const label comm)
Definition: combineGatherScatter.C:282
Foam::max
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
Foam::List::setSize
void setSize(const label)
Reset size of List.
Foam::autoPtr
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:117
setRootCase.H
Foam::primitiveMesh::cellCentres
const vectorField & cellCentres() const
Definition: primitiveMeshCellCentresAndVols.C:211
Foam::polyMesh::faces
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1004
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
Foam::Pstream::gatherList
static void gatherList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Gather data but keep individual values separate.
Definition: gatherScatterList.C:49
Foam::syncTools::syncEdgeList
static void syncEdgeList(const polyMesh &, List< T > &, const CombineOp &cop, const T &nullValue, const TransformOp &top)
Synchronize values on all mesh edges.
Definition: syncToolsTemplates.C:1141
Foam::primitiveMesh::nFaces
label nFaces() const
Definition: primitiveMeshI.H:58
Foam::sumOp
Definition: ops.H:162
Foam::Time::path
fileName path() const
Return path.
Definition: Time.H:281
Foam::Pstream::mapCombineScatter
static void mapCombineScatter(const List< commsStruct > &comms, Container &Values, const int tag, const label comm)
Scatter data. Reverse of combineGather.
Definition: combineGatherScatter.C:636
Foam::polyPatch::faceCentres
const vectorField::subField faceCentres() const
Return face centres.
Definition: polyPatch.C:308
Foam::Pout
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
fvMeshTools.H
Foam::PrimitivePatch::faceNormals
const Field< PointType > & faceNormals() const
Return face normals for patch.
Definition: PrimitivePatchTemplate.C:520
f
labelList f(nPoints)
Foam::faceList
List< face > faceList
Definition: faceListFwd.H:43
Foam::xferCopy
Xfer< T > xferCopy(const T &)
Construct by copying the contents of the arg.
Foam::Vector< scalar >
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::globalMeshData::coupledPatch
const indirectPrimitivePatch & coupledPatch() const
Return patch of all coupled faces.
Definition: globalMeshData.C:2046
Foam::primitiveMesh::isInternalFace
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
Definition: primitiveMeshI.H:70
Foam::primitiveMesh::faceCentres
const vectorField & faceCentres() const
Definition: primitiveMeshFaceCentresAndAreas.C:130
Foam::IOList< label >
Foam::word::null
static const word null
An empty word.
Definition: word.H:77
createTime.H
x
x
Definition: LISASMDCalcMethod2.H:52
Foam::line
A line primitive.
Definition: line.H:56
Foam::argList::optionFound
bool optionFound(const word &opt) const
Return true if the named option is found.
Definition: argListI.H:108
Foam::createShellMesh
Creates mesh by extruding a patch.
Definition: createShellMesh.H:59
nonuniformTransformCyclicPolyPatch.H
Foam::fvMesh::time
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:243
Foam::PrimitivePatch::localFaces
const List< Face > & localFaces() const
Return patch faces addressing into local point list.
Definition: PrimitivePatchTemplate.C:372
Foam::UIndirectList
A List with indirect addressing.
Definition: fvMatrix.H:106
patches
patches[0]
Definition: createSingleCellMesh.H:36
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:330
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::createShellMesh::calcPointRegions
static void calcPointRegions(const globalMeshData &globalData, const primitiveFacePatch &patch, const PackedBoolList &nonManifoldEdge, const bool syncNonCollocated, faceList &pointGlobalRegions, faceList &pointLocalRegions, labelList &localToGlobalRegion)
Helper: calculate point regions. The point region is the.
Definition: createShellMesh.C:154
Foam::polyMesh::globalData
const globalMeshData & globalData() const
Return parallel info.
Definition: polyMesh.C:1143
Foam::Pstream::listCombineScatter
static void listCombineScatter(const List< commsStruct > &comms, List< T > &Value, const int tag, const label comm)
Scatter data. Reverse of combineGather.
Definition: combineGatherScatter.C:417
Foam::PrimitivePatch::meshPoints
const labelList & meshPoints() const
Return labelList of mesh points in patch.
Definition: PrimitivePatchTemplate.C:392
Foam::PatchTools::edgeNormals
static tmp< pointField > edgeNormals(const polyMesh &, const PrimitivePatch< Face, FaceList, PointField, PointType > &, const labelList &patchEdges, const labelList &coupledEdges)
Return parallel consistent edge normals for patches using mesh points.
args
Foam::argList args(argc, argv)
Foam::faceZone::flipMap
const boolList & flipMap() const
Return face flip map.
Definition: faceZone.H:249
Foam::min
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
Foam::patchIdentifier::name
const word & name() const
Return name.
Definition: patchIdentifier.H:109
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:259
Foam::mappedPatchBase::sampleMode
sampleMode
Mesh items to sample.
Definition: mappedPatchBase.H:109
pointFields.H
OBJstream.H
dictIO
IOobject dictIO(dictName, runTime.constant(), mesh, IOobject::MUST_READ_IF_MODIFIED, IOobject::NO_WRITE)
Foam::name
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
Foam::polyMesh::faceNeighbour
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition: polyMesh.C:1023
Foam::dictionary::add
bool add(entry *, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:729
Foam::fvMesh::clearOut
void clearOut()
Clear all geometry and addressing.
Definition: fvMesh.C:231
Foam::globalIndex::toGlobal
label toGlobal(const label i) const
From local to global.
Definition: globalIndexI.H:82
Foam::fvMesh::name
const word & name() const
Return reference to name.
Definition: fvMesh.H:257
Foam::PatchTools::matchEdges
static void matchEdges(const PrimitivePatch< Face1, FaceList1, PointField1, PointType1 > &p1, const PrimitivePatch< Face2, FaceList2, PointField2, PointType2 > &p2, labelList &p1EdgeLabels, labelList &p2EdgeLabels, PackedBoolList &sameOrientation)
Find corresponding edges on patches sharing the same points.
Definition: PatchToolsMatch.C:88
y
scalar y
Definition: LISASMDCalcMethod1.H:14
Foam::PrimitivePatch
A list of faces which address into the list of points.
Definition: PrimitivePatchTemplate.H:88
Foam::dictionary::set
void set(entry *)
Assign a new entry, overwrite any existing entry.
Definition: dictionary.C:856