makeFaMesh.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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2016-2017 Wikki Ltd
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 Application
27  makeFaMesh
28 
29 Description
30  A mesh generator for finiteArea mesh.
31 
32 Author
33  Zeljko Tukovic, FAMENA
34  Hrvoje Jasak, Wikki Ltd.
35 
36 \*---------------------------------------------------------------------------*/
37 
38 #include "objectRegistry.H"
39 #include "Time.H"
40 #include "argList.H"
41 #include "OSspecific.H"
42 #include "faMesh.H"
43 #include "fvMesh.H"
44 
45 using namespace Foam;
46 
47 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
48 
49 class faPatchData
50 {
51 public:
52  word name_;
53  word type_;
55  label ownPolyPatchID_;
56  label ngbPolyPatchID_;
58  faPatchData()
59  :
60  name_(word::null),
61  type_(word::null),
62  ownPolyPatchID_(-1),
63  ngbPolyPatchID_(-1)
64  {}
65 };
66 
67 
68 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
69 
70 int main(int argc, char *argv[])
71 {
73  (
74  "A mesh generator for finiteArea mesh"
75  );
76 
77  #include "addRegionOption.H"
79 
80  #include "setRootCase.H"
81  #include "createTime.H"
82  #include "createNamedMesh.H"
83 
84  // Reading faMeshDefinition dictionary
85  IOdictionary faMeshDefinition
86  (
87  IOobject
88  (
89  "faMeshDefinition",
90  runTime.constant(),
91  "faMesh",
92  mesh,
95  )
96  );
97 
98  wordList polyMeshPatches
99  (
100  faMeshDefinition.get<wordList>("polyMeshPatches")
101  );
102 
103  const dictionary& bndDict = faMeshDefinition.subDict("boundary");
104 
105  const wordList faPatchNames(bndDict.toc());
106 
107  List<faPatchData> faPatches(faPatchNames.size()+1);
108 
109  forAll(faPatchNames, patchI)
110  {
111  const dictionary& curPatchDict = bndDict.subDict(faPatchNames[patchI]);
112 
113  faPatches[patchI].name_ = faPatchNames[patchI];
114 
115  faPatches[patchI].type_ = curPatchDict.get<word>("type");
116 
117  const word ownName(curPatchDict.get<word>("ownerPolyPatch"));
118 
119  faPatches[patchI].ownPolyPatchID_ =
120  mesh.boundaryMesh().findPatchID(ownName);
121 
122  if (faPatches[patchI].ownPolyPatchID_ < 0)
123  {
124  FatalErrorIn("makeFaMesh:")
125  << "neighbourPolyPatch " << ownName << " does not exist"
126  << exit(FatalError);
127  }
128 
129  const word neiName(curPatchDict.get<word>("neighbourPolyPatch"));
130 
131  faPatches[patchI].ngbPolyPatchID_ =
132  mesh.boundaryMesh().findPatchID(neiName);
133 
134  if (faPatches[patchI].ngbPolyPatchID_ < 0)
135  {
136  FatalErrorIn("makeFaMesh:")
137  << "neighbourPolyPatch " << neiName << " does not exist"
138  << exit(FatalError);
139  }
140  }
141 
142  // Setting faceLabels list size
143  label size = 0;
144 
145  labelList patchIDs(polyMeshPatches.size(), -1);
146 
147  forAll(polyMeshPatches, patchI)
148  {
149  patchIDs[patchI] =
150  mesh.boundaryMesh().findPatchID(polyMeshPatches[patchI]);
151 
152  if (patchIDs[patchI] < 0)
153  {
154  FatalErrorIn("makeFaMesh:")
155  << "Patch " << polyMeshPatches[patchI] << " does not exist"
156  << exit(FatalError);
157  }
158 
159  size += mesh.boundaryMesh()[patchIDs[patchI]].size();
160  }
161 
162  labelList faceLabels(size, -1);
163 
164  sort(patchIDs);
165 
166 
167  // Filling of faceLabels list
168  label faceI = -1;
169 
170  forAll(polyMeshPatches, patchI)
171  {
172  label start = mesh.boundaryMesh()[patchIDs[patchI]].start();
173 
174  label size = mesh.boundaryMesh()[patchIDs[patchI]].size();
175 
176  for (label i = 0; i < size; ++i)
177  {
178  faceLabels[++faceI] = start + i;
179  }
180  }
181 
182  // Creating faMesh
183  Info << "Create faMesh ... ";
184 
186  (
187  mesh,
188  faceLabels
189  );
190  Info << "Done" << endl;
191 
192 
193  // Determination of faPatch ID for each boundary edge.
194  // Result is in the bndEdgeFaPatchIDs list
195  const indirectPrimitivePatch& patch = areaMesh.patch();
196 
197  labelList faceCells(faceLabels.size(), -1);
198 
199  forAll(faceCells, faceI)
200  {
201  label faceID = faceLabels[faceI];
202 
203  faceCells[faceI] = mesh.faceOwner()[faceID];
204  }
205 
206  labelList meshEdges =
207  patch.meshEdges
208  (
209  mesh.edges(),
210  mesh.cellEdges(),
211  faceCells
212  );
213 
214  const labelListList& edgeFaces = mesh.edgeFaces();
215 
216  const label nTotalEdges = patch.nEdges();
217  const label nInternalEdges = patch.nInternalEdges();
218 
219  labelList bndEdgeFaPatchIDs(nTotalEdges - nInternalEdges, -1);
220 
221  for (label edgeI = nInternalEdges; edgeI < nTotalEdges; ++edgeI)
222  {
223  label curMeshEdge = meshEdges[edgeI];
224 
225  labelList curEdgePatchIDs(2, label(-1));
226 
227  label patchI = -1;
228 
229  forAll(edgeFaces[curMeshEdge], faceI)
230  {
231  label curFace = edgeFaces[curMeshEdge][faceI];
232 
233  label curPatchID = mesh.boundaryMesh().whichPatch(curFace);
234 
235  if (curPatchID != -1)
236  {
237  curEdgePatchIDs[++patchI] = curPatchID;
238  }
239  }
240 
241  for (label pI = 0; pI < faPatches.size() - 1; ++pI)
242  {
243  if
244  (
245  (
246  curEdgePatchIDs[0] == faPatches[pI].ownPolyPatchID_
247  && curEdgePatchIDs[1] == faPatches[pI].ngbPolyPatchID_
248  )
249  ||
250  (
251  curEdgePatchIDs[1] == faPatches[pI].ownPolyPatchID_
252  && curEdgePatchIDs[0] == faPatches[pI].ngbPolyPatchID_
253  )
254  )
255  {
256  bndEdgeFaPatchIDs[edgeI - nInternalEdges] = pI;
257  break;
258  }
259  }
260  }
261 
262 
263  // Set edgeLabels for each faPatch
264  for (label pI=0; pI<(faPatches.size()-1); ++pI)
265  {
266  SLList<label> tmpList;
267 
268  forAll(bndEdgeFaPatchIDs, eI)
269  {
270  if (bndEdgeFaPatchIDs[eI] == pI)
271  {
272  tmpList.append(nInternalEdges + eI);
273  }
274  }
275 
276  faPatches[pI].edgeLabels_ = tmpList;
277  }
278 
279  // Check for undefined edges
280  SLList<label> tmpList;
281 
282  forAll(bndEdgeFaPatchIDs, eI)
283  {
284  if (bndEdgeFaPatchIDs[eI] == -1)
285  {
286  tmpList.append(nInternalEdges + eI);
287  }
288  }
289 
290  if (tmpList.size() > 0)
291  {
292  label pI = faPatches.size()-1;
293 
294  faPatches[pI].name_ = "undefined";
295  faPatches[pI].type_ = "patch";
296  faPatches[pI].edgeLabels_ = tmpList;
297  }
298 
299  // Add good patches to faMesh
300  SLList<faPatch*> faPatchLst;
301 
302  for (label pI = 0; pI < faPatches.size(); ++pI)
303  {
304  faPatches[pI].dict_.add("type", faPatches[pI].type_);
305  faPatches[pI].dict_.add("edgeLabels", faPatches[pI].edgeLabels_);
306  faPatches[pI].dict_.add
307  (
308  "ngbPolyPatchIndex",
309  faPatches[pI].ngbPolyPatchID_
310  );
311 
312  if(faPatches[pI].edgeLabels_.size() > 0)
313  {
314  faPatchLst.append
315  (
317  (
318  faPatches[pI].name_,
319  faPatches[pI].dict_,
320  pI,
321  areaMesh.boundary()
322  ).ptr()
323  );
324  }
325  }
326 
327  word emptyPatchName;
328  if (args.readIfPresent("addEmptyPatch", emptyPatchName))
329  {
330  dictionary emptyPatchDict;
331  emptyPatchDict.add("type", "empty");
332  emptyPatchDict.add("edgeLabels", labelList());
333  emptyPatchDict.add("ngbPolyPatchIndex", -1);
334 
335  faPatchLst.append
336  (
338  (
339  emptyPatchName,
340  emptyPatchDict,
341  faPatchLst.size(),
342  areaMesh.boundary()
343  ).ptr()
344  );
345  }
346 
347  Info << "Add faPatches ... ";
348  areaMesh.addFaPatches(List<faPatch*>(faPatchLst));
349  Info << "Done" << endl;
350 
351  // Writing faMesh
352  Info << "Write finite area mesh ... ";
353  areaMesh.write();
354 
355  Info << "\nEnd" << endl;
356 
357  return 0;
358 }
359 
360 // ************************************************************************* //
Foam::LList::append
void append(const T &item)
Add copy at tail of list.
Definition: LList.H:237
Foam::IOobject::NO_WRITE
Definition: IOobject.H:130
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:71
Foam::IOdictionary
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:54
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:104
OSspecific.H
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::faPatchData::edgeLabels_
labelList edgeLabels_
Definition: faPatchData.H:54
Foam::faPatchData::ngbPolyPatchID_
label ngbPolyPatchID_
Definition: faPatchData.H:53
Foam::primitiveMesh::edgeFaces
const labelListList & edgeFaces() const
Definition: primitiveMeshEdgeFaces.C:33
objectRegistry.H
Foam::argList::addNote
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:413
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:435
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
faMesh.H
Foam::faPatch::New
static autoPtr< faPatch > New(const word &name, const dictionary &dict, const label index, const faBoundaryMesh &bm)
Return a pointer to a new patch created.
Definition: faPatchNew.C:35
Foam::dictionary::get
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:81
Foam::primitiveMesh::edges
const edgeList & edges() const
Return mesh edges. Uses calcEdges.
Definition: primitiveMeshEdges.C:505
Foam::argList::readIfPresent
bool readIfPresent(const word &optName, T &val) const
Read a value from the named option if present.
Definition: argListI.H:302
Foam::polyBoundaryMesh::start
label start() const
The start label of the boundary faces in the polyMesh face list.
Definition: polyBoundaryMesh.C:638
Foam::faPatchData::ownPolyPatchID_
label ownPolyPatchID_
Definition: faPatchData.H:52
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::faPatchData::faPatchData
faPatchData()
Definition: faPatchData.H:55
Foam::LList
Template class for non-intrusive linked lists.
Definition: LList.H:54
Foam::faPatchData::dict_
dictionary dict_
Definition: faPatchData.H:51
Foam::primitiveMesh::cellEdges
const labelListList & cellEdges() const
Definition: primitiveMeshCellEdges.C:120
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
argList.H
Foam::polyMesh::faceOwner
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1076
Foam::dictionary::subDict
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition: dictionary.C:528
Foam::sort
void sort(UList< T > &a)
Definition: UList.C:254
addRegionOption.H
Foam::polyBoundaryMesh::whichPatch
label whichPatch(const label faceIndex) const
Return patch index for a given face label.
Definition: polyBoundaryMesh.C:805
Foam::areaMesh
Mesh data needed to do the Finite Area discretisation.
Definition: areaFaMesh.H:52
Foam::polyBoundaryMesh::findPatchID
label findPatchID(const word &patchName, const bool allowNotFound=true) const
Find patch index given a name, return -1 if not found.
Definition: polyBoundaryMesh.C:766
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
createNamedMesh.H
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
fvMesh.H
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::faPatchData
Class which holds data needed for faPatch construction.
Definition: faPatchData.H:47
Time.H
setRootCase.H
Foam::foamVersion::patch
const std::string patch
OpenFOAM patch number as a std::string.
Foam::List< label >
createTime.H
Foam::faPatchData::name_
word name_
Definition: faPatchData.H:49
Foam::faMesh
Finite area mesh. Used for 2-D non-Euclidian finite area method.
Definition: faMesh.H:77
Foam::dictionary::add
entry * add(entry *entryPtr, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:708
FatalErrorIn
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:367
Foam::dictionary::toc
wordList toc() const
Return the table of contents.
Definition: dictionary.C:670
Foam::argList::noParallel
static void noParallel()
Remove the parallel options.
Definition: argList.C:491
Foam::TimePaths::constant
const word & constant() const
Return constant name.
Definition: TimePathsI.H:88
args
Foam::argList args(argc, argv)
Foam::faceCells
Smooth ATC in cells next to a set of patches supplied by type.
Definition: faceCells.H:56
Foam::faPatchData::type_
word type_
Definition: faPatchData.H:50
Foam::PrimitivePatch
A list of faces which address into the list of points.
Definition: PrimitivePatch.H:85
Foam::IOobject::MUST_READ
Definition: IOobject.H:120