ENH: autoLayerDriver: better layering information message
[OpenFOAM-2.0.x.git] / src / sampling / probes / probes.C
blobb0a073e1e400b8b3cef254c9e0b1f06bbca603f2
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
11     OpenFOAM is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by
13     the Free Software Foundation, either version 3 of the License, or
14     (at your option) any later version.
16     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "probes.H"
27 #include "volFields.H"
28 #include "dictionary.H"
29 #include "Time.H"
30 #include "IOmanip.H"
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 defineTypeNameAndDebug(Foam::probes, 0);
37 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
39 void Foam::probes::findElements(const fvMesh& mesh)
41     elementList_.clear();
42     elementList_.setSize(size());
44     forAll(*this, probeI)
45     {
46         const vector& location = operator[](probeI);
48         elementList_[probeI] = mesh.findCell(location);
50         if (debug && elementList_[probeI] != -1)
51         {
52             Pout<< "probes : found point " << location
53                 << " in cell " << elementList_[probeI] << endl;
54         }
55     }
58     // Check if all probes have been found.
59     forAll(elementList_, probeI)
60     {
61         const vector& location = operator[](probeI);
62         label cellI = elementList_[probeI];
64         // Check at least one processor with cell.
65         reduce(cellI, maxOp<label>());
67         if (cellI == -1)
68         {
69             if (Pstream::master())
70             {
71                 WarningIn("probes::read()")
72                     << "Did not find location " << location
73                     << " in any cell. Skipping location." << endl;
74             }
75         }
76         else
77         {
78             // Make sure location not on two domains.
79             if (elementList_[probeI] != -1 && elementList_[probeI] != cellI)
80             {
81                 WarningIn("probes::read()")
82                     << "Location " << location
83                     << " seems to be on multiple domains:"
84                     << " cell " << elementList_[probeI]
85                     << " on my domain " << Pstream::myProcNo()
86                         << " and cell " << cellI << " on some other domain."
87                     << endl
88                     << "This might happen if the probe location is on"
89                     << " a processor patch. Change the location slightly"
90                     << " to prevent this." << endl;
91             }
92         }
93     }
97 Foam::label Foam::probes::prepare()
99     const label nFields = classifyFields();
101     // adjust file streams
102     if (Pstream::master())
103     {
104         wordHashSet currentFields;
106         currentFields.insert(scalarFields_);
107         currentFields.insert(vectorFields_);
108         currentFields.insert(sphericalTensorFields_);
109         currentFields.insert(symmTensorFields_);
110         currentFields.insert(tensorFields_);
112         if (debug)
113         {
114             Info<< "Probing fields:" << currentFields << nl
115                 << "Probing locations:" << *this << nl
116                 << endl;
117         }
120         fileName probeDir;
121         fileName probeSubDir = name_;
123         if (mesh_.name() != polyMesh::defaultRegion)
124         {
125             probeSubDir = probeSubDir/mesh_.name();
126         }
127         probeSubDir = probeSubDir/mesh_.time().timeName();
129         if (Pstream::parRun())
130         {
131             // Put in undecomposed case
132             // (Note: gives problems for distributed data running)
133             probeDir = mesh_.time().path()/".."/probeSubDir;
134         }
135         else
136         {
137             probeDir = mesh_.time().path()/probeSubDir;
138         }
140         // ignore known fields, close streams for fields that no longer exist
141         forAllIter(HashPtrTable<OFstream>, probeFilePtrs_, iter)
142         {
143             if (!currentFields.erase(iter.key()))
144             {
145                 if (debug)
146                 {
147                     Info<< "close probe stream: " << iter()->name() << endl;
148                 }
150                 delete probeFilePtrs_.remove(iter);
151             }
152         }
154         // currentFields now just has the new fields - open streams for them
155         forAllConstIter(wordHashSet, currentFields, iter)
156         {
157             const word& fieldName = iter.key();
159             // Create directory if does not exist.
160             mkDir(probeDir);
162             OFstream* sPtr = new OFstream(probeDir/fieldName);
164             if (debug)
165             {
166                 Info<< "open probe stream: " << sPtr->name() << endl;
167             }
169             probeFilePtrs_.insert(fieldName, sPtr);
171             unsigned int w = IOstream::defaultPrecision() + 7;
173             for (direction cmpt=0; cmpt<vector::nComponents; cmpt++)
174             {
175                 *sPtr<< '#' << setw(IOstream::defaultPrecision() + 6)
176                     << vector::componentNames[cmpt];
178                 forAll(*this, probeI)
179                 {
180                     *sPtr<< ' ' << setw(w) << operator[](probeI)[cmpt];
181                 }
182                 *sPtr << endl;
183             }
185             *sPtr<< '#' << setw(IOstream::defaultPrecision() + 6)
186                 << "Time" << endl;
187         }
188     }
190     return nFields;
194 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
196 Foam::probes::probes
198     const word& name,
199     const objectRegistry& obr,
200     const dictionary& dict,
201     const bool loadFromFiles
204     pointField(0),
205     name_(name),
206     mesh_(refCast<const fvMesh>(obr)),
207     loadFromFiles_(loadFromFiles)
209     read(dict);
213 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
215 Foam::probes::~probes()
219 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
221 void Foam::probes::execute()
223     // Do nothing - only valid on write
227 void Foam::probes::end()
229     // Do nothing - only valid on write
233 void Foam::probes::write()
235     if (size() && prepare())
236     {
237         sampleAndWrite(scalarFields_);
238         sampleAndWrite(vectorFields_);
239         sampleAndWrite(sphericalTensorFields_);
240         sampleAndWrite(symmTensorFields_);
241         sampleAndWrite(tensorFields_);
242     }
246 void Foam::probes::read(const dictionary& dict)
248     dict.lookup("probeLocations") >> *this;
249     dict.lookup("fields") >> fieldSelection_;
251     // redetermined all cell locations
252     findElements(mesh_);
253     prepare();
257 // ************************************************************************* //