ensightWriterCaching.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) 2016-2022 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "ensightWriterCaching.H"
29 #include "ListOps.H"
30 #include "Fstream.H"
31 
32 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36 
37 // Compare time values with tolerance
38 static const equalOp<scalar> equalTimes(ROOTSMALL);
39 
40 // Use ListOps findLower (with tolerance), to find the location of the next
41 // time-related index.
42 // The returned index is always 0 or larger (no negative values).
43 static label findTimeIndex(const UList<scalar>& list, const scalar val)
44 {
45  label idx =
46  findLower
47  (
48  list,
49  val,
50  0,
51  [](const scalar a, const scalar b)
52  {
53  return (a < b) && (Foam::mag(b - a) > ROOTSMALL);
54  }
55  );
56 
57  if (idx < 0 || !equalTimes(list[idx], val))
58  {
59  ++idx;
60  }
61 
62  return idx;
63 }
64 
65 } // End namespace Foam
66 
67 
68 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
69 
71 :
72  dictName_(cacheFileName)
73 {}
74 
75 
76 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
77 
79 {
80  const dictionary* dictptr = cache_.findDict("fields", keyType::LITERAL);
81 
82  if (!dictptr)
83  {
84  dictptr = &dictionary::null;
85  }
86 
87  return *dictptr;
88 }
89 
90 
91 Foam::dictionary& Foam::ensightOutput::writerCaching::fieldDict
92 (
93  const word& fieldName
94 )
95 {
96  return
97  cache_
98  .subDictOrAdd("fields", keyType::LITERAL)
99  .subDictOrAdd(fieldName, keyType::LITERAL);
100 }
101 
102 
103 bool Foam::ensightOutput::writerCaching::remove(const word& fieldName)
104 {
105  dictionary* dictptr = cache_.findDict("fields", keyType::LITERAL);
106 
107  if (dictptr)
108  {
109  return dictptr->remove(fieldName);
110  }
111 
112  return false;
113 }
114 
115 
117 {
118  times_.clear();
119  geoms_.clear();
120  cache_.clear();
121 }
122 
123 
124 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
125 
126 Foam::label Foam::ensightOutput::writerCaching::readPreviousTimes
127 (
128  const fileName& dictFile,
129  const scalar timeValue
130 )
131 {
132  // In 1906 and earlier, the fieldsDict contained "meshes" and "times"
133  // entries, each with their own time values.
134  // This makes it more difficult to define the exact correspondence
135  // between geometry intervals and times.
136  //
137  // Now track the used geometry intervals as a bitSet.
138 
139 
140  // Only called from master
141  label timeIndex = 0;
142  cache_.clear();
143 
144  IFstream is(dictFile);
145 
146  if (is.good() && cache_.read(is))
147  {
148  geoms_.clear();
149 
150  cache_.readIfPresent("times", times_);
151  timeIndex = findTimeIndex(times_, timeValue);
152 
153  labelList geomIndices;
154  scalarList meshTimes;
155 
156  if (cache_.readIfPresent("geometry", geomIndices))
157  {
158  // Convert indices to bitSet entries
159  geoms_.set(geomIndices);
160  }
161  else if (cache_.readIfPresent("meshes", meshTimes))
162  {
164  << nl
165  << "Setting geometry timeset information from time values"
166  << " (cache from an older OpenFOAM version)." << nl
167  << "This may not be fully reliable." << nl
168  << nl;
169 
170  for (const scalar meshTime : meshTimes)
171  {
172  const label geomIndex = findTimeIndex(times_, meshTime);
173  geoms_.set(geomIndex);
174  }
175  }
176 
177  // Make length consistent with time information.
178  // We read/write the indices instead of simply dumping the bitSet.
179  // This makes the contents more human readable.
180  geoms_.resize(times_.size());
181  }
182 
183  return timeIndex;
184 }
186 
188 {
189  return max(0, times_.size()-1);
190 }
191 
193 {
194  return max(0, geoms_.find_last());
195 }
196 
197 
198 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
199 
201 {
202  if (geoms_.count() <= 1)
203  {
204  // Static
205  return 0;
206  }
207  if (geoms_.size() == times_.size() && geoms_.all())
208  {
209  // Geometry changing is identical to fields changing
210  return 1;
211  }
212 
213  // Geometry changing differently from fields
214  return 2;
215 }
216 
217 
218 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
219 
221 (
222  const fileName& baseDir,
223  const scalar timeValue,
224  const bool geomChanged,
225  const word& fieldName,
226  const word& fieldType,
227  const word& varName
228 )
229 {
230  const fileName dictFile(baseDir/dictName_);
231 
232  bool stateChanged = false;
233 
234  const label timeIndex =
235  (
236  times_.empty()
237  ? readPreviousTimes(dictFile, timeValue)
238  : findTimeIndex(times_, timeValue)
239  );
240 
241 
242  // Update stored times list and geometry index
243 
244  if (timeIndex < geoms_.size()-1)
245  {
246  // Clear old content when shrinking
247  geoms_.unset(timeIndex);
248  }
249 
250  // Extend or truncate list
251  geoms_.resize(timeIndex+1);
252  times_.resize(timeIndex+1, VGREAT);
253 
254  if (!equalTimes(times_[timeIndex], timeValue))
255  {
256  stateChanged = true;
257  times_[timeIndex] = timeValue;
258  }
259 
260  if (geomChanged)
261  {
262  stateChanged = true;
263  geoms_.set(timeIndex);
264  }
265 
266 
267  // Update time/geometry information in dictionary
268  cache_.set("times", times_);
269  cache_.set("geometry", geoms_.sortedToc());
270 
271  // Debugging, or if needed for older versions:
277 
278  // Add field information to dictionary
279  dictionary& dict = fieldDict(fieldName);
280 
281  if (dict.empty())
282  {
283  stateChanged = true;
284 
285  dict.set("type", fieldType);
286  if (!varName.empty() && varName != fieldName)
287  {
288  // Use variable name, if it differs from fieldName
289  dict.set("name", varName);
290  }
291  }
292 
293  if (stateChanged)
294  {
295  OFstream os(dictFile);
296  os << "// State file for writer output" << nl << nl;
297  cache_.write(os, false);
298 
299  os << nl << "// End" << nl;
300  }
301 
302  return stateChanged;
303 }
304 
305 
306 // ************************************************************************* //
dictionary dict
label findLower(const ListType &input, const T &val, const label start, const ComparePredicate &comp)
Binary search to find the index of the last element in a sorted list that is less than value...
bool update(const fileName &baseDir, const scalar timeValue, const bool geomChanged, const word &fieldName, const word &fieldType, const word &varName=word::null)
Update time/geometry information and file cache. This routine should only be called from the master p...
A class for handling file names.
Definition: fileName.H:71
static const equalOp< scalar > equalTimes(ROOTSMALL)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:120
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
Definition: List.H:463
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
const dictionary & fieldsDict() const
Get or create the &#39;fields&#39; information dictionary.
dictionary & subDictOrAdd(const word &keyword, enum keyType::option matchOpt=keyType::REGEX)
Find and return a sub-dictionary for manipulation.
Definition: dictionary.C:493
Various functions to operate on Lists.
bool remove(const word &keyword)
Remove an entry specified by keyword.
static label findTimeIndex(const UList< scalar > &list, const scalar val)
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
A class for handling words, derived from Foam::string.
Definition: word.H:63
List< scalar > scalarList
A List of scalars.
Definition: scalarList.H:61
static const dictionary null
An empty dictionary, which is also the parent for all dictionaries.
Definition: dictionary.H:465
String literal.
Definition: keyType.H:82
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:99
OBJstream os(runTime.globalPath()/outputName)
int geometryTimeset() const
Expected timeset for the geometry.
#define WarningInFunction
Report a warning using Foam::Warning.
label latestGeomIndex() const
The most current geometry index.
List< label > labelList
A List of labels.
Definition: List.H:62
writerCaching(const word &cacheFileName)
Construct with specified cache name.
label latestTimeIndex() const
The most current time index.
Namespace for OpenFOAM.
label timeIndex
Definition: getTimeIndex.H:24
const dictionary * findDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary pointer if present (and a sub-dictionary) otherwise return nullptr...
Definition: dictionaryI.H:120