Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / conversion / meshTables / cellTable.C
blobcc07b3f18210e09622365e0d588f6e8e226bd2d7
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | foam-extend: Open Source CFD
4    \\    /   O peration     | Version:     3.2
5     \\  /    A nd           | Web:         http://www.foam-extend.org
6      \\/     M anipulation  | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
8 License
9     This file is part of foam-extend.
11     foam-extend 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 3 of the License, or (at your
14     option) any later version.
16     foam-extend is distributed in the hope that it will be useful, but
17     WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19     General Public License for more details.
21     You should have received a copy of the GNU General Public License
22     along with foam-extend.  If not, see <http://www.gnu.org/licenses/>.
24 Description
26 \*---------------------------------------------------------------------------*/
28 #include "cellTable.H"
29 #include "IOMap.H"
30 #include "OFstream.H"
31 #include "wordList.H"
32 #include "stringListOps.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::Map<Foam::word> Foam::cellTable::names
171     const List<wordRe>& patterns
172 ) const
174     Map<word> lookup;
176     forAllConstIter(Map<dictionary>, *this, iter)
177     {
178         word lookupName = iter().lookupOrDefault<word>
179         (
180             "Label",
181             "cellTable_" + Foam::name(iter.key())
182         );
184         if (findStrings(patterns, lookupName))
185         {
186             lookup.insert(iter.key(), lookupName);
187         }
188     }
190     return lookup;
194 Foam::word Foam::cellTable::name(const label& id) const
196     word theName("cellTable_" + Foam::name(id));
198     const_iterator iter = find(id);
199     if (iter != end())
200     {
201         iter().readIfPresent("Label", theName);
202     }
204     return theName;
208 Foam::label Foam::cellTable::findIndex(const word& name) const
210     if (name.empty())
211     {
212         return -1;
213     }
215     forAllConstIter(Map<dictionary>, *this, iter)
216     {
217         if (iter().lookupOrDefault<word>("Label", word::null) == name)
218         {
219             return iter.key();
220         }
221     }
223     return -1;
227 Foam::Map<Foam::word> Foam::cellTable::materialTypes() const
229     Map<word> lookup;
231     forAllConstIter(Map<dictionary>, *this, iter)
232     {
233         lookup.insert
234         (
235             iter.key(),
236             iter().lookupOrDefault<word>("MaterialType", defaultMaterial_)
237         );
238     }
240     return lookup;
244 Foam::Map<Foam::word> Foam::cellTable::selectType(const word& matl) const
246     Map<word> lookup;
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     }
268     return lookup;
272 Foam::Map<Foam::word> Foam::cellTable::fluids() const
274     return selectType("fluid");
278 Foam::Map<Foam::word> Foam::cellTable::solids() const
280     return selectType("solid");
284 Foam::Map<Foam::word> Foam::cellTable::shells() const
286     return selectType("shell");
291 void Foam::cellTable::setMaterial(const label& id, const word& matlType)
293     setEntry(id, "MaterialType", matlType);
297 void Foam::cellTable::setName(const label& id, const word& name)
299     setEntry(id, "Label", name);
303 void Foam::cellTable::setName(const label& id)
305     iterator iter = find(id);
307     if (iter == end() || !iter().found("Label"))
308     {
309         setName(id, "cellTable_" + Foam::name(id));
310     }
314 void Foam::cellTable::readDict
316     const objectRegistry& registry,
317     const word& name,
318     const fileName& instance
321     clear();
323     // read constant/dictName
324     IOMap<dictionary> ioObj
325     (
326         IOobject
327         (
328             name,
329             instance,
330             registry,
331             IOobject::READ_IF_PRESENT,
332             IOobject::NO_WRITE,
333             false
334         )
335     );
337     if (ioObj.headerOk())
338     {
339         *this = ioObj;
340         addDefaults();
341     }
342     else
343     {
344         Info<< "no constant/cellTable information available" << endl;
345     }
349 void Foam::cellTable::writeDict
351     const objectRegistry& registry,
352     const word& name,
353     const fileName& instance
354 ) const
356     // write constant/dictName
357     IOMap<dictionary> ioObj
358     (
359         IOobject
360         (
361             name,
362             instance,
363             registry,
364             IOobject::NO_READ,
365             IOobject::NO_WRITE,
366             false
367         )
368     );
370     ioObj.note() =
371         "persistent data for thirdParty mesh <-> foam translation";
373     Info<< "Writing " << ioObj.name() << " to " << ioObj.objectPath() << endl;
375     OFstream os(ioObj.objectPath());
376     ioObj.writeHeader(os);
377     os << *this;
381 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
383 void Foam::cellTable::operator=(const cellTable& rhs)
385     Map<dictionary>::operator=(rhs);
386     addDefaults();
390 void Foam::cellTable::operator=(const Map<dictionary>& rhs)
392     Map<dictionary>::operator=(rhs);
393     addDefaults();
397 void Foam::cellTable::operator=(const polyMesh& mesh)
399     Map<dictionary> zoneDict;
401     // create cellTableId and cellTable based on cellZones
402     label nZoneCells = 0;
404     wordList zoneNames = mesh.cellZones().names();
405     label unZonedType = zoneNames.size() + 1;
407     // do cell zones
408     forAll(mesh.cellZones(), zoneI)
409     {
410         const cellZone& cZone = mesh.cellZones()[zoneI];
411         nZoneCells += cZone.size();
413         dictionary dict;
414         dict.add("Label", zoneNames[zoneI]);
415         zoneDict.insert(zoneI + 1, dict);
416     }
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     }
426     if (mesh.nCells() > nZoneCells)
427     {
428         zoneDict.insert
429         (
430             unZonedType,
431             dictionary(IStringStream("Label cells;")())
432         );
433     }
435     Map<dictionary>::operator=(zoneDict);
436     addDefaults();
440 // * * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * //
442 void Foam::cellTable::addCellZones
444     polyMesh& mesh,
445     const labelList& tableIds
446 ) const
448     Map<label> typeToZone = zoneMap();
449     List<dynamicLabelList > zoneCells(size());
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     }
460     // track which zones were actually used
461     labelList zoneUsed(zoneCells.size());
462     wordList  zoneNames(namesList());
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);
475     cellZoneMesh& czMesh = mesh.cellZones();
477     czMesh.clear();
478     if (nZone <= 1)
479     {
480         Info<< "cellZones not used" << endl;
481         return;
482     }
483     czMesh.setSize(nZone);
485     forAll(zoneUsed, zoneI)
486     {
487         const label origZoneI = zoneUsed[zoneI];
489         Info<< "cellZone " << zoneI
490             << " (size: "  << zoneCells[origZoneI].size()
491             << ") name: "  << zoneNames[origZoneI] << endl;
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;
509 void Foam::cellTable::combine(const dictionary& mapDict, labelList& tableIds)
511     if (mapDict.empty())
512     {
513         return;
514     }
516     Map<word> origNames(names());
517     labelList mapping(identity(max(origNames.toc()) + 1));
519     bool remap = false;
520     forAllConstIter(dictionary, mapDict, iter)
521     {
522         wordReList patterns(iter().stream());
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         }
534         if (matches.size())
535         {
536             label targetId = this->findIndex(iter().keyword());
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());
545                 Info<< " = (";
546             }
547             else
548             {
549                 Info<< " += (";
550             }
553             // the mapping and name for targetId is already okay
554             matches.erase(targetId);
555             origNames.erase(targetId);
557             // remove matched names, leaving targetId on 'this'
558             this->erase(matches);
559             origNames.erase(matches);
561             forAllConstIter(Map<word>, matches, matchIter)
562             {
563                 mapping[matchIter.key()] = targetId;
564                 Info<< " " << matchIter();
565             }
566             Info<< " )" << endl;
568             remap = true;
569         }
570     }
572     if (remap)
573     {
574         inplaceRenumber(mapping, tableIds);
575     }
578 // ************************************************************************* //