FreeFOAM The Cross-Platform CFD Toolkit
PatchPostProcessing.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "PatchPostProcessing.H"
27 #include <OpenFOAM/Pstream.H>
28 #include <OpenFOAM/ListListOps.H>
29 
30 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
31 
32 template <class CloudType>
34 (
35  const label globalPatchI
36 ) const
37 {
38  forAll(patchIds_, patchI)
39  {
40  if (patchIds_[patchI] == globalPatchI)
41  {
42  return patchI;
43  }
44  }
45 
46  return -1;
47 }
48 
49 
50 // * * * * * * * * * * * * * protected Member Functions * * * * * * * * * * //
51 
52 template<class CloudType>
54 {
55  forAll(patchData_, patchI)
56  {
57  List<List<string> > procData(Pstream::nProcs());
58  procData[Pstream::myProcNo()] = patchData_[patchI];
59 
60  Pstream::gatherList(procData);
61 
62  if (Pstream::master())
63  {
64  fileName outputDir;
65 
66  if (Pstream::parRun())
67  {
68  // Put in undecomposed case (Note: gives problems for
69  // distributed data running)
70  outputDir =
71  mesh_.time().path()/".."/"postProcessing"/cloud::prefix/
72  this->owner().name()/this->owner().time().timeName();
73  }
74  else
75  {
76  outputDir =
77  mesh_.time().path()/"postProcessing"/cloud::prefix/
78  this->owner().name()/this->owner().time().timeName();
79  }
80 
81  // Create directory if it doesn't exist
82  mkDir(outputDir);
83 
84  OFstream patchOutFile
85  (
86  outputDir/patchNames_[patchI] + ".post",
87  IOstream::ASCII,
88  IOstream::currentVersion,
89  mesh_.time().writeCompression()
90  );
91 
92  List<string> globalData;
93  globalData = ListListOps::combine<List<string> >
94  (
95  procData,
97  );
98  sort(globalData);
99 
100  patchOutFile<< "# Time " + parcelType::propHeader << nl;
101 
102  forAll(globalData, i)
103  {
104  patchOutFile<< globalData[i].c_str() << nl;
105  }
106  }
107 
108  patchData_[patchI].clearStorage();
109  }
110 }
111 
112 
113 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
114 
115 template<class CloudType>
117 (
118  const dictionary& dict,
119  CloudType& owner
120 )
121 :
122  PostProcessingModel<CloudType>(dict, owner, typeName),
123  mesh_(owner.mesh()),
124  maxStoredParcels_(readLabel(this->coeffDict().lookup("maxStoredParcels"))),
125  patchNames_(this->coeffDict().lookup("patches")),
126  patchData_(patchNames_.size()),
127  patchIds_(patchNames_.size())
128 {
129  forAll(patchNames_, patchI)
130  {
131  label id = mesh_.boundaryMesh().findPatchID(patchNames_[patchI]);
132  if (id < 0)
133  {
135  (
136  "PatchPostProcessing<CloudType>::PatchPostProcessing"
137  "("
138  "const dictionary&, "
139  "CloudType& owner"
140  ")"
141  )<< "Requested patch " << patchNames_[patchI] << " not found" << nl
142  << "Available patches are: " << mesh_.boundaryMesh().names() << nl
143  << exit(FatalError);
144  }
145  patchIds_[patchI] = id;
146  }
147 }
148 
149 
150 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
151 
152 template<class CloudType>
154 {}
155 
156 
157 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
158 
159 template<class CloudType>
161 {
162  return true;
163 }
164 
165 
166 template<class CloudType>
168 (
169  const parcelType& p,
170  const label patchI
171 )
172 {
173  label localPatchI = applyToPatch(patchI);
174  if (localPatchI >= 0 && patchData_[localPatchI].size() < maxStoredParcels_)
175  {
176  OStringStream data;
177  data<< this->owner().time().timeName() << ' ' << p;
178  patchData_[localPatchI].append(data.str());
179  }
180 }
181 
182 
183 // ************************ vim: set sw=4 sts=4 et: ************************ //