Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / sampling / probes / probes.C
blob7216c09f82e63611be374855b250ffa028466071
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | foam-extend: Open Source CFD
4    \\    /   O peration     | Version:     3.2
5     \\  /    A nd           | Web:         http://www.foam-extend.org
6      \\/     M anipulation  | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
8 License
9     This file is part of foam-extend.
11     foam-extend is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by the
13     Free Software Foundation, either version 3 of the License, or (at your
14     option) any later version.
16     foam-extend is distributed in the hope that it will be useful, but
17     WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19     General Public License for more details.
21     You should have received a copy of the GNU General Public License
22     along with foam-extend.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "probes.H"
27 #include "volFields.H"
28 #include "dictionary.H"
29 #include "foamTime.H"
30 #include "IOmanip.H"
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 namespace Foam
36     defineTypeNameAndDebug(probes, 0);
39 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
41 void Foam::probes::findCells(const fvMesh& mesh)
43     if (cellList_.empty())
44     {
45         Info<< "Searching for probe point locations" << endl;
47         cellList_.setSize(probeLocations_.size());
49         forAll(probeLocations_, probeI)
50         {
51             cellList_[probeI] = mesh.findCell(probeLocations_[probeI]);
53             if (debug && cellList_[probeI] != -1)
54             {
55                 Pout<< "probes : found point " << probeLocations_[probeI]
56                     << " in cell " << cellList_[probeI] << endl;
57             }
58         }
61         // Check if all probes have been found.
62         forAll(cellList_, probeI)
63         {
64             label cellI = cellList_[probeI];
66             // Check at least one processor with cell.
67             reduce(cellI, maxOp<label>());
69             if (cellI == -1)
70             {
71                 if (Pstream::master())
72                 {
73                     WarningIn("probes::read()")
74                         << "Did not find location " << probeLocations_[probeI]
75                         << " in any cell. Skipping location." << endl;
76                 }
77             }
78             else
79             {
80                 // Make sure location not on two domains.
81                 if (cellList_[probeI] != -1 && cellList_[probeI] != cellI)
82                 {
83                     WarningIn("probes::read()")
84                         << "Location " << probeLocations_[probeI]
85                         << " seems to be on multiple domains:"
86                         << " cell " << cellList_[probeI]
87                         << " on my domain " << Pstream::myProcNo()
88                         << " and cell " << cellI << " on some other domain."
89                         << endl
90                         << "This might happen if the probe location is on"
91                         << " a processor patch. Change the location slightly"
92                         << " to prevent this." << endl;
93                 }
94             }
95         }
96     }
100 bool Foam::probes::checkFieldTypes()
102     wordList fieldTypes(fieldNames_.size());
104     // check files for a particular time
105     if (loadFromFiles_)
106     {
107         forAll(fieldNames_, fieldI)
108         {
109             IOobject io
110             (
111                 fieldNames_[fieldI],
112                 obr_.time().timeName(),
113                 refCast<const polyMesh>(obr_),
114                 IOobject::MUST_READ,
115                 IOobject::NO_WRITE,
116                 false
117             );
119             if (io.headerOk())
120             {
121                 fieldTypes[fieldI] = io.headerClassName();
122             }
123             else
124             {
125                 fieldTypes[fieldI] = "(notFound)";
126             }
127         }
128     }
129     else
130     {
131         // check objectRegistry
132         forAll(fieldNames_, fieldI)
133         {
134             objectRegistry::const_iterator iter =
135                 obr_.find(fieldNames_[fieldI]);
137             if (iter != obr_.end())
138             {
139                 fieldTypes[fieldI] = iter()->type();
140             }
141             else
142             {
143                 fieldTypes[fieldI] = "(notFound)";
144             }
145         }
146     }
149     label nFields = 0;
151     // classify fieldTypes
152     nFields += countFields(scalarFields_, fieldTypes);
153     nFields += countFields(vectorFields_, fieldTypes);
154     nFields += countFields(sphericalTensorFields_, fieldTypes);
155     nFields += countFields(symmTensorFields_, fieldTypes);
156     nFields += countFields(tensorFields_, fieldTypes);
158     // concatenate all the lists into foundFields
159     wordList foundFields(nFields);
161     label fieldI = 0;
162     forAll(scalarFields_, i)
163     {
164         foundFields[fieldI++] = scalarFields_[i];
165     }
166     forAll(vectorFields_, i)
167     {
168         foundFields[fieldI++] = vectorFields_[i];
169     }
170     forAll(sphericalTensorFields_, i)
171     {
172         foundFields[fieldI++] = sphericalTensorFields_[i];
173     }
174     forAll(symmTensorFields_, i)
175     {
176         foundFields[fieldI++] = symmTensorFields_[i];
177     }
178     forAll(tensorFields_, i)
179     {
180         foundFields[fieldI++] = tensorFields_[i];
181     }
183     if (Pstream::master())
184     {
185         fileName probeDir;
187         fileName probeSubDir = name_;
189         if (obr_.name() != polyMesh::defaultRegion)
190         {
191             probeSubDir = probeSubDir/obr_.name();
192         }
193         probeSubDir = probeSubDir/obr_.time().timeName();
195         if (Pstream::parRun())
196         {
197             // Put in undecomposed case
198             // (Note: gives problems for distributed data running)
199             probeDir = obr_.time().path()/".."/probeSubDir;
200         }
201         else
202         {
203             probeDir = obr_.time().path()/probeSubDir;
204         }
206         // Close the file if any fields have been removed.
207         forAllIter(HashPtrTable<OFstream>, probeFilePtrs_, iter)
208         {
209             if (findIndex(foundFields, iter.key()) == -1)
210             {
211                 if (debug)
212                 {
213                     Pout<< "close stream: " << iter()->name() << endl;
214                 }
216                 delete probeFilePtrs_.remove(iter);
217             }
218         }
220         // Open new files for new fields. Keep existing files.
222         probeFilePtrs_.resize(2*foundFields.size());
224         forAll(foundFields, fieldI)
225         {
226             const word& fldName = foundFields[fieldI];
228             // Check if added field. If so open a stream for it.
230             if (!probeFilePtrs_.found(fldName))
231             {
232                 // Create directory if does not exist.
233                 mkDir(probeDir);
235                 OFstream* sPtr = new OFstream(probeDir/fldName);
237                 if (debug)
238                 {
239                     Pout<< "open  stream: " << sPtr->name() << endl;
240                 }
242                 probeFilePtrs_.insert(fldName, sPtr);
244                 unsigned int w = IOstream::defaultPrecision() + 7;
246                 for (direction cmpt=0; cmpt<vector::nComponents; cmpt++)
247                 {
248                     *sPtr<< '#' << setw(IOstream::defaultPrecision() + 6)
249                         << vector::componentNames[cmpt];
251                     forAll(probeLocations_, probeI)
252                     {
253                         *sPtr<< ' ' << setw(w) << probeLocations_[probeI][cmpt];
254                     }
255                     *sPtr << endl;
256                 }
258                 *sPtr<< '#' << setw(IOstream::defaultPrecision() + 6)
259                     << "Time" << endl;
260             }
261         }
263         if (debug)
264         {
265             Pout<< "Probing fields:" << foundFields << nl
266                 << "Probing locations:" << probeLocations_ << nl
267                 << endl;
268         }
269     }
272     return nFields > 0;
276 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
278 Foam::probes::probes
280     const word& name,
281     const objectRegistry& obr,
282     const dictionary& dict,
283     const bool loadFromFiles
286     name_(name),
287     obr_(obr),
288     loadFromFiles_(loadFromFiles),
289     fieldNames_(),
290     probeLocations_(),
291     scalarFields_(),
292     vectorFields_(),
293     sphericalTensorFields_(),
294     symmTensorFields_(),
295     tensorFields_(),
296     cellList_(),
297     probeFilePtrs_()
299     read(dict);
303 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
305 Foam::probes::~probes()
309 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
311 void Foam::probes::execute()
316 void Foam::probes::end()
318     // Do nothing - only valid on write
322 void Foam::probes::write()
324     // Check if the mesh is changing and if so, resample
325     const fvMesh& mesh = refCast<const fvMesh>(obr_);
327     if (mesh.moving() || mesh.changing())
328     {
329         cellList_.clear();
330         findCells(mesh);
331     }
333     if (probeLocations_.size() && checkFieldTypes())
334     {
335         sampleAndWrite(scalarFields_);
336         sampleAndWrite(vectorFields_);
337         sampleAndWrite(sphericalTensorFields_);
338         sampleAndWrite(symmTensorFields_);
339         sampleAndWrite(tensorFields_);
340     }
344 void Foam::probes::read(const dictionary& dict)
346     dict.lookup("fields") >> fieldNames_;
347     dict.lookup("probeLocations") >> probeLocations_;
349     // Force all cell locations to be redetermined
350     cellList_.clear();
351     findCells(refCast<const fvMesh>(obr_));
352     checkFieldTypes();
356 // ************************************************************************* //