ENH: autoLayerDriver: better layering information message
[OpenFOAM-2.0.x.git] / src / conversion / meshTables / cellTable.C
blob04af94aeb52acf300c7ee979731c7e05a334396b
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
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
13     the Free Software Foundation, either version 3 of the License, or
14     (at your 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, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "cellTable.H"
27 #include "IOMap.H"
28 #include "OFstream.H"
29 #include "wordList.H"
30 #include "stringListOps.H"
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 const char* const Foam::cellTable::defaultMaterial_ = "fluid";
36 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
38 Foam::Map<Foam::label> Foam::cellTable::zoneMap() const
40     Map<label> lookup;
42     label zoneI = 0;
43     forAllConstIter(Map<dictionary>, *this, iter)
44     {
45         lookup.insert(iter.key(), zoneI++);
46     }
48     return lookup;
52 Foam::wordList Foam::cellTable::namesList() const
54     Map<word> lookup = names();
55     wordList lst(lookup.size());
57     label zoneI = 0;
58     forAllConstIter(Map<word>, lookup, iter)
59     {
60         lst[zoneI++] = iter();
61     }
63     return lst;
67 void Foam::cellTable::addDefaults()
69     forAllIter(Map<dictionary>, *this, iter)
70     {
71         if (!iter().found("MaterialType"))
72         {
73             iter().add("MaterialType", defaultMaterial_);
74         }
75     }
79 void Foam::cellTable::setEntry
81     const label id,
82     const word& keyWord,
83     const word& value
86     dictionary dict;
87     dict.add(keyWord, value);
89     iterator iter = find(id);
90     if (iter != end())
91     {
92         iter().merge(dict);
93     }
94     else
95     {
96         insert(id, dict);
97     }
101 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
103 Foam::cellTable::cellTable()
105     Map<dictionary>()
109 Foam::cellTable::cellTable
111     const objectRegistry& registry,
112     const word& name,
113     const fileName& instance
116     Map<dictionary>()
118     readDict(registry, name, instance);
122 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
124 Foam::cellTable::~cellTable()
128 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
130 Foam::label Foam::cellTable::append(const dictionary& dict)
132     label maxId = -1;
133     forAllConstIter(Map<dictionary>, *this, iter)
134     {
135         if (maxId < iter.key())
136         {
137             maxId = iter.key();
138         }
139     }
141     insert(++maxId, dict);
142     return maxId;
146 Foam::Map<Foam::word> Foam::cellTable::names() const
148     Map<word> lookup;
150     forAllConstIter(Map<dictionary>, *this, iter)
151     {
152         lookup.insert
153         (
154             iter.key(),
155             iter().lookupOrDefault<word>
156             (
157                 "Label",
158                 "cellTable_" + Foam::name(iter.key())
159             )
160         );
161     }
163     return lookup;
167 Foam::Map<Foam::word> Foam::cellTable::names
169     const UList<wordRe>& patterns
170 ) const
172     Map<word> lookup;
174     forAllConstIter(Map<dictionary>, *this, iter)
175     {
176         word lookupName = iter().lookupOrDefault<word>
177         (
178             "Label",
179             "cellTable_" + Foam::name(iter.key())
180         );
182         if (findStrings(patterns, lookupName))
183         {
184             lookup.insert(iter.key(), lookupName);
185         }
186     }
188     return lookup;
192 Foam::word Foam::cellTable::name(const label id) const
194     word theName("cellTable_" + Foam::name(id));
196     const_iterator iter = find(id);
197     if (iter != end())
198     {
199         iter().readIfPresent("Label", theName);
200     }
202     return theName;
206 Foam::label Foam::cellTable::findIndex(const word& name) const
208     if (name.empty())
209     {
210         return -1;
211     }
213     forAllConstIter(Map<dictionary>, *this, iter)
214     {
215         if (iter().lookupOrDefault<word>("Label", word::null) == name)
216         {
217             return iter.key();
218         }
219     }
221     return -1;
225 Foam::Map<Foam::word> Foam::cellTable::materialTypes() const
227     Map<word> lookup;
229     forAllConstIter(Map<dictionary>, *this, iter)
230     {
231         lookup.insert
232         (
233             iter.key(),
234             iter().lookupOrDefault<word>("MaterialType", defaultMaterial_)
235         );
236     }
238     return lookup;
242 Foam::Map<Foam::word> Foam::cellTable::selectType(const word& matl) const
244     Map<word> lookup;
246     forAllConstIter(Map<dictionary>, *this, iter)
247     {
248         if
249         (
250             matl
251          == iter().lookupOrDefault<word>("MaterialType", defaultMaterial_)
252         )
253         {
254             lookup.insert
255             (
256                 iter.key(),
257                 iter().lookupOrDefault<word>
258                 (
259                     "Label",
260                     "cellTable_" + Foam::name(iter.key())
261                 )
262             );
263         }
264     }
266     return lookup;
270 Foam::Map<Foam::word> Foam::cellTable::fluids() const
272     return selectType("fluid");
276 Foam::Map<Foam::word> Foam::cellTable::solids() const
278     return selectType("solid");
282 Foam::Map<Foam::word> Foam::cellTable::shells() const
284     return selectType("shell");
289 void Foam::cellTable::setMaterial(const label id, const word& matlType)
291     setEntry(id, "MaterialType", matlType);
295 void Foam::cellTable::setName(const label id, const word& name)
297     setEntry(id, "Label", name);
301 void Foam::cellTable::setName(const label id)
303     iterator iter = find(id);
305     if (iter == end() || !iter().found("Label"))
306     {
307         setName(id, "cellTable_" + Foam::name(id));
308     }
312 void Foam::cellTable::readDict
314     const objectRegistry& registry,
315     const word& name,
316     const fileName& instance
319     clear();
321     // read constant/dictName
322     IOMap<dictionary> ioObj
323     (
324         IOobject
325         (
326             name,
327             instance,
328             registry,
329             IOobject::READ_IF_PRESENT,
330             IOobject::NO_WRITE,
331             false
332         )
333     );
335     if (ioObj.headerOk())
336     {
337         *this = ioObj;
338         addDefaults();
339     }
340     else
341     {
342         Info<< "no constant/cellTable information available" << endl;
343     }
347 void Foam::cellTable::writeDict
349     const objectRegistry& registry,
350     const word& name,
351     const fileName& instance
352 ) const
354     // write constant/dictName
355     IOMap<dictionary> ioObj
356     (
357         IOobject
358         (
359             name,
360             instance,
361             registry,
362             IOobject::NO_READ,
363             IOobject::NO_WRITE,
364             false
365         )
366     );
368     ioObj.note() =
369         "persistent data for thirdParty mesh <-> OpenFOAM translation";
371     Info<< "Writing " << ioObj.name() << " to " << ioObj.objectPath() << endl;
373     OFstream os(ioObj.objectPath());
374     ioObj.writeHeader(os);
375     os << *this;
379 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
381 void Foam::cellTable::operator=(const cellTable& rhs)
383     Map<dictionary>::operator=(rhs);
384     addDefaults();
388 void Foam::cellTable::operator=(const Map<dictionary>& rhs)
390     Map<dictionary>::operator=(rhs);
391     addDefaults();
395 void Foam::cellTable::operator=(const polyMesh& mesh)
397     Map<dictionary> zoneDict;
399     // create cellTableId and cellTable based on cellZones
400     label nZoneCells = 0;
402     wordList zoneNames = mesh.cellZones().names();
403     label unZonedType = zoneNames.size() + 1;
405     // do cell zones
406     forAll(mesh.cellZones(), zoneI)
407     {
408         const cellZone& cZone = mesh.cellZones()[zoneI];
409         nZoneCells += cZone.size();
411         dictionary dict;
412         dict.add("Label", zoneNames[zoneI]);
413         zoneDict.insert(zoneI + 1, dict);
414     }
416     // collect unzoned cells
417     // special case: no zones at all - do entire mesh
418     if (nZoneCells == 0)
419     {
420         zoneDict.clear();
421         unZonedType = 1;
422     }
424     if (mesh.nCells() > nZoneCells)
425     {
426         zoneDict.insert
427         (
428             unZonedType,
429             dictionary(IStringStream("Label cells;")())
430         );
431     }
433     Map<dictionary>::operator=(zoneDict);
434     addDefaults();
438 // * * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * //
440 void Foam::cellTable::addCellZones
442     polyMesh& mesh,
443     const labelList& tableIds
444 ) const
446     Map<label> typeToZone = zoneMap();
447     List<DynamicList<label> > zoneCells(size());
449     forAll(tableIds, cellI)
450     {
451         Map<label>::const_iterator iter = typeToZone.find(tableIds[cellI]);
452         if (iter != typeToZone.end())
453         {
454             zoneCells[iter()].append(cellI);
455         }
456     }
458     // track which zones were actually used
459     labelList zoneUsed(zoneCells.size());
460     wordList  zoneNames(namesList());
462     label nZone = 0;
463     forAll(zoneCells, zoneI)
464     {
465         zoneCells[zoneI].shrink();
466         if (zoneCells[zoneI].size())
467         {
468             zoneUsed[nZone++] = zoneI;
469         }
470     }
471     zoneUsed.setSize(nZone);
473     cellZoneMesh& czMesh = mesh.cellZones();
475     czMesh.clear();
476     if (nZone <= 1)
477     {
478         Info<< "cellZones not used" << endl;
479         return;
480     }
481     czMesh.setSize(nZone);
483     forAll(zoneUsed, zoneI)
484     {
485         const label origZoneI = zoneUsed[zoneI];
487         Info<< "cellZone " << zoneI
488             << " (size: "  << zoneCells[origZoneI].size()
489             << ") name: "  << zoneNames[origZoneI] << endl;
491         czMesh.set
492         (
493             zoneI,
494             new cellZone
495             (
496                 zoneNames[origZoneI],
497                 zoneCells[origZoneI],
498                 zoneI,
499                 czMesh
500             )
501         );
502     }
503     czMesh.writeOpt() = IOobject::AUTO_WRITE;
507 void Foam::cellTable::combine(const dictionary& mapDict, labelList& tableIds)
509     if (mapDict.empty())
510     {
511         return;
512     }
514     Map<word> origNames(names());
515     labelList mapping(identity(max(origNames.toc()) + 1));
517     bool remap = false;
518     forAllConstIter(dictionary, mapDict, iter)
519     {
520         wordReList patterns(iter().stream());
522         // find all matches
523         Map<word> matches;
524         forAllConstIter(Map<word>, origNames, namesIter)
525         {
526             if (findStrings(patterns, namesIter()))
527             {
528                 matches.insert(namesIter.key(), namesIter());
529             }
530         }
532         if (matches.size())
533         {
534             label targetId = this->findIndex(iter().keyword());
536             Info<< "combine cellTable: " << iter().keyword();
537             if (targetId < 0)
538             {
539                 // not found - reuse 1st element but with different name
540                 targetId = min(matches.toc());
541                 operator[](targetId).set("Label", iter().keyword());
543                 Info<< " = (";
544             }
545             else
546             {
547                 Info<< " += (";
548             }
551             // the mapping and name for targetId is already okay
552             matches.erase(targetId);
553             origNames.erase(targetId);
555             // remove matched names, leaving targetId on 'this'
556             this->erase(matches);
557             origNames.erase(matches);
559             forAllConstIter(Map<word>, matches, matchIter)
560             {
561                 mapping[matchIter.key()] = targetId;
562                 Info<< " " << matchIter();
563             }
564             Info<< " )" << endl;
566             remap = true;
567         }
568     }
570     if (remap)
571     {
572         inplaceRenumber(mapping, tableIds);
573     }
576 // ************************************************************************* //