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

refinementHistory.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 \*---------------------------------------------------------------------------*/
00025 
00026 #include <OpenFOAM/DynamicList.H>
00027 #include "refinementHistory.H"
00028 #include <OpenFOAM/ListOps.H>
00029 #include <OpenFOAM/mapPolyMesh.H>
00030 #include <OpenFOAM/mapDistributePolyMesh.H>
00031 #include <OpenFOAM/polyMesh.H>
00032 
00033 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00034 
00035 namespace Foam
00036 {
00037 
00038 defineTypeNameAndDebug(refinementHistory, 0);
00039 
00040 }
00041 
00042 
00043 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00044 
00045 void Foam::refinementHistory::writeEntry
00046 (
00047     const List<splitCell8>& splitCells,
00048     const splitCell8& split
00049 )
00050 {
00051     // Write me:
00052     if (split.addedCellsPtr_.valid())
00053     {
00054         Pout<< "parent:" << split.parent_
00055             << " subCells:" << split.addedCellsPtr_()
00056             << endl;
00057     }
00058     else
00059     {
00060         Pout<< "parent:" << split.parent_
00061             << " no subcells"
00062             << endl;
00063     }
00064 
00065     if (split.parent_ >= 0)
00066     {
00067         Pout<< "parent data:" << endl;
00068         // Write my parent
00069         string oldPrefix = Pout.prefix();
00070         Pout.prefix() = "  " + oldPrefix;
00071         writeEntry(splitCells, splitCells[split.parent_]);
00072         Pout.prefix() = oldPrefix;
00073     }
00074 }
00075 
00076 
00077 void Foam::refinementHistory::writeDebug
00078 (
00079     const labelList& visibleCells,
00080     const List<splitCell8>& splitCells
00081 )
00082 {
00083     string oldPrefix = Pout.prefix();
00084     Pout.prefix() = "";
00085 
00086     forAll(visibleCells, cellI)
00087     {
00088         label index = visibleCells[cellI];
00089 
00090         if (index >= 0)
00091         {
00092             Pout<< "Cell from refinement:" << cellI << " index:" << index
00093                 << endl;
00094 
00095             string oldPrefix = Pout.prefix();
00096             Pout.prefix() = "  " + oldPrefix;
00097             writeEntry(splitCells, splitCells[index]);
00098             Pout.prefix() = oldPrefix;
00099         }
00100         else
00101         {
00102             Pout<< "Unrefined cell:" << cellI << " index:" << index << endl;
00103         }
00104     }
00105     Pout.prefix() = oldPrefix;
00106 }
00107 
00108 
00109 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00110 
00111 //- Construct null
00112 Foam::refinementHistory::splitCell8::splitCell8()
00113 :
00114     parent_(-1),
00115     addedCellsPtr_(NULL)
00116 {}
00117 
00118 
00119 //- Construct as child element of parent
00120 Foam::refinementHistory::splitCell8::splitCell8(const label parent)
00121 :
00122     parent_(parent),
00123     addedCellsPtr_(NULL)
00124 {}
00125 
00126 
00127 //- Construct from Istream
00128 Foam::refinementHistory::splitCell8::splitCell8(Istream& is)
00129 {
00130     is >> *this;
00131 }
00132 
00133 
00134 //- Construct as (deep) copy.
00135 Foam::refinementHistory::splitCell8::splitCell8(const splitCell8& sc)
00136 :
00137     parent_(sc.parent_),
00138     addedCellsPtr_
00139     (
00140         sc.addedCellsPtr_.valid()
00141       ? new FixedList<label, 8>(sc.addedCellsPtr_())
00142       : NULL
00143     )
00144 {}
00145 
00146 
00147 // * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
00148 
00149 Foam::Istream& Foam::operator>>(Istream& is, refinementHistory::splitCell8& sc)
00150 {
00151     labelList addedCells;
00152 
00153     is >> sc.parent_ >> addedCells;
00154 
00155     if (addedCells.size())
00156     {
00157         sc.addedCellsPtr_.reset(new FixedList<label, 8>(addedCells));
00158     }
00159     else
00160     {
00161         sc.addedCellsPtr_.reset(NULL);
00162     }
00163 
00164     return is;
00165 }
00166 
00167 
00168 Foam::Ostream& Foam::operator<<
00169 (
00170     Ostream& os,
00171     const refinementHistory::splitCell8& sc
00172 )
00173 {
00174     // Output as labelList so we can have 0 sized lists. Alternative is to
00175     // output as fixedlist with e.g. -1 elements and check for this upon
00176     // reading. However would cause much more data to be transferred.
00177 
00178     if (sc.addedCellsPtr_.valid())
00179     {
00180         return os
00181             << sc.parent_
00182             << token::SPACE
00183             << labelList(sc.addedCellsPtr_());
00184     }
00185     else
00186     {
00187         return os << sc.parent_ << token::SPACE << labelList(0);
00188     }
00189 }
00190 
00191 
00192 void Foam::refinementHistory::checkIndices() const
00193 {
00194     // Check indices.
00195     forAll(visibleCells_, i)
00196     {
00197         if (visibleCells_[i] < 0 && visibleCells_[i] >= splitCells_.size())
00198         {
00199             FatalErrorIn("refinementHistory::checkIndices() const")
00200                 << "Illegal entry " << visibleCells_[i]
00201                 << " in visibleCells at location" << i << nl
00202                 << "It points outside the range of splitCells : 0.."
00203                 << splitCells_.size()-1
00204                 << abort(FatalError);
00205         }
00206     }
00207 }
00208 
00209 
00210 Foam::label Foam::refinementHistory::allocateSplitCell
00211 (
00212     const label parent,
00213     const label i
00214 )
00215 {
00216     label index = -1;
00217 
00218     if (freeSplitCells_.size())
00219     {
00220         index = freeSplitCells_.remove();
00221 
00222         splitCells_[index] = splitCell8(parent);
00223     }
00224     else
00225     {
00226         index = splitCells_.size();
00227 
00228         splitCells_.append(splitCell8(parent));
00229     }
00230 
00231 
00232     // Update the parent field
00233     if (parent >= 0)
00234     {
00235         splitCell8& parentSplit = splitCells_[parent];
00236 
00237         if (parentSplit.addedCellsPtr_.empty())
00238         {
00239             // Allocate storage on parent for the 8 subcells.
00240             parentSplit.addedCellsPtr_.reset(new FixedList<label, 8>(-1));
00241         }
00242 
00243 
00244         // Store me on my parent
00245         FixedList<label, 8>& parentSplits = parentSplit.addedCellsPtr_();
00246 
00247         parentSplits[i] = index;
00248     }
00249 
00250     return index;
00251 }
00252 
00253 
00254 void Foam::refinementHistory::freeSplitCell(const label index)
00255 {
00256     splitCell8& split = splitCells_[index];
00257 
00258     // Make sure parent does not point to me anymore.
00259     if (split.parent_ >= 0)
00260     {
00261         autoPtr<FixedList<label, 8> >& subCellsPtr =
00262             splitCells_[split.parent_].addedCellsPtr_;
00263 
00264         if (subCellsPtr.valid())
00265         {
00266             FixedList<label, 8>& subCells = subCellsPtr();
00267 
00268             label myPos = findIndex(subCells, index);
00269 
00270             if (myPos == -1)
00271             {
00272                 FatalErrorIn("refinementHistory::freeSplitCell")
00273                     << "Problem: cannot find myself in"
00274                     << " parents' children" << abort(FatalError);
00275             }
00276             else
00277             {
00278                 subCells[myPos] = -1;
00279             }
00280         }
00281     }
00282 
00283     // Mark splitCell as free
00284     split.parent_ = -2;
00285 
00286     // Add to cache of free splitCells
00287     freeSplitCells_.append(index);
00288 }
00289 
00290 
00291 // Mark entry in splitCells. Recursively mark its parent and subs.
00292 void Foam::refinementHistory::markSplit
00293 (
00294     const label index,
00295     labelList& oldToNew,
00296     DynamicList<splitCell8>& newSplitCells
00297 ) const
00298 {
00299     if (oldToNew[index] == -1)
00300     {
00301         // Not yet compacted.
00302 
00303         const splitCell8& split = splitCells_[index];
00304 
00305         oldToNew[index] = newSplitCells.size();
00306         newSplitCells.append(split);
00307 
00308         if (split.parent_ >= 0)
00309         {
00310             markSplit(split.parent_, oldToNew, newSplitCells);
00311         }
00312         if (split.addedCellsPtr_.valid())
00313         {
00314             const FixedList<label, 8>& splits = split.addedCellsPtr_();
00315 
00316             forAll(splits, i)
00317             {
00318                 if (splits[i] >= 0)
00319                 {
00320                     markSplit(splits[i], oldToNew, newSplitCells);
00321                 }
00322             }
00323         }
00324     }
00325 }
00326 
00327 
00328 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00329 
00330 Foam::refinementHistory::refinementHistory(const IOobject& io)
00331 :
00332     regIOobject(io)
00333 {
00334     if
00335     (
00336         io.readOpt() == IOobject::MUST_READ
00337      || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
00338     )
00339     {
00340         readStream(typeName) >> *this;
00341         close();
00342     }
00343 
00344     if (debug)
00345     {
00346         Pout<< "refinementHistory::refinementHistory :"
00347             << " constructed history from IOobject :"
00348             << " splitCells:" << splitCells_.size()
00349             << " visibleCells:" << visibleCells_.size()
00350             << endl;
00351     }
00352 }
00353 
00354 
00355 //- Read or construct
00356 Foam::refinementHistory::refinementHistory
00357 (
00358     const IOobject& io,
00359     const List<splitCell8>& splitCells,
00360     const labelList& visibleCells
00361 )
00362 :
00363     regIOobject(io),
00364     splitCells_(splitCells),
00365     freeSplitCells_(0),
00366     visibleCells_(visibleCells)
00367 {
00368     if
00369     (
00370         io.readOpt() == IOobject::MUST_READ
00371      || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
00372     )
00373     {
00374         readStream(typeName) >> *this;
00375         close();
00376     }
00377 
00378     // Check indices.
00379     checkIndices();
00380 
00381     if (debug)
00382     {
00383         Pout<< "refinementHistory::refinementHistory :"
00384             << " constructed history from IOobject or components :"
00385             << " splitCells:" << splitCells_.size()
00386             << " visibleCells:" << visibleCells_.size()
00387             << endl;
00388     }
00389 }
00390 
00391 
00392 // Construct from initial number of cells (all visible)
00393 Foam::refinementHistory::refinementHistory
00394 (
00395     const IOobject& io,
00396     const label nCells
00397 )
00398 :
00399     regIOobject(io),
00400     freeSplitCells_(0)
00401 {
00402     if
00403     (
00404         io.readOpt() == IOobject::MUST_READ
00405      || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
00406     )
00407     {
00408         readStream(typeName) >> *this;
00409         close();
00410     }
00411     else
00412     {
00413         visibleCells_.setSize(nCells);
00414         splitCells_.setCapacity(nCells);
00415 
00416         for (label cellI = 0; cellI < nCells; cellI++)
00417         {
00418             visibleCells_[cellI] = cellI;
00419             splitCells_.append(splitCell8());
00420         }
00421     }
00422 
00423     // Check indices.
00424     checkIndices();
00425 
00426     if (debug)
00427     {
00428         Pout<< "refinementHistory::refinementHistory :"
00429             << " constructed history from IOobject or initial size :"
00430             << " splitCells:" << splitCells_.size()
00431             << " visibleCells:" << visibleCells_.size()
00432             << endl;
00433     }
00434 }
00435 
00436 
00437 // Construct as copy
00438 Foam::refinementHistory::refinementHistory
00439 (
00440     const IOobject& io,
00441     const refinementHistory& rh
00442 )
00443 :
00444     regIOobject(io),
00445     splitCells_(rh.splitCells()),
00446     freeSplitCells_(rh.freeSplitCells()),
00447     visibleCells_(rh.visibleCells())
00448 {
00449     if (debug)
00450     {
00451         Pout<< "refinementHistory::refinementHistory : constructed initial"
00452             << " history." << endl;
00453     }
00454 }
00455 
00456 
00457 // Construct from Istream
00458 Foam::refinementHistory::refinementHistory(const IOobject& io, Istream& is)
00459 :
00460     regIOobject(io),
00461     splitCells_(is),
00462     freeSplitCells_(0),
00463     visibleCells_(is)
00464 {
00465     // Check indices.
00466     checkIndices();
00467 
00468     if (debug)
00469     {
00470         Pout<< "refinementHistory::refinementHistory :"
00471             << " constructed history from Istream"
00472             << " splitCells:" << splitCells_.size()
00473             << " visibleCells:" << visibleCells_.size()
00474             << endl;
00475     }
00476 }
00477 
00478 
00479 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00480 
00481 void Foam::refinementHistory::resize(const label size)
00482 {
00483     label oldSize = visibleCells_.size();
00484 
00485     if (debug)
00486     {
00487         Pout<< "refinementHistory::resize from " << oldSize << " to " << size
00488             << " cells" << endl;
00489     }
00490 
00491     visibleCells_.setSize(size);
00492 
00493     // Set additional elements to -1.
00494     for (label i = oldSize; i < visibleCells_.size(); i++)
00495     {
00496         visibleCells_[i] = -1;
00497     }
00498 }
00499 
00500 
00501 void Foam::refinementHistory::updateMesh(const mapPolyMesh& map)
00502 {
00503     if (active())
00504     {
00505         const labelList& reverseCellMap = map.reverseCellMap();
00506 
00507         // Note that only the live cells need to be renumbered.
00508 
00509         labelList newVisibleCells(map.cellMap().size(), -1);
00510 
00511         forAll(visibleCells_, cellI)
00512         {
00513             if (visibleCells_[cellI] != -1)
00514             {
00515                 label index = visibleCells_[cellI];
00516 
00517                 // Check not already set
00518                 if (splitCells_[index].addedCellsPtr_.valid())
00519                 {
00520                     FatalErrorIn
00521                     (
00522                         "refinementHistory::updateMesh(const mapPolyMesh&)"
00523                     )   << "Problem" << abort(FatalError);
00524                 }
00525 
00526                 label newCellI = reverseCellMap[cellI];
00527 
00528                 if (newCellI >= 0)
00529                 {
00530                     newVisibleCells[newCellI] = index;
00531                 }
00532             }
00533         }
00534 
00535         if (debug)
00536         {
00537             Pout<< "refinementHistory::updateMesh : from "
00538                 << visibleCells_.size()
00539                 << " to " << newVisibleCells.size()
00540                 << " cells" << endl;
00541         }
00542 
00543         visibleCells_.transfer(newVisibleCells);
00544     }
00545 }
00546 
00547 
00548 // Update numbering for subsetting
00549 void Foam::refinementHistory::subset
00550 (
00551     const labelList& pointMap,
00552     const labelList& faceMap,
00553     const labelList& cellMap
00554 )
00555 {
00556     if (active())
00557     {
00558         labelList newVisibleCells(cellMap.size(), -1);
00559 
00560         forAll(newVisibleCells, cellI)
00561         {
00562             label oldCellI = cellMap[cellI];
00563 
00564             label index = visibleCells_[oldCellI];
00565 
00566             // Check that cell is live (so its parent has no refinement)
00567             if (index >= 0 && splitCells_[index].addedCellsPtr_.valid())
00568             {
00569                 FatalErrorIn
00570                 (
00571                     "refinementHistory::subset"
00572                     "(const labelList&, const labelList&, const labelList&)"
00573                 )   << "Problem" << abort(FatalError);
00574             }
00575 
00576             newVisibleCells[cellI] = index;
00577         }
00578 
00579         if (debug)
00580         {
00581             Pout<< "refinementHistory::updateMesh : from "
00582                 << visibleCells_.size()
00583                 << " to " << newVisibleCells.size()
00584                 << " cells" << endl;
00585         }
00586 
00587         visibleCells_.transfer(newVisibleCells);
00588     }
00589 }
00590 
00591 
00592 void Foam::refinementHistory::countProc
00593 (
00594     const label index,
00595     const label newProcNo,
00596     labelList& splitCellProc,
00597     labelList& splitCellNum
00598 ) const
00599 {
00600     if (splitCellProc[index] != newProcNo)
00601     {
00602         // Different destination processor from other cells using this
00603         // parent. Reset count.
00604         splitCellProc[index] = newProcNo;
00605         splitCellNum[index] = 1;
00606     }
00607     else
00608     {
00609         splitCellNum[index]++;
00610 
00611         // Increment parent if whole splitCell moves to same processor
00612         if (splitCellNum[index] == 8)
00613         {
00614             Pout<< "Moving " << splitCellNum[index]
00615                 << " cells originating from cell " << index
00616                 << " from processor " << Pstream::myProcNo()
00617                 << " to processor " << splitCellProc[index]
00618                 << endl;
00619 
00620             label parent = splitCells_[index].parent_;
00621 
00622             if (parent >= 0)
00623             {
00624                 string oldPrefix = Pout.prefix();
00625                 Pout.prefix() = "  " + oldPrefix;
00626 
00627                 countProc(parent, newProcNo, splitCellProc, splitCellNum);
00628 
00629                 Pout.prefix() = oldPrefix;
00630             }
00631         }
00632     }
00633 }
00634 
00635 
00636 void Foam::refinementHistory::distribute(const mapDistributePolyMesh& map)
00637 {
00638     if (!active())
00639     {
00640         FatalErrorIn
00641         (
00642             "refinementHistory::distribute(const mapDistributePolyMesh&)"
00643         )   << "Calling distribute on inactive history" << abort(FatalError);
00644     }
00645 
00646 
00647     if (!Pstream::parRun())
00648     {
00649         return;
00650     }
00651 
00652     // Remove unreferenced history.
00653     compact();
00654 
00655     Pout<< nl << "--BEFORE:" << endl;
00656     writeDebug();
00657     Pout<< "---------" << nl << endl;
00658 
00659 
00660     // Distribution is only partially functional.
00661     // If all 8 cells resulting from a single parent are sent across in one
00662     // go it will also send across that part of the refinement history.
00663     // If however e.g. first 1 and then the other 7 are sent across the
00664     // history will not be reconstructed.
00665 
00666     // Determine clusters. This is per every entry in splitCells_ (that is
00667     // a parent of some refinement) a label giving the processor it goes to
00668     // if all its children are going to the same processor.
00669 
00670     // Per visible cell the processor it goes to.
00671     labelList destination(visibleCells_.size());
00672 
00673     const labelListList& subCellMap = map.cellMap().subMap();
00674 
00675     forAll(subCellMap, procI)
00676     {
00677         const labelList& newToOld = subCellMap[procI];
00678 
00679         forAll(newToOld, i)
00680         {
00681             label oldCellI = newToOld[i];
00682 
00683             destination[oldCellI] = procI;
00684         }
00685     }
00686 
00687 //Pout<< "refinementHistory::distribute :"
00688 //    << " destination:" << destination << endl;
00689 
00690     // Per splitCell entry the processor it moves to
00691     labelList splitCellProc(splitCells_.size(), -1);
00692     // Per splitCell entry the number of live cells that move to that processor
00693     labelList splitCellNum(splitCells_.size(), 0);
00694 
00695     forAll(visibleCells_, cellI)
00696     {
00697         label index = visibleCells_[cellI];
00698 
00699         if (index >= 0)
00700         {
00701             countProc
00702             (
00703                 splitCells_[index].parent_,
00704                 destination[cellI],
00705                 splitCellProc,
00706                 splitCellNum
00707             );
00708         }
00709     }
00710 
00711 Pout<< "refinementHistory::distribute :"
00712     << " splitCellProc:" << splitCellProc << endl;
00713 
00714 Pout<< "refinementHistory::distribute :"
00715     << " splitCellNum:" << splitCellNum << endl;
00716 
00717 
00718     // Create subsetted refinement tree consisting of all parents that
00719     // move in their whole to other processor.
00720     for (label procI = 0; procI < Pstream::nProcs(); procI++)
00721     {
00722         Pout<< "-- Subetting for processor " << procI << endl;
00723 
00724         // From uncompacted to compacted splitCells.
00725         labelList oldToNew(splitCells_.size(), -1);
00726 
00727         // Compacted splitCells. Similar to subset routine below.
00728         DynamicList<splitCell8> newSplitCells(splitCells_.size());
00729 
00730         // Loop over all entries. Note: could recurse like countProc so only
00731         // visit used entries but is probably not worth it.
00732 
00733         forAll(splitCells_, index)
00734         {
00735 //            Pout<< "oldCell:" << index
00736 //                << " proc:" << splitCellProc[index]
00737 //                << " nCells:" << splitCellNum[index]
00738 //                << endl;
00739 
00740             if (splitCellProc[index] == procI && splitCellNum[index] == 8)
00741             {
00742                 // Entry moves in its whole to procI
00743                 oldToNew[index] = newSplitCells.size();
00744                 newSplitCells.append(splitCells_[index]);
00745 
00746                 Pout<< "Added oldCell " << index
00747                     << " info " << newSplitCells[newSplitCells.size()-1]
00748                     << " at position " << newSplitCells.size()-1
00749                     << endl;
00750             }
00751         }
00752 
00753         // Add live cells that are subsetted.
00754         forAll(visibleCells_, cellI)
00755         {
00756             label index = visibleCells_[cellI];
00757 
00758             if (index >= 0 && destination[cellI] == procI)
00759             {
00760                 label parent = splitCells_[index].parent_;
00761 
00762                 Pout<< "Adding refined cell " << cellI
00763                     << " since moves to "
00764                     << procI << " old parent:" << parent << endl;
00765 
00766                 // Create new splitCell with parent
00767                 oldToNew[index] = newSplitCells.size();
00768                 newSplitCells.append(splitCell8(parent));
00769             }
00770         }
00771 
00772         //forAll(oldToNew, index)
00773         //{
00774         //    Pout<< "old:" << index << " new:" << oldToNew[index]
00775         //        << endl;
00776         //}
00777 
00778         newSplitCells.shrink();
00779 
00780         // Renumber contents of newSplitCells
00781         forAll(newSplitCells, index)
00782         {
00783             splitCell8& split = newSplitCells[index];
00784 
00785             if (split.parent_ >= 0)
00786             {
00787                 split.parent_ = oldToNew[split.parent_];
00788             }
00789             if (split.addedCellsPtr_.valid())
00790             {
00791                 FixedList<label, 8>& splits = split.addedCellsPtr_();
00792 
00793                 forAll(splits, i)
00794                 {
00795                     if (splits[i] >= 0)
00796                     {
00797                         splits[i] = oldToNew[splits[i]];
00798                     }
00799                 }
00800             }
00801         }
00802 
00803 
00804         const labelList& subMap = subCellMap[procI];
00805 
00806         // New visible cells.
00807         labelList newVisibleCells(subMap.size(), -1);
00808 
00809         forAll(subMap, newCellI)
00810         {
00811             label oldCellI = subMap[newCellI];
00812 
00813             label oldIndex = visibleCells_[oldCellI];
00814 
00815             if (oldIndex >= 0)
00816             {
00817                 newVisibleCells[newCellI] = oldToNew[oldIndex];
00818             }
00819         }
00820 
00821         //Pout<< nl << "--Subset for domain:" << procI << endl;
00822         //writeDebug(newVisibleCells, newSplitCells);
00823         //Pout<< "---------" << nl << endl;
00824 
00825 
00826         // Send to neighbours
00827         OPstream toNbr(Pstream::blocking, procI);
00828         toNbr << newSplitCells << newVisibleCells;
00829     }
00830 
00831 
00832     // Receive from neighbours and merge
00833     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00834 
00835     // Remove all entries. Leave storage intact.
00836     splitCells_.clear();
00837 
00838     visibleCells_.setSize(map.mesh().nCells());
00839     visibleCells_ = -1;
00840 
00841     for (label procI = 0; procI < Pstream::nProcs(); procI++)
00842     {
00843         IPstream fromNbr(Pstream::blocking, procI);
00844         List<splitCell8> newSplitCells(fromNbr);
00845         labelList newVisibleCells(fromNbr);
00846 
00847         //Pout<< nl << "--Received from domain:" << procI << endl;
00848         //writeDebug(newVisibleCells, newSplitCells);
00849         //Pout<< "---------" << nl << endl;
00850 
00851 
00852         // newSplitCells contain indices only into newSplitCells so
00853         // renumbering can be done here.
00854         label offset = splitCells_.size();
00855 
00856         Pout<< "**Renumbering data from proc " << procI << " with offset "
00857             << offset << endl;
00858 
00859         forAll(newSplitCells, index)
00860         {
00861             splitCell8& split = newSplitCells[index];
00862 
00863             if (split.parent_ >= 0)
00864             {
00865                 split.parent_ += offset;
00866             }
00867             if (split.addedCellsPtr_.valid())
00868             {
00869                 FixedList<label, 8>& splits = split.addedCellsPtr_();
00870 
00871                 forAll(splits, i)
00872                 {
00873                     if (splits[i] >= 0)
00874                     {
00875                         splits[i] += offset;
00876                     }
00877                 }
00878             }
00879 
00880             splitCells_.append(split);
00881         }
00882 
00883 
00884         // Combine visibleCell.
00885         const labelList& constructMap = map.cellMap().constructMap()[procI];
00886 
00887         forAll(newVisibleCells, i)
00888         {
00889             visibleCells_[constructMap[i]] = newVisibleCells[i] + offset;
00890         }
00891     }
00892     splitCells_.shrink();
00893 
00894     Pout<< nl << "--AFTER:" << endl;
00895     writeDebug();
00896     Pout<< "---------" << nl << endl;
00897 }
00898 
00899 
00900 void Foam::refinementHistory::compact()
00901 {
00902     if (debug)
00903     {
00904         Pout<< "refinementHistory::compact() Entering with:"
00905             << " freeSplitCells_:" << freeSplitCells_.size()
00906             << " splitCells_:" << splitCells_.size()
00907             << " visibleCells_:" << visibleCells_.size()
00908             << endl;
00909 
00910         // Check all free splitCells are marked as such
00911         forAll(freeSplitCells_, i)
00912         {
00913             label index = freeSplitCells_[i];
00914 
00915             if (splitCells_[index].parent_ != -2)
00916             {
00917                 FatalErrorIn("refinementHistory::compact()")
00918                     << "Problem index:" << index
00919                     << abort(FatalError);
00920             }
00921         }
00922 
00923         // Check none of the visible cells are marked as free
00924         forAll(visibleCells_, cellI)
00925         {
00926             if
00927             (
00928                 visibleCells_[cellI] >= 0
00929              && splitCells_[visibleCells_[cellI]].parent_ == -2
00930             )
00931             {
00932                 FatalErrorIn("refinementHistory::compact()")
00933                     << "Problem : visible cell:" << cellI
00934                     << " is marked as being free." << abort(FatalError);
00935             }
00936         }
00937     }
00938 
00939     DynamicList<splitCell8> newSplitCells(splitCells_.size());
00940 
00941     // From uncompacted to compacted splitCells.
00942     labelList oldToNew(splitCells_.size(), -1);
00943 
00944     // Mark all used splitCell entries. These are either indexed by visibleCells
00945     // or indexed from other splitCell entries.
00946 
00947     // Mark from visibleCells
00948     forAll(visibleCells_, cellI)
00949     {
00950         label index = visibleCells_[cellI];
00951 
00952         if (index >= 0)
00953         {
00954             // Make sure we only mark visible indices if they either have a
00955             // parent or subsplits.
00956             if
00957             (
00958                 splitCells_[index].parent_ != -1
00959              || splitCells_[index].addedCellsPtr_.valid()
00960             )
00961             {
00962                 markSplit(index, oldToNew, newSplitCells);
00963             }
00964         }
00965     }
00966 
00967     // Mark from splitCells
00968     forAll(splitCells_, index)
00969     {
00970         if (splitCells_[index].parent_ == -2)
00971         {
00972             // freed cell.
00973         }
00974         else if
00975         (
00976             splitCells_[index].parent_ == -1
00977          && splitCells_[index].addedCellsPtr_.empty()
00978         )
00979         {
00980             // recombined cell. No need to keep since no parent and no subsplits
00981             // Note that gets marked if reachable from other index!
00982         }
00983         else
00984         {
00985             // Is used element.
00986             markSplit(index, oldToNew, newSplitCells);
00987         }
00988     }
00989 
00990 
00991     // Now oldToNew is fully complete and compacted elements are in
00992     // newSplitCells.
00993     // Renumber contents of newSplitCells and visibleCells.
00994     forAll(newSplitCells, index)
00995     {
00996         splitCell8& split = newSplitCells[index];
00997 
00998         if (split.parent_ >= 0)
00999         {
01000             split.parent_ = oldToNew[split.parent_];
01001         }
01002         if (split.addedCellsPtr_.valid())
01003         {
01004             FixedList<label, 8>& splits = split.addedCellsPtr_();
01005 
01006             forAll(splits, i)
01007             {
01008                 if (splits[i] >= 0)
01009                 {
01010                     splits[i] = oldToNew[splits[i]];
01011                 }
01012             }
01013         }
01014     }
01015 
01016 
01017     if (debug)
01018     {
01019         Pout<< "refinementHistory::compact : compacted splitCells from "
01020             << splitCells_.size() << " to " << newSplitCells.size() << endl;
01021     }
01022 
01023     splitCells_.transfer(newSplitCells);
01024     freeSplitCells_.clearStorage();
01025 
01026 
01027     if (debug)
01028     {
01029         Pout<< "refinementHistory::compact() NOW:"
01030             << " freeSplitCells_:" << freeSplitCells_.size()
01031             << " splitCells_:" << splitCells_.size()
01032             << " newSplitCells:" << newSplitCells.size()
01033             << " visibleCells_:" << visibleCells_.size()
01034             << endl;
01035     }
01036 
01037 
01038     // Adapt indices in visibleCells_
01039     forAll(visibleCells_, cellI)
01040     {
01041         label index = visibleCells_[cellI];
01042 
01043         if (index >= 0)
01044         {
01045             // Note that oldToNew can be -1 so it resets newVisibleCells.
01046             visibleCells_[cellI] = oldToNew[index];
01047         }
01048         else
01049         {
01050             // Keep -1 value.
01051         }
01052     }
01053 }
01054 
01055 
01056 void Foam::refinementHistory::writeDebug() const
01057 {
01058     writeDebug(visibleCells_, splitCells_);
01059 }
01060 
01061 
01062 void Foam::refinementHistory::storeSplit
01063 (
01064     const label cellI,
01065     const labelList& addedCells
01066 )
01067 {
01068     label parentIndex = -1;
01069 
01070     if (visibleCells_[cellI] != -1)
01071     {
01072         // Was already live. The current live cell becomes the
01073         // parent of the cells split off from it.
01074 
01075         parentIndex = visibleCells_[cellI];
01076 
01077         // It is no longer live (note that actually cellI gets alive
01078         // again below since is addedCells[0])
01079         visibleCells_[cellI] = -1;
01080     }
01081     else
01082     {
01083         // Create 0th level. -1 parent to denote this.
01084         parentIndex = allocateSplitCell(-1, -1);
01085     }
01086 
01087     // Create live entries for added cells that point to the
01088     // cell they were created from (parentIndex)
01089     forAll(addedCells, i)
01090     {
01091         label addedCellI = addedCells[i];
01092 
01093         // Create entries for the split off cells. All of them
01094         // are visible.
01095         visibleCells_[addedCellI] = allocateSplitCell(parentIndex, i);
01096     }
01097 }
01098 
01099 
01100 void Foam::refinementHistory::combineCells
01101 (
01102     const label masterCellI,
01103     const labelList& combinedCells
01104 )
01105 {
01106     // Save the parent structure
01107     label parentIndex = splitCells_[visibleCells_[masterCellI]].parent_;
01108 
01109     // Remove the information for the combined cells
01110     forAll(combinedCells, i)
01111     {
01112         label cellI = combinedCells[i];
01113 
01114         freeSplitCell(visibleCells_[cellI]);
01115         visibleCells_[cellI] = -1;
01116     }
01117 
01118     splitCell8& parentSplit = splitCells_[parentIndex];
01119     parentSplit.addedCellsPtr_.reset(NULL);
01120     visibleCells_[masterCellI] = parentIndex;
01121 }
01122 
01123 
01124 bool Foam::refinementHistory::readData(Istream& is)
01125 {
01126     is >> *this;
01127     return !is.bad();
01128 }
01129 
01130 
01131 bool Foam::refinementHistory::writeData(Ostream& os) const
01132 {
01133     os << *this;
01134 
01135     return os.good();
01136 }
01137 
01138 
01139 // * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
01140 
01141 Foam::Istream& Foam::operator>>(Istream& is, refinementHistory& rh)
01142 {
01143     rh.freeSplitCells_.clearStorage();
01144 
01145     is >> rh.splitCells_ >> rh.visibleCells_;
01146 
01147     // Check indices.
01148     rh.checkIndices();
01149 
01150     return is;
01151 }
01152 
01153 
01154 Foam::Ostream& Foam::operator<<(Ostream& os, const refinementHistory& rh)
01155 {
01156     const_cast<refinementHistory&>(rh).compact();
01157 
01158     return os   << "// splitCells" << nl
01159                 << rh.splitCells_ << nl
01160                 << "// visibleCells" << nl
01161                 << rh.visibleCells_;
01162 }
01163 
01164 
01165 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines