initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / conversion / meshTables / cellTable.C
blob2d640deb7e92b5f18fb8f4b02918b22310ac19c4
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 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"
33 #include "stringListOps.H"
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 const char* const Foam::cellTable::defaultMaterial_ = "fluid";
39 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
41 Foam::Map<Foam::label> Foam::cellTable::zoneMap() const
43     Map<label> lookup;
45     label zoneI = 0;
46     forAllConstIter(Map<dictionary>, *this, iter)
47     {
48         lookup.insert(iter.key(), zoneI++);
49     }
51     return lookup;
55 Foam::wordList Foam::cellTable::namesList() const
57     Map<word> lookup = names();
58     wordList lst(lookup.size());
60     label zoneI = 0;
61     forAllConstIter(Map<word>, lookup, iter)
62     {
63         lst[zoneI++] = iter();
64     }
66     return lst;
70 void Foam::cellTable::addDefaults()
72     forAllIter(Map<dictionary>, *this, iter)
73     {
74         if (!iter().found("MaterialType"))
75         {
76             iter().add("MaterialType", defaultMaterial_);
77         }
78     }
82 void Foam::cellTable::setEntry
84     const label& id,
85     const word& keyWord,
86     const word& value
89     dictionary dict;
90     dict.add(keyWord, value);
92     iterator iter = find(id);
93     if (iter != end())
94     {
95         iter().merge(dict);
96     }
97     else
98     {
99         insert(id, dict);
100     }
104 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
106 Foam::cellTable::cellTable()
108     Map<dictionary>()
112 Foam::cellTable::cellTable
114     const objectRegistry& registry,
115     const word& name,
116     const fileName& instance
119     Map<dictionary>()
121     readDict(registry, name, instance);
125 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
127 Foam::cellTable::~cellTable()
131 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
133 Foam::label Foam::cellTable::append(const dictionary& dict)
135     label maxId = -1;
136     forAllConstIter(Map<dictionary>, *this, iter)
137     {
138         if (maxId < iter.key())
139         {
140             maxId = iter.key();
141         }
142     }
144     insert(++maxId, dict);
145     return maxId;
149 Foam::Map<Foam::word> Foam::cellTable::names() const
151     Map<word> lookup;
153     forAllConstIter(Map<dictionary>, *this, iter)
154     {
155         lookup.insert
156         (
157             iter.key(),
158             iter().lookupOrDefault<word>
159             (
160                 "Label",
161                 "cellTable_" + Foam::name(iter.key())
162             )
163         );
164     }
166     return lookup;
170 Foam::Map<Foam::word> Foam::cellTable::names
172     const List<wordRe>& patterns
173 ) const
175     Map<word> lookup;
177     forAllConstIter(Map<dictionary>, *this, iter)
178     {
179         word lookupName = iter().lookupOrDefault<word>
180         (
181             "Label",
182             "cellTable_" + Foam::name(iter.key())
183         );
185         if (findStrings(patterns, lookupName))
186         {
187             lookup.insert(iter.key(), lookupName);
188         }
189     }
191     return lookup;
195 Foam::word Foam::cellTable::name(const label& id) const
197     word theName("cellTable_" + Foam::name(id));
199     const_iterator iter = find(id);
200     if (iter != end())
201     {
202         iter().readIfPresent("Label", theName);
203     }
205     return theName;
209 Foam::label Foam::cellTable::findIndex(const word& name) const
211     if (name.empty())
212     {
213         return -1;
214     }
216     forAllConstIter(Map<dictionary>, *this, iter)
217     {
218         if (iter().lookupOrDefault<word>("Label", word::null) == name)
219         {
220             return iter.key();
221         }
222     }
224     return -1;
228 Foam::Map<Foam::word> Foam::cellTable::materialTypes() const
230     Map<word> lookup;
232     forAllConstIter(Map<dictionary>, *this, iter)
233     {
234         lookup.insert
235         (
236             iter.key(),
237             iter().lookupOrDefault<word>("MaterialType", defaultMaterial_)
238         );
239     }
241     return lookup;
245 Foam::Map<Foam::word> Foam::cellTable::selectType(const word& matl) const
247     Map<word> lookup;
249     forAllConstIter(Map<dictionary>, *this, iter)
250     {
251         if
252         (
253             matl
254          == iter().lookupOrDefault<word>("MaterialType", defaultMaterial_)
255         )
256         {
257             lookup.insert
258             (
259                 iter.key(),
260                 iter().lookupOrDefault<word>
261                 (
262                     "Label",
263                     "cellTable_" + Foam::name(iter.key())
264                 )
265             );
266         }
267     }
269     return lookup;
273 Foam::Map<Foam::word> Foam::cellTable::fluids() const
275     return selectType("fluid");
279 Foam::Map<Foam::word> Foam::cellTable::solids() const
281     return selectType("solid");
285 Foam::Map<Foam::word> Foam::cellTable::shells() const
287     return selectType("shell");
292 void Foam::cellTable::setMaterial(const label& id, const word& matlType)
294     setEntry(id, "MaterialType", matlType);
298 void Foam::cellTable::setName(const label& id, const word& name)
300     setEntry(id, "Label", name);
304 void Foam::cellTable::setName(const label& id)
306     iterator iter = find(id);
308     if (iter == end() || !iter().found("Label"))
309     {
310         setName(id, "cellTable_" + Foam::name(id));
311     }
315 void Foam::cellTable::readDict
317     const objectRegistry& registry,
318     const word& name,
319     const fileName& instance
322     clear();
324     // read constant/dictName
325     IOMap<dictionary> ioObj
326     (
327         IOobject
328         (
329             name,
330             instance,
331             registry,
332             IOobject::READ_IF_PRESENT,
333             IOobject::NO_WRITE,
334             false
335         )
336     );
338     if (ioObj.headerOk())
339     {
340         *this = ioObj;
341         addDefaults();
342     }
343     else
344     {
345         Info<< "no constant/cellTable information available" << endl;
346     }
350 void Foam::cellTable::writeDict
352     const objectRegistry& registry,
353     const word& name,
354     const fileName& instance
355 ) const
357     // write constant/dictName
358     IOMap<dictionary> ioObj
359     (
360         IOobject
361         (
362             name,
363             instance,
364             registry,
365             IOobject::NO_READ,
366             IOobject::NO_WRITE,
367             false
368         )
369     );
371     ioObj.note() =
372         "persistent data for thirdParty mesh <-> OpenFOAM translation";
374     Info<< "Writing " << ioObj.name() << " to " << ioObj.objectPath() << endl;
376     OFstream os(ioObj.objectPath());
377     ioObj.writeHeader(os);
378     os << *this;
382 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
384 void Foam::cellTable::operator=(const cellTable& rhs)
386     Map<dictionary>::operator=(rhs);
387     addDefaults();
391 void Foam::cellTable::operator=(const Map<dictionary>& rhs)
393     Map<dictionary>::operator=(rhs);
394     addDefaults();
398 void Foam::cellTable::operator=(const polyMesh& mesh)
400     Map<dictionary> zoneDict;
402     // create cellTableId and cellTable based on cellZones
403     label nZoneCells = 0;
405     wordList zoneNames = mesh.cellZones().names();
406     label unZonedType = zoneNames.size() + 1;
408     // do cell zones
409     forAll(mesh.cellZones(), zoneI)
410     {
411         const cellZone& cZone = mesh.cellZones()[zoneI];
412         nZoneCells += cZone.size();
414         dictionary dict;
415         dict.add("Label", zoneNames[zoneI]);
416         zoneDict.insert(zoneI + 1, dict);
417     }
419     // collect unzoned cells
420     // special case: no zones at all - do entire mesh
421     if (nZoneCells == 0)
422     {
423         zoneDict.clear();
424         unZonedType = 1;
425     }
427     if (mesh.nCells() > nZoneCells)
428     {
429         zoneDict.insert
430         (
431             unZonedType,
432             dictionary(IStringStream("Label cells;")())
433         );
434     }
436     Map<dictionary>::operator=(zoneDict);
437     addDefaults();
441 // * * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * //
443 void Foam::cellTable::addCellZones
445     polyMesh& mesh,
446     const labelList& tableIds
447 ) const
449     Map<label> typeToZone = zoneMap();
450     List<DynamicList<label> > zoneCells(size());
452     forAll(tableIds, cellI)
453     {
454         Map<label>::const_iterator iter = typeToZone.find(tableIds[cellI]);
455         if (iter != typeToZone.end())
456         {
457             zoneCells[iter()].append(cellI);
458         }
459     }
461     // track which zones were actually used
462     labelList zoneUsed(zoneCells.size());
463     wordList  zoneNames(namesList());
465     label nZone = 0;
466     forAll(zoneCells, zoneI)
467     {
468         zoneCells[zoneI].shrink();
469         if (zoneCells[zoneI].size())
470         {
471             zoneUsed[nZone++] = zoneI;
472         }
473     }
474     zoneUsed.setSize(nZone);
476     cellZoneMesh& czMesh = mesh.cellZones();
478     czMesh.clear();
479     if (nZone <= 1)
480     {
481         Info<< "cellZones not used" << endl;
482         return;
483     }
484     czMesh.setSize(nZone);
486     forAll(zoneUsed, zoneI)
487     {
488         const label origZoneI = zoneUsed[zoneI];
490         Info<< "cellZone " << zoneI
491             << " (size: "  << zoneCells[origZoneI].size()
492             << ") name: "  << zoneNames[origZoneI] << endl;
494         czMesh.set
495         (
496             zoneI,
497             new cellZone
498             (
499                 zoneNames[origZoneI],
500                 zoneCells[origZoneI],
501                 zoneI,
502                 czMesh
503             )
504         );
505     }
506     czMesh.writeOpt() = IOobject::AUTO_WRITE;
510 void Foam::cellTable::combine(const dictionary& mapDict, labelList& tableIds)
512     if (mapDict.empty())
513     {
514         return;
515     }
517     Map<word> origNames(names());
518     labelList mapping(identity(max(origNames.toc()) + 1));
520     bool remap = false;
521     forAllConstIter(dictionary, mapDict, iter)
522     {
523         wordReList patterns(iter().stream());
525         // find all matches
526         Map<word> matches;
527         forAllConstIter(Map<word>, origNames, namesIter)
528         {
529             if (findStrings(patterns, namesIter()))
530             {
531                 matches.insert(namesIter.key(), namesIter());
532             }
533         }
535         if (matches.size())
536         {
537             label targetId = this->findIndex(iter().keyword());
539             Info<< "combine cellTable: " << iter().keyword();
540             if (targetId < 0)
541             {
542                 // not found - reuse 1st element but with different name
543                 targetId = min(matches.toc());
544                 operator[](targetId).set("Label", iter().keyword());
546                 Info<< " = (";
547             }
548             else
549             {
550                 Info<< " += (";
551             }
554             // the mapping and name for targetId is already okay
555             matches.erase(targetId);
556             origNames.erase(targetId);
558             // remove matched names, leaving targetId on 'this'
559             this->erase(matches);
560             origNames.erase(matches);
562             forAllConstIter(Map<word>, matches, matchIter)
563             {
564                 mapping[matchIter.key()] = targetId;
565                 Info<< " " << matchIter();
566             }
567             Info<< " )" << endl;
569             remap = true;
570         }
571     }
573     if (remap)
574     {
575         inplaceRenumber(mapping, tableIds);
576     }
579 // ************************************************************************* //