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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2019 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "PatchPostProcessing.H"
30 #include "Pstream.H"
31 #include "stringListOps.H"
32 #include "ListOps.H"
33 #include "ListListOps.H"
34 
35 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
36 
37 template<class CloudType>
39 (
40  const label globalPatchi
41 ) const
42 {
43  return patchIDs_.find(globalPatchi);
44 }
45 
46 
47 // * * * * * * * * * * * * * protected Member Functions * * * * * * * * * * //
48 
49 template<class CloudType>
51 {
52  forAll(patchData_, i)
53  {
54  List<List<scalar>> procTimes(Pstream::nProcs());
55  procTimes[Pstream::myProcNo()] = times_[i];
56  Pstream::gatherList(procTimes);
57 
58  List<List<string>> procData(Pstream::nProcs());
59  procData[Pstream::myProcNo()] = patchData_[i];
60  Pstream::gatherList(procData);
61 
62  if (Pstream::master())
63  {
64  const fvMesh& mesh = this->owner().mesh();
65 
66  // Create directory if it doesn't exist
67  mkDir(this->writeTimeDir());
68 
69  const word& patchName = mesh.boundaryMesh()[patchIDs_[i]].name();
70 
71  OFstream patchOutFile
72  (
73  this->writeTimeDir()/patchName + ".post",
74  IOstreamOption::ASCII,
75  mesh.time().writeCompression()
76  );
77 
78  List<string> globalData;
79  globalData = ListListOps::combine<List<string>>
80  (
81  procData,
83  );
84 
85  List<scalar> globalTimes;
86  globalTimes = ListListOps::combine<List<scalar>>
87  (
88  procTimes,
90  );
91 
92  labelList indices(sortedOrder(globalTimes));
93 
94  string header("# Time currentProc " + header_);
95  patchOutFile<< header.c_str() << nl;
96 
97  forAll(globalTimes, i)
98  {
99  label dataI = indices[i];
100 
101  patchOutFile
102  << globalTimes[dataI] << ' '
103  << globalData[dataI].c_str()
104  << nl;
105  }
106  }
107 
108  patchData_[i].clearStorage();
109  times_[i].clearStorage();
110  }
111 }
112 
113 
114 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
115 
116 template<class CloudType>
118 (
119  const dictionary& dict,
120  CloudType& owner,
121  const word& modelName
122 )
123 :
124  CloudFunctionObject<CloudType>(dict, owner, modelName, typeName),
125  maxStoredParcels_(this->coeffDict().getScalar("maxStoredParcels")),
126  fields_(),
127  patchIDs_(),
128  times_(),
129  patchData_(),
130  header_()
131 {
132  // The "fields" filter is optional
133  this->coeffDict().readIfPresent("fields", fields_);
134 
135  // The "patches" are required
136  const wordRes patchMatcher(this->coeffDict().lookup("patches"));
137 
138  patchIDs_ = patchMatcher.matching(owner.mesh().boundaryMesh().names());
139 
140  if (patchIDs_.empty())
141  {
143  << "No matching patches found: "
144  << flatOutput(patchMatcher) << nl;
145  }
146 
147  if (debug)
148  {
149  Info<< "Post-process fields "
150  << flatOutput(fields_) << nl;
151 
152  Info<< "On patches (";
153 
154  for (const label patchi : patchIDs_)
155  {
156  Info<< ' ' << owner.mesh().boundaryMesh()[patchi].name();
157  }
158 
159  Info<< " )" << nl;
160  }
161 
162  patchData_.setSize(patchIDs_.size());
163  times_.setSize(patchIDs_.size());
164 }
165 
166 
167 template<class CloudType>
169 (
171 )
172 :
174  maxStoredParcels_(ppm.maxStoredParcels_),
175  fields_(ppm.fields_),
176  patchIDs_(ppm.patchIDs_),
177  times_(ppm.times_),
178  patchData_(ppm.patchData_),
179  header_(ppm.header_)
180 {}
181 
182 
183 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
184 
185 template<class CloudType>
187 (
188  const parcelType& p,
189  const polyPatch& pp,
190  bool&
191 )
192 {
193  const label patchi = pp.index();
194  const label localPatchi = applyToPatch(patchi);
195 
196  if (header_.empty())
197  {
199  p.writeProperties(data, fields_, " ", true);
200  header_ = data.str();
201  }
202 
203  if (localPatchi != -1 && patchData_[localPatchi].size() < maxStoredParcels_)
204  {
205  times_[localPatchi].append(this->owner().time().value());
206 
207  OStringStream data;
208  data<< Pstream::myProcNo();
209  p.writeProperties(data, fields_, " ", false);
210 
211  patchData_[localPatchi].append(data.str());
212  }
213 }
214 
215 
216 // ************************************************************************* //
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:584
dictionary dict
void write()
Write post-processing info.
labelList matching(const UList< StringType > &input, const bool invert=false) const
Return list indices for all matches.
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:120
void append(const T &val)
Append an element at the end of the list.
Definition: List.H:491
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:150
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:56
Output to file stream, using an OSstream.
Definition: OFstream.H:49
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
bool empty() const noexcept
True if the UList is empty (ie, size() is zero)
Definition: UListI.H:420
Object access operator or list access operator.
Definition: UList.H:945
Operations on lists of strings.
static int myProcNo(const label communicator=worldComm)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:688
Lookup type of boundary radiation properties.
Definition: lookup.H:57
Various functions to operate on Lists.
const CloudType & owner() const
Return const access to the owner cloud.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:413
dynamicFvMesh & mesh
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition: POSIX.C:567
A class for handling words, derived from Foam::string.
Definition: word.H:63
wordList names() const
Return a list of patch names.
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:47
virtual void postPatch(const parcelType &p, const polyPatch &pp, bool &keepParticle)
Post-patch hook.
const dictionary & coeffDict() const
Return const access to the coefficients dictionary.
Definition: subModelBase.C:122
int debug
Static debugging option.
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry if present, and assign to T val. FatalIOError if it is found and the number of tokens i...
Database for solution data, solver performance and other reduced data.
Definition: data.H:51
const fvMesh & mesh() const
Return reference to the mesh.
Definition: DSMCCloudI.H:37
#define WarningInFunction
Report a warning using Foam::Warning.
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:79
messageStream Info
Information stream (stdout output on master, null elsewhere)
Standard post-processing.
label index() const noexcept
The index of this patch in the boundaryMesh.
volScalarField & p
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:69
Templated base class for dsmc cloud.
Definition: DSMCCloud.H:67
Output to string buffer, using a OSstream. Always UNCOMPRESSED.
Definition: StringStream.H:256
Templated cloud function object base class.
PatchPostProcessing(const dictionary &dict, CloudType &owner, const word &modelName)
Construct from dictionary.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:225