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

probes.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 "probes.H"
00027 #include <finiteVolume/volFields.H>
00028 #include <OpenFOAM/dictionary.H>
00029 #include <OpenFOAM/Time.H>
00030 #include <OpenFOAM/IOmanip.H>
00031 
00032 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00033 
00034 namespace Foam
00035 {
00036     defineTypeNameAndDebug(probes, 0);
00037 }
00038 
00039 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00040 
00041 void Foam::probes::findElements(const fvMesh& mesh)
00042 {
00043     if (elementList_.empty())
00044     {
00045         elementList_.setSize(probeLocations_.size());
00046 
00047         forAll(probeLocations_, probeI)
00048         {
00049             elementList_[probeI] = mesh.findCell(probeLocations_[probeI]);
00050 
00051             if (debug && elementList_[probeI] != -1)
00052             {
00053                 Pout<< "probes : found point " << probeLocations_[probeI]
00054                     << " in cell " << elementList_[probeI] << endl;
00055             }
00056         }
00057 
00058 
00059         // Check if all probes have been found.
00060         forAll(elementList_, probeI)
00061         {
00062             label cellI = elementList_[probeI];
00063 
00064             // Check at least one processor with cell.
00065             reduce(cellI, maxOp<label>());
00066 
00067             if (cellI == -1)
00068             {
00069                 if (Pstream::master())
00070                 {
00071                     WarningIn("probes::read()")
00072                         << "Did not find location " << probeLocations_[probeI]
00073                         << " in any cell. Skipping location." << endl;
00074                 }
00075             }
00076             else
00077             {
00078                 // Make sure location not on two domains.
00079                 if (elementList_[probeI] != -1 && elementList_[probeI] != cellI)
00080                 {
00081                     WarningIn("probes::read()")
00082                         << "Location " << probeLocations_[probeI]
00083                         << " seems to be on multiple domains:"
00084                         << " cell " << elementList_[probeI]
00085                         << " on my domain " << Pstream::myProcNo()
00086                         << " and cell " << cellI << " on some other domain."
00087                         << endl
00088                         << "This might happen if the probe location is on"
00089                         << " a processor patch. Change the location slightly"
00090                         << " to prevent this." << endl;
00091                 }
00092             }
00093         }
00094     }
00095 }
00096 
00097 
00098 bool Foam::probes::checkFieldTypes()
00099 {
00100     wordList fieldTypes(fieldNames_.size());
00101 
00102     // check files for a particular time
00103     if (loadFromFiles_)
00104     {
00105         forAll(fieldNames_, fieldI)
00106         {
00107             IOobject io
00108             (
00109                 fieldNames_[fieldI],
00110                 obr_.time().timeName(),
00111                 refCast<const polyMesh>(obr_),
00112                 IOobject::MUST_READ,
00113                 IOobject::NO_WRITE,
00114                 false
00115             );
00116 
00117             if (io.headerOk())
00118             {
00119                 fieldTypes[fieldI] = io.headerClassName();
00120             }
00121             else
00122             {
00123                 fieldTypes[fieldI] = "(notFound)";
00124             }
00125         }
00126     }
00127     else
00128     {
00129         // check objectRegistry
00130         forAll(fieldNames_, fieldI)
00131         {
00132             objectRegistry::const_iterator iter =
00133                 obr_.find(fieldNames_[fieldI]);
00134 
00135             if (iter != obr_.end())
00136             {
00137                 fieldTypes[fieldI] = iter()->type();
00138             }
00139             else
00140             {
00141                 fieldTypes[fieldI] = "(notFound)";
00142             }
00143         }
00144     }
00145 
00146 
00147     label nFields = 0;
00148 
00149     // classify fieldTypes
00150     nFields += countFields(scalarFields_, fieldTypes);
00151     nFields += countFields(vectorFields_, fieldTypes);
00152     nFields += countFields(sphericalTensorFields_, fieldTypes);
00153     nFields += countFields(symmTensorFields_, fieldTypes);
00154     nFields += countFields(tensorFields_, fieldTypes);
00155 
00156     // concatenate all the lists into foundFields
00157     wordList foundFields(nFields);
00158 
00159     label fieldI = 0;
00160     forAll(scalarFields_, i)
00161     {
00162         foundFields[fieldI++] = scalarFields_[i];
00163     }
00164     forAll(vectorFields_, i)
00165     {
00166         foundFields[fieldI++] = vectorFields_[i];
00167     }
00168     forAll(sphericalTensorFields_, i)
00169     {
00170         foundFields[fieldI++] = sphericalTensorFields_[i];
00171     }
00172     forAll(symmTensorFields_, i)
00173     {
00174         foundFields[fieldI++] = symmTensorFields_[i];
00175     }
00176     forAll(tensorFields_, i)
00177     {
00178         foundFields[fieldI++] = tensorFields_[i];
00179     }
00180 
00181     if (Pstream::master())
00182     {
00183         fileName probeDir;
00184 
00185         fileName probeSubDir = name_;
00186 
00187         if (obr_.name() != polyMesh::defaultRegion)
00188         {
00189             probeSubDir = probeSubDir/obr_.name();
00190         }
00191         probeSubDir = probeSubDir/obr_.time().timeName();
00192 
00193         if (Pstream::parRun())
00194         {
00195             // Put in undecomposed case
00196             // (Note: gives problems for distributed data running)
00197             probeDir = obr_.time().path()/".."/probeSubDir;
00198         }
00199         else
00200         {
00201             probeDir = obr_.time().path()/probeSubDir;
00202         }
00203 
00204         // Close the file if any fields have been removed.
00205         forAllIter(HashPtrTable<OFstream>, probeFilePtrs_, iter)
00206         {
00207             if (findIndex(foundFields, iter.key()) == -1)
00208             {
00209                 if (debug)
00210                 {
00211                     Pout<< "close stream: " << iter()->name() << endl;
00212                 }
00213 
00214                 delete probeFilePtrs_.remove(iter);
00215             }
00216         }
00217 
00218         // Open new files for new fields. Keep existing files.
00219 
00220         probeFilePtrs_.resize(2*foundFields.size());
00221 
00222         forAll(foundFields, fieldI)
00223         {
00224             const word& fldName = foundFields[fieldI];
00225 
00226             // Check if added field. If so open a stream for it.
00227 
00228             if (!probeFilePtrs_.found(fldName))
00229             {
00230                 // Create directory if does not exist.
00231                 mkDir(probeDir);
00232 
00233                 OFstream* sPtr = new OFstream(probeDir/fldName);
00234 
00235                 if (debug)
00236                 {
00237                     Pout<< "open  stream: " << sPtr->name() << endl;
00238                 }
00239 
00240                 probeFilePtrs_.insert(fldName, sPtr);
00241 
00242                 unsigned int w = IOstream::defaultPrecision() + 7;
00243 
00244                 for (direction cmpt=0; cmpt<vector::nComponents; cmpt++)
00245                 {
00246                     *sPtr<< '#' << setw(IOstream::defaultPrecision() + 6)
00247                         << vector::componentNames[cmpt];
00248 
00249                     forAll(probeLocations_, probeI)
00250                     {
00251                         *sPtr<< ' ' << setw(w) << probeLocations_[probeI][cmpt];
00252                     }
00253                     *sPtr << endl;
00254                 }
00255 
00256                 *sPtr<< '#' << setw(IOstream::defaultPrecision() + 6)
00257                     << "Time" << endl;
00258             }
00259         }
00260 
00261         if (debug)
00262         {
00263             Pout<< "Probing fields:" << foundFields << nl
00264                 << "Probing locations:" << probeLocations_ << nl
00265                 << endl;
00266         }
00267     }
00268 
00269 
00270     return nFields > 0;
00271 }
00272 
00273 
00274 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00275 
00276 Foam::probes::probes
00277 (
00278     const word& name,
00279     const objectRegistry& obr,
00280     const dictionary& dict,
00281     const bool loadFromFiles
00282 )
00283 :
00284     name_(name),
00285     obr_(obr),
00286     loadFromFiles_(loadFromFiles),
00287     fieldNames_(0),
00288     probeLocations_(0),
00289     scalarFields_(),
00290     vectorFields_(),
00291     sphericalTensorFields_(),
00292     symmTensorFields_(),
00293     tensorFields_(),
00294     elementList_(0),
00295     probeFilePtrs_(0)
00296 {
00297     read(dict);
00298 }
00299 
00300 
00301 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00302 
00303 Foam::probes::~probes()
00304 {}
00305 
00306 
00307 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00308 
00309 void Foam::probes::execute()
00310 {
00311     // Do nothing - only valid on write
00312 }
00313 
00314 
00315 void Foam::probes::end()
00316 {
00317     // Do nothing - only valid on write
00318 }
00319 
00320 
00321 void Foam::probes::write()
00322 {
00323     if (probeLocations_.size() && checkFieldTypes())
00324     {
00325         sampleAndWrite(scalarFields_);
00326         sampleAndWrite(vectorFields_);
00327         sampleAndWrite(sphericalTensorFields_);
00328         sampleAndWrite(symmTensorFields_);
00329         sampleAndWrite(tensorFields_);
00330     }
00331 }
00332 
00333 
00334 void Foam::probes::read(const dictionary& dict)
00335 {
00336     dict.lookup("fields") >> fieldNames_;
00337     dict.lookup("probeLocations") >> probeLocations_;
00338 
00339     // Force all cell locations to be redetermined
00340     elementList_.clear();
00341     findElements(refCast<const fvMesh>(obr_));
00342     checkFieldTypes();
00343 }
00344 
00345 
00346 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines