FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

cellTable.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 Description
00025 
00026 \*---------------------------------------------------------------------------*/
00027 
00028 #include "cellTable.H"
00029 #include <OpenFOAM/IOMap.H>
00030 #include <OpenFOAM/OFstream.H>
00031 #include <OpenFOAM/wordList.H>
00032 #include <OpenFOAM/stringListOps.H>
00033 
00034 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00035 
00036 const char* const Foam::cellTable::defaultMaterial_ = "fluid";
00037 
00038 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00039 
00040 Foam::Map<Foam::label> Foam::cellTable::zoneMap() const
00041 {
00042     Map<label> lookup;
00043 
00044     label zoneI = 0;
00045     forAllConstIter(Map<dictionary>, *this, iter)
00046     {
00047         lookup.insert(iter.key(), zoneI++);
00048     }
00049 
00050     return lookup;
00051 }
00052 
00053 
00054 Foam::wordList Foam::cellTable::namesList() const
00055 {
00056     Map<word> lookup = names();
00057     wordList lst(lookup.size());
00058 
00059     label zoneI = 0;
00060     forAllConstIter(Map<word>, lookup, iter)
00061     {
00062         lst[zoneI++] = iter();
00063     }
00064 
00065     return lst;
00066 }
00067 
00068 
00069 void Foam::cellTable::addDefaults()
00070 {
00071     forAllIter(Map<dictionary>, *this, iter)
00072     {
00073         if (!iter().found("MaterialType"))
00074         {
00075             iter().add("MaterialType", defaultMaterial_);
00076         }
00077     }
00078 }
00079 
00080 
00081 void Foam::cellTable::setEntry
00082 (
00083     const label& id,
00084     const word& keyWord,
00085     const word& value
00086 )
00087 {
00088     dictionary dict;
00089     dict.add(keyWord, value);
00090 
00091     iterator iter = find(id);
00092     if (iter != end())
00093     {
00094         iter().merge(dict);
00095     }
00096     else
00097     {
00098         insert(id, dict);
00099     }
00100 }
00101 
00102 
00103 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00104 
00105 Foam::cellTable::cellTable()
00106 :
00107     Map<dictionary>()
00108 {}
00109 
00110 
00111 Foam::cellTable::cellTable
00112 (
00113     const objectRegistry& registry,
00114     const word& name,
00115     const fileName& instance
00116 )
00117 :
00118     Map<dictionary>()
00119 {
00120     readDict(registry, name, instance);
00121 }
00122 
00123 
00124 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00125 
00126 Foam::cellTable::~cellTable()
00127 {}
00128 
00129 
00130 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
00131 
00132 Foam::label Foam::cellTable::append(const dictionary& dict)
00133 {
00134     label maxId = -1;
00135     forAllConstIter(Map<dictionary>, *this, iter)
00136     {
00137         if (maxId < iter.key())
00138         {
00139             maxId = iter.key();
00140         }
00141     }
00142 
00143     insert(++maxId, dict);
00144     return maxId;
00145 }
00146 
00147 
00148 Foam::Map<Foam::word> Foam::cellTable::names() const
00149 {
00150     Map<word> lookup;
00151 
00152     forAllConstIter(Map<dictionary>, *this, iter)
00153     {
00154         lookup.insert
00155         (
00156             iter.key(),
00157             iter().lookupOrDefault<word>
00158             (
00159                 "Label",
00160                 "cellTable_" + Foam::name(iter.key())
00161             )
00162         );
00163     }
00164 
00165     return lookup;
00166 }
00167 
00168 
00169 Foam::Map<Foam::word> Foam::cellTable::names
00170 (
00171     const List<wordRe>& patterns
00172 ) const
00173 {
00174     Map<word> lookup;
00175 
00176     forAllConstIter(Map<dictionary>, *this, iter)
00177     {
00178         word lookupName = iter().lookupOrDefault<word>
00179         (
00180             "Label",
00181             "cellTable_" + Foam::name(iter.key())
00182         );
00183 
00184         if (findStrings(patterns, lookupName))
00185         {
00186             lookup.insert(iter.key(), lookupName);
00187         }
00188     }
00189 
00190     return lookup;
00191 }
00192 
00193 
00194 Foam::word Foam::cellTable::name(const label& id) const
00195 {
00196     word theName("cellTable_" + Foam::name(id));
00197 
00198     const_iterator iter = find(id);
00199     if (iter != end())
00200     {
00201         iter().readIfPresent("Label", theName);
00202     }
00203 
00204     return theName;
00205 }
00206 
00207 
00208 Foam::label Foam::cellTable::findIndex(const word& name) const
00209 {
00210     if (name.empty())
00211     {
00212         return -1;
00213     }
00214 
00215     forAllConstIter(Map<dictionary>, *this, iter)
00216     {
00217         if (iter().lookupOrDefault<word>("Label", word::null) == name)
00218         {
00219             return iter.key();
00220         }
00221     }
00222 
00223     return -1;
00224 }
00225 
00226 
00227 Foam::Map<Foam::word> Foam::cellTable::materialTypes() const
00228 {
00229     Map<word> lookup;
00230 
00231     forAllConstIter(Map<dictionary>, *this, iter)
00232     {
00233         lookup.insert
00234         (
00235             iter.key(),
00236             iter().lookupOrDefault<word>("MaterialType", defaultMaterial_)
00237         );
00238     }
00239 
00240     return lookup;
00241 }
00242 
00243 
00244 Foam::Map<Foam::word> Foam::cellTable::selectType(const word& matl) const
00245 {
00246     Map<word> lookup;
00247 
00248     forAllConstIter(Map<dictionary>, *this, iter)
00249     {
00250         if
00251         (
00252             matl
00253          == iter().lookupOrDefault<word>("MaterialType", defaultMaterial_)
00254         )
00255         {
00256             lookup.insert
00257             (
00258                 iter.key(),
00259                 iter().lookupOrDefault<word>
00260                 (
00261                     "Label",
00262                     "cellTable_" + Foam::name(iter.key())
00263                 )
00264             );
00265         }
00266     }
00267 
00268     return lookup;
00269 }
00270 
00271 
00272 Foam::Map<Foam::word> Foam::cellTable::fluids() const
00273 {
00274     return selectType("fluid");
00275 }
00276 
00277 
00278 Foam::Map<Foam::word> Foam::cellTable::solids() const
00279 {
00280     return selectType("solid");
00281 }
00282 
00283 
00284 Foam::Map<Foam::word> Foam::cellTable::shells() const
00285 {
00286     return selectType("shell");
00287 }
00288 
00289 
00290 
00291 void Foam::cellTable::setMaterial(const label& id, const word& matlType)
00292 {
00293     setEntry(id, "MaterialType", matlType);
00294 }
00295 
00296 
00297 void Foam::cellTable::setName(const label& id, const word& name)
00298 {
00299     setEntry(id, "Label", name);
00300 }
00301 
00302 
00303 void Foam::cellTable::setName(const label& id)
00304 {
00305     iterator iter = find(id);
00306 
00307     if (iter == end() || !iter().found("Label"))
00308     {
00309         setName(id, "cellTable_" + Foam::name(id));
00310     }
00311 }
00312 
00313 
00314 void Foam::cellTable::readDict
00315 (
00316     const objectRegistry& registry,
00317     const word& name,
00318     const fileName& instance
00319 )
00320 {
00321     clear();
00322 
00323     // read constant/dictName
00324     IOMap<dictionary> ioObj
00325     (
00326         IOobject
00327         (
00328             name,
00329             instance,
00330             registry,
00331             IOobject::READ_IF_PRESENT,
00332             IOobject::NO_WRITE,
00333             false
00334         )
00335     );
00336 
00337     if (ioObj.headerOk())
00338     {
00339         *this = ioObj;
00340         addDefaults();
00341     }
00342     else
00343     {
00344         Info<< "no constant/cellTable information available" << endl;
00345     }
00346 }
00347 
00348 
00349 void Foam::cellTable::writeDict
00350 (
00351     const objectRegistry& registry,
00352     const word& name,
00353     const fileName& instance
00354 ) const
00355 {
00356     // write constant/dictName
00357     IOMap<dictionary> ioObj
00358     (
00359         IOobject
00360         (
00361             name,
00362             instance,
00363             registry,
00364             IOobject::NO_READ,
00365             IOobject::NO_WRITE,
00366             false
00367         )
00368     );
00369 
00370     ioObj.note() =
00371         "persistent data for thirdParty mesh <-> OpenFOAM translation";
00372 
00373     Info<< "Writing " << ioObj.name() << " to " << ioObj.objectPath() << endl;
00374 
00375     OFstream os(ioObj.objectPath());
00376     ioObj.writeHeader(os);
00377     os << *this;
00378 }
00379 
00380 
00381 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
00382 
00383 void Foam::cellTable::operator=(const cellTable& rhs)
00384 {
00385     Map<dictionary>::operator=(rhs);
00386     addDefaults();
00387 }
00388 
00389 
00390 void Foam::cellTable::operator=(const Map<dictionary>& rhs)
00391 {
00392     Map<dictionary>::operator=(rhs);
00393     addDefaults();
00394 }
00395 
00396 
00397 void Foam::cellTable::operator=(const polyMesh& mesh)
00398 {
00399     Map<dictionary> zoneDict;
00400 
00401     // create cellTableId and cellTable based on cellZones
00402     label nZoneCells = 0;
00403 
00404     wordList zoneNames = mesh.cellZones().names();
00405     label unZonedType = zoneNames.size() + 1;
00406 
00407     // do cell zones
00408     forAll(mesh.cellZones(), zoneI)
00409     {
00410         const cellZone& cZone = mesh.cellZones()[zoneI];
00411         nZoneCells += cZone.size();
00412 
00413         dictionary dict;
00414         dict.add("Label", zoneNames[zoneI]);
00415         zoneDict.insert(zoneI + 1, dict);
00416     }
00417 
00418     // collect unzoned cells
00419     // special case: no zones at all - do entire mesh
00420     if (nZoneCells == 0)
00421     {
00422         zoneDict.clear();
00423         unZonedType = 1;
00424     }
00425 
00426     if (mesh.nCells() > nZoneCells)
00427     {
00428         zoneDict.insert
00429         (
00430             unZonedType,
00431             dictionary(IStringStream("Label cells;")())
00432         );
00433     }
00434 
00435     Map<dictionary>::operator=(zoneDict);
00436     addDefaults();
00437 }
00438 
00439 
00440 // * * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * //
00441 
00442 void Foam::cellTable::addCellZones
00443 (
00444     polyMesh& mesh,
00445     const labelList& tableIds
00446 ) const
00447 {
00448     Map<label> typeToZone = zoneMap();
00449     List<DynamicList<label> > zoneCells(size());
00450 
00451     forAll(tableIds, cellI)
00452     {
00453         Map<label>::const_iterator iter = typeToZone.find(tableIds[cellI]);
00454         if (iter != typeToZone.end())
00455         {
00456             zoneCells[iter()].append(cellI);
00457         }
00458     }
00459 
00460     // track which zones were actually used
00461     labelList zoneUsed(zoneCells.size());
00462     wordList  zoneNames(namesList());
00463 
00464     label nZone = 0;
00465     forAll(zoneCells, zoneI)
00466     {
00467         zoneCells[zoneI].shrink();
00468         if (zoneCells[zoneI].size())
00469         {
00470             zoneUsed[nZone++] = zoneI;
00471         }
00472     }
00473     zoneUsed.setSize(nZone);
00474 
00475     cellZoneMesh& czMesh = mesh.cellZones();
00476 
00477     czMesh.clear();
00478     if (nZone <= 1)
00479     {
00480         Info<< "cellZones not used" << endl;
00481         return;
00482     }
00483     czMesh.setSize(nZone);
00484 
00485     forAll(zoneUsed, zoneI)
00486     {
00487         const label origZoneI = zoneUsed[zoneI];
00488 
00489         Info<< "cellZone " << zoneI
00490             << " (size: "  << zoneCells[origZoneI].size()
00491             << ") name: "  << zoneNames[origZoneI] << endl;
00492 
00493         czMesh.set
00494         (
00495             zoneI,
00496             new cellZone
00497             (
00498                 zoneNames[origZoneI],
00499                 zoneCells[origZoneI],
00500                 zoneI,
00501                 czMesh
00502             )
00503         );
00504     }
00505     czMesh.writeOpt() = IOobject::AUTO_WRITE;
00506 }
00507 
00508 
00509 void Foam::cellTable::combine(const dictionary& mapDict, labelList& tableIds)
00510 {
00511     if (mapDict.empty())
00512     {
00513         return;
00514     }
00515 
00516     Map<word> origNames(names());
00517     labelList mapping(identity(max(origNames.toc()) + 1));
00518 
00519     bool remap = false;
00520     forAllConstIter(dictionary, mapDict, iter)
00521     {
00522         wordReList patterns(iter().stream());
00523 
00524         // find all matches
00525         Map<word> matches;
00526         forAllConstIter(Map<word>, origNames, namesIter)
00527         {
00528             if (findStrings(patterns, namesIter()))
00529             {
00530                 matches.insert(namesIter.key(), namesIter());
00531             }
00532         }
00533 
00534         if (matches.size())
00535         {
00536             label targetId = this->findIndex(iter().keyword());
00537 
00538             Info<< "combine cellTable: " << iter().keyword();
00539             if (targetId < 0)
00540             {
00541                 // not found - reuse 1st element but with different name
00542                 targetId = min(matches.toc());
00543                 operator[](targetId).set("Label", iter().keyword());
00544 
00545                 Info<< " = (";
00546             }
00547             else
00548             {
00549                 Info<< " += (";
00550             }
00551 
00552 
00553             // the mapping and name for targetId is already okay
00554             matches.erase(targetId);
00555             origNames.erase(targetId);
00556 
00557             // remove matched names, leaving targetId on 'this'
00558             this->erase(matches);
00559             origNames.erase(matches);
00560 
00561             forAllConstIter(Map<word>, matches, matchIter)
00562             {
00563                 mapping[matchIter.key()] = targetId;
00564                 Info<< " " << matchIter();
00565             }
00566             Info<< " )" << endl;
00567 
00568             remap = true;
00569         }
00570     }
00571 
00572     if (remap)
00573     {
00574         inplaceRenumber(mapping, tableIds);
00575     }
00576 }
00577 
00578 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines