FreeFOAM The Cross-Platform CFD Toolkit
cellTable.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) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 Description
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "cellTable.H"
29 #include <OpenFOAM/IOMap.H>
30 #include <OpenFOAM/OFstream.H>
31 #include <OpenFOAM/wordList.H>
32 #include <OpenFOAM/stringListOps.H>
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 const char* const Foam::cellTable::defaultMaterial_ = "fluid";
37 
38 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
39 
40 Foam::Map<Foam::label> Foam::cellTable::zoneMap() const
41 {
42  Map<label> lookup;
43 
44  label zoneI = 0;
45  forAllConstIter(Map<dictionary>, *this, iter)
46  {
47  lookup.insert(iter.key(), zoneI++);
48  }
49 
50  return lookup;
51 }
52 
53 
54 Foam::wordList Foam::cellTable::namesList() const
55 {
56  Map<word> lookup = names();
57  wordList lst(lookup.size());
58 
59  label zoneI = 0;
60  forAllConstIter(Map<word>, lookup, iter)
61  {
62  lst[zoneI++] = iter();
63  }
64 
65  return lst;
66 }
67 
68 
69 void Foam::cellTable::addDefaults()
70 {
71  forAllIter(Map<dictionary>, *this, iter)
72  {
73  if (!iter().found("MaterialType"))
74  {
75  iter().add("MaterialType", defaultMaterial_);
76  }
77  }
78 }
79 
80 
81 void Foam::cellTable::setEntry
82 (
83  const label& id,
84  const word& keyWord,
85  const word& value
86 )
87 {
88  dictionary dict;
89  dict.add(keyWord, value);
90 
91  iterator iter = find(id);
92  if (iter != end())
93  {
94  iter().merge(dict);
95  }
96  else
97  {
98  insert(id, dict);
99  }
100 }
101 
102 
103 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
104 
106 :
107  Map<dictionary>()
108 {}
109 
110 
112 (
113  const objectRegistry& registry,
114  const word& name,
115  const fileName& instance
116 )
117 :
119 {
120  readDict(registry, name, instance);
121 }
122 
123 
124 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
125 
127 {}
128 
129 
130 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
131 
132 Foam::label Foam::cellTable::append(const dictionary& dict)
133 {
134  label maxId = -1;
135  forAllConstIter(Map<dictionary>, *this, iter)
136  {
137  if (maxId < iter.key())
138  {
139  maxId = iter.key();
140  }
141  }
142 
143  insert(++maxId, dict);
144  return maxId;
145 }
146 
147 
149 {
150  Map<word> lookup;
151 
152  forAllConstIter(Map<dictionary>, *this, iter)
153  {
154  lookup.insert
155  (
156  iter.key(),
157  iter().lookupOrDefault<word>
158  (
159  "Label",
160  "cellTable_" + Foam::name(iter.key())
161  )
162  );
163  }
164 
165  return lookup;
166 }
167 
168 
170 (
171  const List<wordRe>& patterns
172 ) const
173 {
174  Map<word> lookup;
175 
176  forAllConstIter(Map<dictionary>, *this, iter)
177  {
178  word lookupName = iter().lookupOrDefault<word>
179  (
180  "Label",
181  "cellTable_" + Foam::name(iter.key())
182  );
183 
184  if (findStrings(patterns, lookupName))
185  {
186  lookup.insert(iter.key(), lookupName);
187  }
188  }
189 
190  return lookup;
191 }
192 
193 
194 Foam::word Foam::cellTable::name(const label& id) const
195 {
196  word theName("cellTable_" + Foam::name(id));
197 
198  const_iterator iter = find(id);
199  if (iter != end())
200  {
201  iter().readIfPresent("Label", theName);
202  }
203 
204  return theName;
205 }
206 
207 
208 Foam::label Foam::cellTable::findIndex(const word& name) const
209 {
210  if (name.empty())
211  {
212  return -1;
213  }
214 
215  forAllConstIter(Map<dictionary>, *this, iter)
216  {
217  if (iter().lookupOrDefault<word>("Label", word::null) == name)
218  {
219  return iter.key();
220  }
221  }
222 
223  return -1;
224 }
225 
226 
228 {
229  Map<word> lookup;
230 
231  forAllConstIter(Map<dictionary>, *this, iter)
232  {
233  lookup.insert
234  (
235  iter.key(),
236  iter().lookupOrDefault<word>("MaterialType", defaultMaterial_)
237  );
238  }
239 
240  return lookup;
241 }
242 
243 
245 {
246  Map<word> lookup;
247 
248  forAllConstIter(Map<dictionary>, *this, iter)
249  {
250  if
251  (
252  matl
253  == iter().lookupOrDefault<word>("MaterialType", defaultMaterial_)
254  )
255  {
256  lookup.insert
257  (
258  iter.key(),
259  iter().lookupOrDefault<word>
260  (
261  "Label",
262  "cellTable_" + Foam::name(iter.key())
263  )
264  );
265  }
266  }
267 
268  return lookup;
269 }
270 
271 
273 {
274  return selectType("fluid");
275 }
276 
277 
279 {
280  return selectType("solid");
281 }
282 
283 
285 {
286  return selectType("shell");
287 }
288 
289 
290 
291 void Foam::cellTable::setMaterial(const label& id, const word& matlType)
292 {
293  setEntry(id, "MaterialType", matlType);
294 }
295 
296 
297 void Foam::cellTable::setName(const label& id, const word& name)
298 {
299  setEntry(id, "Label", name);
300 }
301 
302 
303 void Foam::cellTable::setName(const label& id)
304 {
305  iterator iter = find(id);
306 
307  if (iter == end() || !iter().found("Label"))
308  {
309  setName(id, "cellTable_" + Foam::name(id));
310  }
311 }
312 
313 
315 (
316  const objectRegistry& registry,
317  const word& name,
318  const fileName& instance
319 )
320 {
321  clear();
322 
323  // read constant/dictName
324  IOMap<dictionary> ioObj
325  (
326  IOobject
327  (
328  name,
329  instance,
330  registry,
333  false
334  )
335  );
336 
337  if (ioObj.headerOk())
338  {
339  *this = ioObj;
340  addDefaults();
341  }
342  else
343  {
344  Info<< "no constant/cellTable information available" << endl;
345  }
346 }
347 
348 
350 (
351  const objectRegistry& registry,
352  const word& name,
353  const fileName& instance
354 ) const
355 {
356  // write constant/dictName
357  IOMap<dictionary> ioObj
358  (
359  IOobject
360  (
361  name,
362  instance,
363  registry,
366  false
367  )
368  );
369 
370  ioObj.note() =
371  "persistent data for thirdParty mesh <-> OpenFOAM translation";
372 
373  Info<< "Writing " << ioObj.name() << " to " << ioObj.objectPath() << endl;
374 
375  OFstream os(ioObj.objectPath());
376  ioObj.writeHeader(os);
377  os << *this;
378 }
379 
380 
381 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
382 
384 {
386  addDefaults();
387 }
388 
389 
391 {
393  addDefaults();
394 }
395 
396 
398 {
399  Map<dictionary> zoneDict;
400 
401  // create cellTableId and cellTable based on cellZones
402  label nZoneCells = 0;
403 
404  wordList zoneNames = mesh.cellZones().names();
405  label unZonedType = zoneNames.size() + 1;
406 
407  // do cell zones
408  forAll(mesh.cellZones(), zoneI)
409  {
410  const cellZone& cZone = mesh.cellZones()[zoneI];
411  nZoneCells += cZone.size();
412 
413  dictionary dict;
414  dict.add("Label", zoneNames[zoneI]);
415  zoneDict.insert(zoneI + 1, dict);
416  }
417 
418  // collect unzoned cells
419  // special case: no zones at all - do entire mesh
420  if (nZoneCells == 0)
421  {
422  zoneDict.clear();
423  unZonedType = 1;
424  }
425 
426  if (mesh.nCells() > nZoneCells)
427  {
428  zoneDict.insert
429  (
430  unZonedType,
431  dictionary(IStringStream("Label cells;")())
432  );
433  }
434 
435  Map<dictionary>::operator=(zoneDict);
436  addDefaults();
437 }
438 
439 
440 // * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
441 
443 (
444  polyMesh& mesh,
445  const labelList& tableIds
446 ) const
447 {
448  Map<label> typeToZone = zoneMap();
449  List<DynamicList<label> > zoneCells(size());
450 
451  forAll(tableIds, cellI)
452  {
453  Map<label>::const_iterator iter = typeToZone.find(tableIds[cellI]);
454  if (iter != typeToZone.end())
455  {
456  zoneCells[iter()].append(cellI);
457  }
458  }
459 
460  // track which zones were actually used
461  labelList zoneUsed(zoneCells.size());
462  wordList zoneNames(namesList());
463 
464  label nZone = 0;
465  forAll(zoneCells, zoneI)
466  {
467  zoneCells[zoneI].shrink();
468  if (zoneCells[zoneI].size())
469  {
470  zoneUsed[nZone++] = zoneI;
471  }
472  }
473  zoneUsed.setSize(nZone);
474 
475  cellZoneMesh& czMesh = mesh.cellZones();
476 
477  czMesh.clear();
478  if (nZone <= 1)
479  {
480  Info<< "cellZones not used" << endl;
481  return;
482  }
483  czMesh.setSize(nZone);
484 
485  forAll(zoneUsed, zoneI)
486  {
487  const label origZoneI = zoneUsed[zoneI];
488 
489  Info<< "cellZone " << zoneI
490  << " (size: " << zoneCells[origZoneI].size()
491  << ") name: " << zoneNames[origZoneI] << endl;
492 
493  czMesh.set
494  (
495  zoneI,
496  new cellZone
497  (
498  zoneNames[origZoneI],
499  zoneCells[origZoneI],
500  zoneI,
501  czMesh
502  )
503  );
504  }
505  czMesh.writeOpt() = IOobject::AUTO_WRITE;
506 }
507 
508 
509 void Foam::cellTable::combine(const dictionary& mapDict, labelList& tableIds)
510 {
511  if (mapDict.empty())
512  {
513  return;
514  }
515 
516  Map<word> origNames(names());
517  labelList mapping(identity(max(origNames.toc()) + 1));
518 
519  bool remap = false;
520  forAllConstIter(dictionary, mapDict, iter)
521  {
522  wordReList patterns(iter().stream());
523 
524  // find all matches
525  Map<word> matches;
526  forAllConstIter(Map<word>, origNames, namesIter)
527  {
528  if (findStrings(patterns, namesIter()))
529  {
530  matches.insert(namesIter.key(), namesIter());
531  }
532  }
533 
534  if (matches.size())
535  {
536  label targetId = this->findIndex(iter().keyword());
537 
538  Info<< "combine cellTable: " << iter().keyword();
539  if (targetId < 0)
540  {
541  // not found - reuse 1st element but with different name
542  targetId = min(matches.toc());
543  operator[](targetId).set("Label", iter().keyword());
544 
545  Info<< " = (";
546  }
547  else
548  {
549  Info<< " += (";
550  }
551 
552 
553  // the mapping and name for targetId is already okay
554  matches.erase(targetId);
555  origNames.erase(targetId);
556 
557  // remove matched names, leaving targetId on 'this'
558  this->erase(matches);
559  origNames.erase(matches);
560 
561  forAllConstIter(Map<word>, matches, matchIter)
562  {
563  mapping[matchIter.key()] = targetId;
564  Info<< " " << matchIter();
565  }
566  Info<< " )" << endl;
567 
568  remap = true;
569  }
570  }
571 
572  if (remap)
573  {
574  inplaceRenumber(mapping, tableIds);
575  }
576 }
577 
578 // ************************ vim: set sw=4 sts=4 et: ************************ //