meshTables: bugfix and cleanup
[OpenFOAM-1.5.x.git] / src / conversion / meshTables / cellTable.C
blobb1c28c73613d05c0c46d6b7d46769a4b2300dc56
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     option) any later version.
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.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM; if not, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 Description
27 \*---------------------------------------------------------------------------*/
29 #include "cellTable.H"
30 #include "IOMap.H"
31 #include "OFstream.H"
32 #include "wordList.H"
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 const char* const Foam::cellTable::defaultMaterial_ = "fluid";
38 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
40 Foam::Map<Foam::label> Foam::cellTable::zoneMap() const
42     Map<label> lookup;
44     label zoneI = 0;
45     forAllConstIter(Map<dictionary>, *this, iter)
46     {
47         lookup.insert(iter.key(), zoneI++);
48     }
50     return lookup;
54 Foam::wordList Foam::cellTable::namesList() const
56     Map<word> lookup = names();
57     wordList lst(lookup.size());
59     label zoneI = 0;
60     forAllConstIter(Map<word>, lookup, iter)
61     {
62         lst[zoneI++] = iter();
63     }
65     return lst;
69 void Foam::cellTable::addDefaults()
71     forAllIter(Map<dictionary>, *this, iter)
72     {
73         if (!iter().found("MaterialType"))
74         {
75             iter().add("MaterialType", defaultMaterial_);
76         }
77     }
81 void Foam::cellTable::setEntry
83     const label& id,
84     const word& keyWord,
85     const word& value
88     dictionary dict;
89     dict.add(keyWord, value);
91     iterator iter = find(id);
92     if (iter != end())
93     {
94         iter().merge(dict);
95     }
96     else
97     {
98         insert(id, dict);
99     }
103 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
105 Foam::cellTable::cellTable()
107     Map<dictionary>()
111 Foam::cellTable::cellTable
113     const objectRegistry& registry,
114     const word& name,
115     const fileName& instance
118     Map<dictionary>()
120     readDict(registry, name, instance);
124 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
126 Foam::cellTable::~cellTable()
130 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
132 Foam::label Foam::cellTable::append(const dictionary& dict)
134     label maxId = -1;
135     forAllConstIter(Map<dictionary>, *this, iter)
136     {
137         if (maxId < iter.key())
138         {
139             maxId = iter.key();
140         }
141     }
143     insert(++maxId, dict);
144     return maxId;
148 Foam::Map<Foam::word> Foam::cellTable::names() const
150     Map<word> lookup;
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     }
165     return lookup;
169 Foam::word Foam::cellTable::name(const label& id) const
171     word theName("cellTable_" + Foam::name(id));
173     const_iterator iter = find(id);
174     if (iter != end())
175     {
176         iter().readIfPresent("Label", theName);
177     }
179     return theName;
183 Foam::label Foam::cellTable::findIndex(const word& name) const
185     if (!name.size())
186     {
187         return -1;
188     }
190     forAllConstIter(Map<dictionary>, *this, iter)
191     {
192         if (iter().lookupOrDefault<word>("Label", word::null) == name)
193         {
194             return iter.key();
195         }
196     }
198     return -1;
202 Foam::Map<Foam::word> Foam::cellTable::materialTypes() const
204     Map<word> lookup;
206     forAllConstIter(Map<dictionary>, *this, iter)
207     {
208         lookup.insert
209         (
210             iter.key(),
211             iter().lookupOrDefault<word>("MaterialType", defaultMaterial_)
212         );
213     }
215     return lookup;
219 Foam::Map<Foam::word> Foam::cellTable::selectType(const word& matl) const
221     Map<word> lookup;
223     forAllConstIter(Map<dictionary>, *this, iter)
224     {
225         if
226         (
227             matl
228          == iter().lookupOrDefault<word>("MaterialType", defaultMaterial_)
229         )
230         {
231             lookup.insert
232             (
233                 iter.key(),
234                 iter().lookupOrDefault<word>
235                 (
236                     "Label",
237                     "cellTable_" + Foam::name(iter.key())
238                 )
239             );
240         }
241     }
243     return lookup;
247 Foam::Map<Foam::word> Foam::cellTable::fluids() const
249     return selectType("fluid");
253 Foam::Map<Foam::word> Foam::cellTable::solids() const
255     return selectType("solid");
259 Foam::Map<Foam::word> Foam::cellTable::shells() const
261     return selectType("shell");
266 void Foam::cellTable::setMaterial(const label& id, const word& matlType)
268     setEntry(id, "MaterialType", matlType);
272 void Foam::cellTable::setName(const label& id, const word& name)
274     setEntry(id, "Label", name);
278 void Foam::cellTable::setName(const label& id)
280     iterator iter = find(id);
282     if (iter == end() || !iter().found("Label"))
283     {
284         setName(id, "cellTable_" + ::Foam::name(id));
285     }
289 void Foam::cellTable::readDict
291     const objectRegistry& registry,
292     const word& name,
293     const fileName& instance
296     clear();
298     // read constant/dictName
299     IOMap<dictionary> ioObj
300     (
301         IOobject
302         (
303             name,
304             instance,
305             registry,
306             IOobject::READ_IF_PRESENT,
307             IOobject::NO_WRITE,
308             false
309         )
310     );
312     if (ioObj.headerOk())
313     {
314         *this = ioObj;
315         addDefaults();
316     }
317     else
318     {
319         Info<< "no constant/cellTable information available" << endl;
320     }
324 void Foam::cellTable::writeDict
326     const objectRegistry& registry,
327     const word& name,
328     const fileName& instance
329 ) const
331     // write constant/dictName
332     IOMap<dictionary> ioObj
333     (
334         IOobject
335         (
336             name,
337             instance,
338             registry,
339             IOobject::NO_READ,
340             IOobject::NO_WRITE,
341             false
342         )
343     );
345     ioObj.note() =
346         "persistent data for thirdParty mesh <-> OpenFOAM translation";
348     Info<< "Writing " << ioObj.name() << " to " << ioObj.objectPath() << endl;
350     OFstream os(ioObj.objectPath());
351     ioObj.writeHeader(os);
352     os << *this;
356 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
358 void Foam::cellTable::operator=(const cellTable& rhs)
360     Map<dictionary>::operator=(rhs);
361     addDefaults();
365 void Foam::cellTable::operator=(const Map<dictionary>& rhs)
367     Map<dictionary>::operator=(rhs);
368     addDefaults();
372 void Foam::cellTable::operator=(const polyMesh& mesh)
374     Map<dictionary> zoneDict;
376     // create cellTableId and cellTable based on cellZones
377     label nZoneCells = 0;
379     wordList zoneNames = mesh.cellZones().names();
380     label unZonedType = zoneNames.size() + 1;
382     // do cell zones
383     forAll(mesh.cellZones(), zoneI)
384     {
385         const cellZone& cZone = mesh.cellZones()[zoneI];
386         nZoneCells += cZone.size();
388         dictionary dict;
389         dict.add("Label", zoneNames[zoneI]);
390         zoneDict.insert(zoneI + 1, dict);
391     }
393     // collect unzoned cells
394     // special case: no zones at all - do entire mesh
395     if (nZoneCells == 0)
396     {
397         zoneDict.clear();
398         unZonedType = 1;
399     }
401     if (mesh.nCells() > nZoneCells)
402     {
403         zoneDict.insert
404         (
405             unZonedType,
406             dictionary(IStringStream("Label cells;")())
407         );
408     }
410     Map<dictionary>::operator=(zoneDict);
411     addDefaults();
415 // * * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * //
417 void Foam::cellTable::addCellZones
419     polyMesh& mesh,
420     const labelList& tableIds
421 ) const
423     Map<label> typeToZone = zoneMap();
424     List<DynamicList<label> > zoneCells(size());
426     forAll(tableIds, cellI)
427     {
428         Map<label>::const_iterator iter = typeToZone.find(tableIds[cellI]);
429         if (iter != typeToZone.end())
430         {
431             zoneCells[iter()].append(cellI);
432         }
433     }
435     // track which zones were actually used
436     labelList zoneUsed(zoneCells.size());
437     wordList  zoneNames(namesList());
439     label nZone = 0;
440     forAll(zoneCells, zoneI)
441     {
442         zoneCells[zoneI].shrink();
443         if (zoneCells[zoneI].size() > 0)
444         {
445             zoneUsed[nZone++] = zoneI;
446         }
447     }
448     zoneUsed.setSize(nZone);
450     cellZoneMesh& czMesh = mesh.cellZones();
452     czMesh.clear();
453     if (nZone <= 1)
454     {
455         Info<< "cellZones not used" << endl;
456         return;
457     }
458     czMesh.setSize(nZone);
460     forAll(zoneUsed, zoneI)
461     {
462         const label origZoneI = zoneUsed[zoneI];
464         Info<< "cellZone " << zoneI
465             << " (size: "  << zoneCells[origZoneI].size()
466             << ") name: "  << zoneNames[origZoneI] << endl;
468         czMesh.set
469         (
470             zoneI,
471             new cellZone
472             (
473                 zoneNames[origZoneI],
474                 zoneCells[origZoneI],
475                 zoneI,
476                 czMesh
477             )
478         );
479     }
480     czMesh.writeOpt() = IOobject::AUTO_WRITE;
484 void Foam::cellTable::combine(const dictionary& mapDict, labelList& tableIds)
486     if (!mapDict.size())
487     {
488         return;
489     }
491     bool remap = false;
492     labelList mapping(identity(max(this->toc()) + 1));
494     forAllConstIter (dictionary, mapDict, iter)
495     {
496         wordList  zoneNames(iter().stream());
497         labelList zoneIndex(zoneNames.size());
499         label nElem = 0;
500         forAll(zoneNames, zoneI)
501         {
502             zoneIndex[nElem] = this->findIndex(zoneNames[zoneI]);
503             if (zoneIndex[nElem] >= 0)
504             {
505                 if (zoneI != nElem)
506                 {
507                     zoneNames[nElem] = zoneNames[zoneI];
508                 }
509                 ++nElem;
510             }
511         }
513         zoneIndex.setSize(nElem);
514         zoneNames.setSize(nElem);
516         if (nElem)
517         {
518             remap = true;
519             label targetId = this->findIndex(iter().keyword());
521             Info<< "combine cellTable: " << iter().keyword();
522             if (targetId >= 0)
523             {
524                 Info<< " += (";
525             }
526             else
527             {
528                 Info<< " = (";
529             }
530             forAll(zoneNames, zoneI)
531             {
532                 Info<< " " << zoneNames[zoneI];
533             }
534             Info<< " )" << endl;
536             // re-use the first element if possible
537             if (targetId < 0)
538             {
539                 targetId = min(zoneIndex);
540                 operator[](targetId).set("Label", iter().keyword());
541             }
543             forAll(zoneIndex, zoneI)
544             {
545                 label idx = zoneIndex[zoneI];
546                 if (idx != targetId && idx >= 0)
547                 {
548                     mapping[idx] = targetId;
549                     this->erase(idx);
550                 }
551             }
552         }
553     }
555     if (remap)
556     {
557         inplaceRenumber(mapping, tableIds);
558     }
561 // ************************************************************************* //