00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 #include <OpenFOAM/argList.H>
00070 #include <OpenFOAM/Time.H>
00071 #include <OpenFOAM/polyMesh.H>
00072 #include <OpenFOAM/globalMeshData.H>
00073 #include <OpenFOAM/IStringStream.H>
00074 #include <meshTools/cellSet.H>
00075 #include <meshTools/faceSet.H>
00076 #include <meshTools/pointSet.H>
00077 #include <meshTools/topoSetSource.H>
00078 #include <OpenFOAM/OFstream.H>
00079 #include <OpenFOAM/IFstream.H>
00080 #include <OpenFOAM/demandDrivenData.H>
00081 #include "writePatch.H"
00082 #include "writePointSet.H"
00083 #include <OpenFOAM/IOobjectList.H>
00084 #include <meshTools/cellZoneSet.H>
00085 #include <meshTools/faceZoneSet.H>
00086 #include <meshTools/pointZoneSet.H>
00087 
00088 #include <stdio.h>
00089 
00090 
00091 #if READLINE != 0
00092 # include <readline/readline.h>
00093 # include <readline/history.h>
00094 #endif
00095 
00096 using namespace Foam;
00097 
00098 
00099 
00100 
00101 #if READLINE != 0
00102 static const char* historyFile = ".setSet";
00103 #endif
00104 
00105 Istream& selectStream(Istream* is0Ptr, Istream* is1Ptr)
00106 {
00107     if (is0Ptr)
00108     {
00109         return *is0Ptr;
00110     }
00111     else if (is1Ptr)
00112     {
00113         return *is1Ptr;
00114     }
00115     else
00116     {
00117         FatalErrorIn("selectStream(Istream*, Istream*)")
00118             << "No valid stream opened" << abort(FatalError);
00119 
00120         return *is0Ptr;
00121     }
00122 }
00123 
00124 
00125 void backup
00126 (
00127     const word& setType,
00128     const polyMesh& mesh,
00129     const word& fromName,
00130     const topoSet& fromSet,
00131     const word& toName
00132 )
00133 {
00134     if (fromSet.size())
00135     {
00136         Info<< "    Backing up " << fromName << " into " << toName << endl;
00137 
00138         topoSet::New(setType, mesh, toName, fromSet)().write();
00139     }
00140 }
00141 
00142 
00143 
00144 void backup
00145 (
00146     const word& setType,
00147     const polyMesh& mesh,
00148     const word& fromName,
00149     const word& toName
00150 )
00151 {
00152     autoPtr<topoSet> fromSet = topoSet::New
00153     (
00154         setType,
00155         mesh,
00156         fromName,
00157         IOobject::READ_IF_PRESENT
00158     );
00159 
00160     backup(setType, mesh, fromName, fromSet(), toName);
00161 }
00162 
00163 
00164 
00165 void writeVTK
00166 (
00167     const polyMesh& mesh,
00168     const topoSet& currentSet,
00169     const fileName& vtkName
00170 )
00171 {
00172     if (isA<faceSet>(currentSet))
00173     {
00174         
00175 
00176         faceList setFaces(currentSet.size());
00177         labelList faceValues(currentSet.size());
00178         label setFaceI = 0;
00179 
00180         forAllConstIter(topoSet, currentSet, iter)
00181         {
00182             setFaces[setFaceI] = mesh.faces()[iter.key()];
00183             faceValues[setFaceI] = iter.key();
00184             setFaceI++;
00185         }
00186 
00187         primitiveFacePatch fp(setFaces, mesh.points());
00188 
00189         writePatch
00190         (
00191             true,
00192             currentSet.name(),
00193             fp,
00194             "faceID",
00195             faceValues,
00196             mesh.time().path()/vtkName
00197         );
00198     }
00199     else if (isA<cellSet>(currentSet))
00200     {
00201         
00202 
00203         Map<label> cellFaces(currentSet.size());
00204 
00205         forAllConstIter(cellSet, currentSet, iter)
00206         {
00207             label cellI = iter.key();
00208 
00209             const cell& cFaces = mesh.cells()[cellI];
00210 
00211             forAll(cFaces, i)
00212             {
00213                 label faceI = cFaces[i];
00214 
00215                 if (mesh.isInternalFace(faceI))
00216                 {
00217                     label otherCellI = mesh.faceOwner()[faceI];
00218 
00219                     if (otherCellI == cellI)
00220                     {
00221                         otherCellI = mesh.faceNeighbour()[faceI];
00222                     }
00223 
00224                     if (!currentSet.found(otherCellI))
00225                     {
00226                         cellFaces.insert(faceI, cellI);
00227                     }
00228                 }
00229                 else
00230                 {
00231                     cellFaces.insert(faceI, cellI);
00232                 }
00233             }
00234         }
00235 
00236         faceList setFaces(cellFaces.size());
00237         labelList faceValues(cellFaces.size());
00238         label setFaceI = 0;
00239 
00240         forAllConstIter(Map<label>, cellFaces, iter)
00241         {
00242             setFaces[setFaceI] = mesh.faces()[iter.key()];
00243             faceValues[setFaceI] = iter();              
00244             setFaceI++;
00245         }
00246 
00247         primitiveFacePatch fp(setFaces, mesh.points());
00248 
00249         writePatch
00250         (
00251             true,
00252             currentSet.name(),
00253             fp,
00254             "cellID",
00255             faceValues,
00256             mesh.time().path()/vtkName
00257         );
00258     }
00259     else if (isA<pointSet>(currentSet))
00260     {
00261         writePointSet
00262         (
00263             true,
00264             mesh,
00265             currentSet,
00266             mesh.time().path()/vtkName
00267         );
00268     }
00269     else
00270     {
00271         WarningIn
00272         (
00273             "void writeVTK"
00274             "(const polyMesh& mesh, const topoSet& currentSet,"
00275             "const fileName& vtkName)"
00276         )   << "Don't know how to handle set of type " << currentSet.type()
00277             << endl;
00278     }
00279 }
00280 
00281 
00282 void printHelp(Ostream& os)
00283 {
00284     os  << "Please type 'help', 'list', 'quit', 'time ddd'"
00285         << " or a set command after prompt." << endl
00286         << "'list' will show all current cell/face/point sets." << endl
00287         << "'time ddd' will change the current time." << endl
00288         << endl
00289         << "A set command should be of the following form" << endl
00290         << endl
00291         << "    cellSet|faceSet|pointSet <setName> <action> <source>"
00292         << endl
00293         << endl
00294         << "The <action> is one of" << endl
00295         << "    list            - prints the contents of the set" << endl
00296         << "    clear           - clears the set" << endl
00297         << "    invert          - inverts the set" << endl
00298         << "    remove          - remove the set" << endl
00299         << "    new <source>    - sets to set to the source set" << endl
00300         << "    add <source>    - adds all elements from the source set" << endl
00301         << "    delete <source> - deletes      ,," << endl
00302         << "    subset <source> - combines current set with the source set"
00303         << endl
00304         << endl
00305         << "The sources come in various forms. Type a wrong source"
00306         << " to see all the types available." << endl
00307         << endl
00308         << "Example: pick up all cells connected by point or face to patch"
00309         << " movingWall" << endl
00310         << endl
00311         << "Pick up all faces of patch:" << endl
00312         << "    faceSet f0 new patchToFace movingWall" << endl
00313         << "Add faces 0,1,2:" << endl
00314         << "    faceSet f0 add labelToFace (0 1 2)" << endl
00315         << "Pick up all points used by faces in faceSet f0:" << endl
00316         << "    pointSet p0 new faceToPoint f0 all" << endl
00317         << "Pick up cell which has any face in f0:" << endl
00318         << "    cellSet c0 new faceToCell f0 any" << endl
00319         << "Add cells which have any point in p0:" << endl
00320         << "    cellSet c0 add pointToCell p0 any" << endl
00321         << "List set:" << endl
00322         << "    cellSet c0 list" << endl
00323         << endl
00324         << "Zones can be set using zoneSets from corresponding sets:" << endl
00325         << "    cellZoneSet c0Zone new setToCellZone c0" << endl
00326         << "    faceZoneSet f0Zone new setToFaceZone f0" << endl
00327         << endl
00328         << "or if orientation is important:" << endl
00329         << "    faceZoneSet f0Zone new setsToFaceZone f0 c0" << endl
00330         << endl
00331         << "ZoneSets can be manipulated using the general actions:" << endl
00332         << "    list            - prints the contents of the set" << endl
00333         << "    clear           - clears the set" << endl
00334         << "    invert          - inverts the set (undefined orientation)"
00335         << endl
00336         << "    remove          - remove the set" << endl
00337         << endl;
00338 }
00339 
00340 
00341 void printAllSets(const polyMesh& mesh, Ostream& os)
00342 {
00343     IOobjectList objects
00344     (
00345         mesh,
00346         mesh.pointsInstance(),
00347         polyMesh::meshSubDir/"sets"
00348     );
00349     IOobjectList cellSets(objects.lookupClass(cellSet::typeName));
00350     if (cellSets.size())
00351     {
00352         os  << "cellSets:" << endl;
00353         forAllConstIter(IOobjectList, cellSets, iter)
00354         {
00355             cellSet set(*iter());
00356             os  << '\t' << set.name() << "\tsize:" << set.size() << endl;
00357         }
00358     }
00359     IOobjectList faceSets(objects.lookupClass(faceSet::typeName));
00360     if (faceSets.size())
00361     {
00362         os  << "faceSets:" << endl;
00363         forAllConstIter(IOobjectList, faceSets, iter)
00364         {
00365             faceSet set(*iter());
00366             os  << '\t' << set.name() << "\tsize:" << set.size() << endl;
00367         }
00368     }
00369     IOobjectList pointSets(objects.lookupClass(pointSet::typeName));
00370     if (pointSets.size())
00371     {
00372         os  << "pointSets:" << endl;
00373         forAllConstIter(IOobjectList, pointSets, iter)
00374         {
00375             pointSet set(*iter());
00376             os  << '\t' << set.name() << "\tsize:" << set.size() << endl;
00377         }
00378     }
00379 
00380     const cellZoneMesh& cellZones = mesh.cellZones();
00381     if (cellZones.size())
00382     {
00383         os  << "cellZones:" << endl;
00384         forAll(cellZones, i)
00385         {
00386             const cellZone& zone = cellZones[i];
00387             os  << '\t' << zone.name() << "\tsize:" << zone.size() << endl;
00388         }
00389     }
00390     const faceZoneMesh& faceZones = mesh.faceZones();
00391     if (faceZones.size())
00392     {
00393         os  << "faceZones:" << endl;
00394         forAll(faceZones, i)
00395         {
00396             const faceZone& zone = faceZones[i];
00397             os  << '\t' << zone.name() << "\tsize:" << zone.size() << endl;
00398         }
00399     }
00400     const pointZoneMesh& pointZones = mesh.pointZones();
00401     if (pointZones.size())
00402     {
00403         os  << "pointZones:" << endl;
00404         forAll(pointZones, i)
00405         {
00406             const pointZone& zone = pointZones[i];
00407             os  << '\t' << zone.name() << "\tsize:" << zone.size() << endl;
00408         }
00409     }
00410 
00411     os  << endl;
00412 }
00413 
00414 
00415 template<class ZoneType>
00416 void removeZone
00417 (
00418     ZoneMesh<ZoneType, polyMesh>& zones,
00419     const word& setName
00420 )
00421 {
00422     label zoneID = zones.findZoneID(setName);
00423 
00424     if (zoneID != -1)
00425     {
00426         Info<< "Removing zone " << setName << " at index " << zoneID << endl;
00427         
00428         labelList oldToNew(zones.size());
00429         label newI = 0;
00430         forAll(oldToNew, i)
00431         {
00432             if (i != zoneID)
00433             {
00434                 oldToNew[i] = newI++;
00435             }
00436         }
00437         oldToNew[zoneID] = newI;
00438         zones.reorder(oldToNew);
00439         
00440         zones.setSize(zones.size()-1);
00441         zones.clearAddressing();
00442         zones.write();
00443     }
00444 }
00445 
00446 
00447 
00448 void removeSet
00449 (
00450     const polyMesh& mesh,
00451     const word& setType,
00452     const word& setName
00453 )
00454 {
00455     
00456     IOobjectList objects
00457     (
00458         mesh,
00459         mesh.pointsInstance(),
00460         polyMesh::meshSubDir/"sets"
00461     );
00462 
00463     if (objects.found(setName))
00464     {
00465         
00466         fileName object = objects[setName]->objectPath();
00467         Info<< "Removing file " << object << endl;
00468         rm(object);
00469     }
00470 
00471     
00472     if (setType == cellZoneSet::typeName)
00473     {
00474         removeZone
00475         (
00476             const_cast<cellZoneMesh&>(mesh.cellZones()),
00477             setName
00478         );
00479     }
00480     else if (setType == faceZoneSet::typeName)
00481     {
00482         removeZone
00483         (
00484             const_cast<faceZoneMesh&>(mesh.faceZones()),
00485             setName
00486         );
00487     }
00488     else if (setType == pointZoneSet::typeName)
00489     {
00490         removeZone
00491         (
00492             const_cast<pointZoneMesh&>(mesh.pointZones()),
00493             setName
00494         );
00495     }
00496 }
00497 
00498 
00499 
00500 bool doCommand
00501 (
00502     const polyMesh& mesh,
00503     const word& setType,
00504     const word& setName,
00505     const word& actionName,
00506     const bool writeVTKFile,
00507     Istream& is
00508 )
00509 {
00510     
00511     const globalMeshData& parData = mesh.globalData();
00512 
00513     label typSize =
00514         max
00515         (
00516             parData.nTotalCells(),
00517             max
00518             (
00519                 parData.nTotalFaces(),
00520                 parData.nTotalPoints()
00521             )
00522         )
00523       / (10*Pstream::nProcs());
00524 
00525 
00526     bool ok = true;
00527 
00528     
00529     autoPtr<topoSet> currentSetPtr;
00530 
00531     word sourceType;
00532 
00533     try
00534     {
00535         topoSetSource::setAction action =
00536             topoSetSource::toAction(actionName);
00537 
00538 
00539         IOobject::readOption r;
00540 
00541         if (action == topoSetSource::REMOVE)
00542         {
00543             removeSet(mesh, setType, setName);
00544         }
00545         else if
00546         (
00547             (action == topoSetSource::NEW)
00548          || (action == topoSetSource::CLEAR)
00549         )
00550         {
00551             r = IOobject::NO_READ;
00552             currentSetPtr = topoSet::New(setType, mesh, setName, typSize);
00553         }
00554         else
00555         {
00556             r = IOobject::MUST_READ;
00557             currentSetPtr = topoSet::New(setType, mesh, setName, r);
00558             topoSet& currentSet = currentSetPtr();
00559             
00560             currentSet.resize(max(currentSet.size(), typSize));
00561         }
00562 
00563         if (currentSetPtr.valid())
00564         {
00565             topoSet& currentSet = currentSetPtr();
00566 
00567             Info<< "    Set:" << currentSet.name()
00568                 << "  Size:" << currentSet.size()
00569                 << "  Action:" << actionName
00570                 << endl;
00571 
00572             switch (action)
00573             {
00574                 case topoSetSource::CLEAR:
00575                 {
00576                     
00577                     break;
00578                 }
00579                 case topoSetSource::INVERT:
00580                 {
00581                     currentSet.invert(currentSet.maxSize(mesh));
00582                     break;
00583                 }
00584                 case topoSetSource::LIST:
00585                 {
00586                     currentSet.writeDebug(Pout, mesh, 100);
00587                     Pout<< endl;
00588                     break;
00589                 }
00590                 case topoSetSource::SUBSET:
00591                 {
00592                     if (is >> sourceType)
00593                     {
00594                         autoPtr<topoSetSource> setSource
00595                         (
00596                             topoSetSource::New
00597                             (
00598                                 sourceType,
00599                                 mesh,
00600                                 is
00601                             )
00602                         );
00603 
00604                         
00605                         autoPtr<topoSet> oldSet
00606                         (
00607                             topoSet::New
00608                             (
00609                                 setType,
00610                                 mesh,
00611                                 currentSet.name() + "_old2",
00612                                 currentSet
00613                             )
00614                         );
00615 
00616                         currentSet.clear();
00617                         setSource().applyToSet(topoSetSource::NEW, currentSet);
00618 
00619                         
00620                         currentSet.subset(oldSet);
00621                     }
00622                     break;
00623                 }
00624                 default:
00625                 {
00626                     if (is >> sourceType)
00627                     {
00628                         autoPtr<topoSetSource> setSource
00629                         (
00630                             topoSetSource::New
00631                             (
00632                                 sourceType,
00633                                 mesh,
00634                                 is
00635                             )
00636                         );
00637 
00638                         setSource().applyToSet(action, currentSet);
00639                     }
00640                 }
00641             }
00642 
00643 
00644             if (action != topoSetSource::LIST)
00645             {
00646                 
00647 
00648                 
00649                 currentSet.sync(mesh);
00650 
00651                 
00652                 if (writeVTKFile)
00653                 {
00654                     mkDir(mesh.time().path()/"VTK"/currentSet.name());
00655 
00656                     fileName vtkName
00657                     (
00658                         "VTK"/currentSet.name()/currentSet.name()
00659                       + "_"
00660                       + name(mesh.time().timeIndex())
00661                       + ".vtk"
00662                     );
00663 
00664                     Info<< "    Writing " << currentSet.name()
00665                         << " (size " << currentSet.size() << ") to "
00666                         << currentSet.instance()/currentSet.local()
00667                            /currentSet.name()
00668                         << " and to vtk file " << vtkName << endl << endl;
00669 
00670                     currentSet.write();
00671 
00672                     writeVTK(mesh, currentSet, vtkName);
00673                 }
00674                 else
00675                 {
00676                     Info<< "    Writing " << currentSet.name()
00677                         << " (size " << currentSet.size() << ") to "
00678                         << currentSet.instance()/currentSet.local()
00679                            /currentSet.name() << endl << endl;
00680 
00681                     currentSet.write();
00682                 }
00683             }
00684         }
00685     }
00686     catch (Foam::IOerror& fIOErr)
00687     {
00688         ok = false;
00689 
00690         Pout<< fIOErr.message().c_str() << endl;
00691 
00692         if (sourceType.size())
00693         {
00694             Pout<< topoSetSource::usage(sourceType).c_str();
00695         }
00696     }
00697     catch (Foam::error& fErr)
00698     {
00699         ok = false;
00700 
00701         Pout<< fErr.message().c_str() << endl;
00702 
00703         if (sourceType.size())
00704         {
00705             Pout<< topoSetSource::usage(sourceType).c_str();
00706         }
00707     }
00708 
00709     return ok;
00710 }
00711 
00712 
00713 
00714 enum commandStatus
00715 {
00716     QUIT,           
00717     INVALID,        
00718     VALIDSETCMD,    
00719     VALIDZONECMD    
00720 };
00721 
00722 
00723 void printMesh(const Time& runTime, const polyMesh& mesh)
00724 {
00725     Info<< "Time:" << runTime.timeName()
00726         << "  cells:" << mesh.nCells()
00727         << "  faces:" << mesh.nFaces()
00728         << "  points:" << mesh.nPoints()
00729         << "  patches:" << mesh.boundaryMesh().size()
00730         << "  bb:" << mesh.bounds() << nl;
00731 }
00732 
00733 
00734 
00735 commandStatus parseType
00736 (
00737     Time& runTime,
00738     polyMesh& mesh,
00739     const word& setType,
00740     IStringStream& is
00741 )
00742 {
00743     if (setType.empty())
00744     {
00745         Info<< "Type 'help' for usage information" << endl;
00746 
00747         return INVALID;
00748     }
00749     else if (setType == "help")
00750     {
00751         printHelp(Info);
00752 
00753         return INVALID;
00754     }
00755     else if (setType == "list")
00756     {
00757         printAllSets(mesh, Info);
00758 
00759         return INVALID;
00760     }
00761     else if (setType == "time")
00762     {
00763         scalar requestedTime = readScalar(is);
00764         instantList Times = runTime.times();
00765 
00766         label nearestIndex = Time::findClosestTimeIndex(Times, requestedTime);
00767 
00768         Info<< "Changing time from " << runTime.timeName()
00769             << " to " << Times[nearestIndex].name()
00770             << endl;
00771 
00772         runTime.setTime(Times[nearestIndex], nearestIndex);
00773         polyMesh::readUpdateState stat = mesh.readUpdate();
00774 
00775         switch(stat)
00776         {
00777             case polyMesh::UNCHANGED:
00778             {
00779                 Info<< "    mesh not changed." << endl;
00780                 break;
00781             }
00782             case polyMesh::POINTS_MOVED:
00783             {
00784                 Info<< "    points moved; topology unchanged." << endl;
00785                 break;
00786             }
00787             case polyMesh::TOPO_CHANGE:
00788             {
00789                 Info<< "    topology changed; patches unchanged." << nl
00790                     << "    ";
00791                 printMesh(runTime, mesh);
00792                 break;
00793             }
00794             case polyMesh::TOPO_PATCH_CHANGE:
00795             {
00796                 Info<< "    topology changed and patches changed." << nl
00797                     << "    ";
00798                 printMesh(runTime, mesh);
00799 
00800                 break;
00801             }
00802             default:
00803             {
00804                 FatalErrorIn("parseType")
00805                     << "Illegal mesh update state "
00806                     << stat  << abort(FatalError);
00807                 break;
00808             }
00809         }
00810 
00811         return INVALID;
00812     }
00813     else if (setType == "quit")
00814     {
00815         Info<< "Quitting ..." << endl;
00816 
00817         return QUIT;
00818     }
00819     else if
00820     (
00821         setType == "cellSet"
00822      || setType == "faceSet"
00823      || setType == "pointSet"
00824     )
00825     {
00826         return VALIDSETCMD;
00827     }
00828     else if
00829     (
00830         setType == "cellZoneSet"
00831      || setType == "faceZoneSet"
00832      || setType == "pointZoneSet"
00833     )
00834     {
00835         return VALIDZONECMD;
00836     }
00837     else
00838     {
00839         SeriousErrorIn
00840         (
00841             "commandStatus parseType(Time&, polyMesh&, const word&"
00842             ", IStringStream&)"
00843         )   << "Illegal command " << setType << endl
00844             << "Should be one of 'help', 'list', 'time' or a set type :"
00845             << " 'cellSet', 'faceSet', 'pointSet', 'faceZoneSet'"
00846             << endl;
00847 
00848         return INVALID;
00849     }
00850 }
00851 
00852 
00853 commandStatus parseAction(const word& actionName)
00854 {
00855     commandStatus stat = INVALID;
00856 
00857     if (actionName.size())
00858     {
00859         try
00860         {
00861             (void)topoSetSource::toAction(actionName);
00862 
00863             stat = VALIDSETCMD;
00864         }
00865         catch (Foam::IOerror& fIOErr)
00866         {
00867             stat = INVALID;
00868         }
00869         catch (Foam::error& fErr)
00870         {
00871             stat = INVALID;
00872         }
00873     }
00874     return stat;
00875 }
00876 
00877 
00878 
00879 
00880 int main(int argc, char *argv[])
00881 {
00882 #   include <OpenFOAM/addRegionOption.H>
00883 #   include <OpenFOAM/addTimeOptions.H>
00884 
00885     argList::validOptions.insert("noVTK", "");
00886     argList::validOptions.insert("batch", "file");
00887 
00888 #   include <OpenFOAM/setRootCase.H>
00889 #   include <OpenFOAM/createTime.H>
00890 
00891     bool writeVTK = !args.optionFound("noVTK");
00892 
00893     
00894     instantList Times = runTime.times();
00895 
00896 #   include <OpenFOAM/checkTimeOptions.H>
00897 
00898     runTime.setTime(Times[startTime], startTime);
00899 
00900 #   include <OpenFOAM/createNamedPolyMesh.H>
00901 
00902     
00903     printMesh(runTime, mesh);
00904 
00905     
00906     printAllSets(mesh, Info);
00907 
00908 
00909 
00910     std::ifstream* fileStreamPtr(NULL);
00911 
00912     if (args.optionFound("batch"))
00913     {
00914         fileName batchFile(args.option("batch"));
00915 
00916         Info<< "Reading commands from file " << batchFile << endl;
00917 
00918         
00919         if (!isFile(batchFile, false))
00920         {
00921             FatalErrorIn(args.executable())
00922                 << "Cannot open file " << batchFile << exit(FatalError);
00923         }
00924 
00925         fileStreamPtr = new std::ifstream(batchFile.c_str());
00926     }
00927 #if READLINE != 0
00928     else if (!read_history(historyFile))
00929     {
00930         Info<< "Successfully read history from " << historyFile << endl;
00931     }
00932 #endif
00933 
00934     Info<< "Please type 'help', 'quit' or a set command after prompt." << endl;
00935 
00936     bool ok = true;
00937 
00938     FatalError.throwExceptions();
00939     FatalIOError.throwExceptions();
00940 
00941     do
00942     {
00943         string rawLine;
00944 
00945         
00946         word setType;
00947         
00948         word setName;
00949         
00950         word actionName;
00951 
00952         commandStatus stat = INVALID;
00953 
00954         if (fileStreamPtr)
00955         {
00956             if (!fileStreamPtr->good())
00957             {
00958                 Info<< "End of batch file" << endl;
00959                 break;
00960             }
00961 
00962             std::getline(*fileStreamPtr, rawLine);
00963 
00964             if (rawLine.size())
00965             {
00966                 Info<< "Doing:" << rawLine << endl;
00967             }
00968         }
00969         else
00970         {
00971 #           if READLINE != 0
00972             {
00973                 char* linePtr = readline("readline>");
00974 
00975                 rawLine = string(linePtr);
00976 
00977                 if (*linePtr)
00978                 {
00979                     add_history(linePtr);
00980                     write_history(historyFile);
00981                 }
00982 
00983                 free(linePtr);   
00984             }
00985 #           else
00986             {
00987                 Info<< "Command>" << flush;
00988                 std::getline(std::cin, rawLine);
00989             }
00990 #           endif
00991         }
00992 
00993         if (rawLine.empty() || rawLine[0] == '#')
00994         {
00995             continue;
00996         }
00997 
00998         IStringStream is(rawLine + ' ');
00999 
01000         
01001         is >> setType;
01002 
01003         stat = parseType(runTime, mesh, setType, is);
01004 
01005         if (stat == VALIDSETCMD || stat == VALIDZONECMD)
01006         {
01007             if (is >> setName)
01008             {
01009                 if (is >> actionName)
01010                 {
01011                     stat = parseAction(actionName);
01012                 }
01013             }
01014         }
01015         ok = true;
01016 
01017         if (stat == QUIT)
01018         {
01019             break;
01020         }
01021         else if (stat == VALIDSETCMD || stat == VALIDZONECMD)
01022         {
01023             ok = doCommand(mesh, setType, setName, actionName, writeVTK, is);
01024         }
01025 
01026     } while (ok);
01027 
01028 
01029     if (fileStreamPtr)
01030     {
01031         delete fileStreamPtr;
01032     }
01033 
01034     Info<< "\nEnd\n" << endl;
01035 
01036     return 0;
01037 }
01038 
01039 
01040