FreeFOAM The Cross-Platform CFD Toolkit
timeSelector.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) 1991-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 "timeSelector.H"
27 #include <OpenFOAM/ListOps.H>
28 #include <OpenFOAM/argList.H>
29 #include "Time.H"
30 #include <OpenFOAM/IStringStream.H>
31 
32 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
33 
35 :
36  scalarRanges()
37 {}
38 
39 
41 :
42  scalarRanges(is)
43 {}
44 
45 
46 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
47 
48 bool Foam::timeSelector::selected(const instant& value) const
49 {
50  return scalarRanges::selected(value.value());
51 }
52 
53 
55 {
56  List<bool> lst(Times.size(), false);
57 
58  // check ranges, avoid false positive on constant/
59  forAll(Times, timeI)
60  {
61  if (Times[timeI].name() != "constant" && selected(Times[timeI]))
62  {
63  lst[timeI] = true;
64  }
65  }
66 
67  // check specific values
68  forAll(*this, rangeI)
69  {
70  if (operator[](rangeI).isExact())
71  {
72  scalar target = operator[](rangeI).value();
73 
74  int nearestIndex = -1;
75  scalar nearestDiff = Foam::GREAT;
76 
77  forAll(Times, timeI)
78  {
79  if (Times[timeI].name() == "constant") continue;
80 
81  scalar diff = fabs(Times[timeI].value() - target);
82  if (diff < nearestDiff)
83  {
84  nearestDiff = diff;
85  nearestIndex = timeI;
86  }
87  }
88 
89  if (nearestIndex >= 0)
90  {
91  lst[nearestIndex] = true;
92  }
93  }
94  }
95 
96  return lst;
97 }
98 
99 
101 (
102  const List<instant>& Times
103 ) const
104 {
105  return subset(selected(Times), Times);
106 }
107 
108 
110 (
111  List<instant>& Times
112 ) const
113 {
114  inplaceSubset(selected(Times), Times);
115 }
116 
117 
119 (
120  const bool constant,
121  const bool zeroTime
122 )
123 {
124  if (constant)
125  {
126  argList::validOptions.insert("constant", "");
127  }
128  if (zeroTime)
129  {
130  argList::validOptions.insert("zeroTime", "");
131  }
132  argList::validOptions.insert("noZero", "");
133  argList::validOptions.insert("time", "ranges");
134  argList::validOptions.insert("latestTime", "");
135 }
136 
137 
139 (
140  const List<instant>& timeDirs,
141  const argList& args
142 )
143 {
144  if (timeDirs.size())
145  {
146  List<bool> selectTimes(timeDirs.size(), true);
147 
148  // determine locations of constant/ and 0/ directories
149  label constantIdx = -1;
150  label zeroIdx = -1;
151 
152  forAll(timeDirs, timeI)
153  {
154  if (timeDirs[timeI].name() == "constant")
155  {
156  constantIdx = timeI;
157  }
158  else if (timeDirs[timeI].value() == 0)
159  {
160  zeroIdx = timeI;
161  }
162 
163  if (constantIdx >= 0 && zeroIdx >= 0)
164  {
165  break;
166  }
167  }
168 
169  // determine latestTime selection (if any)
170  // this must appear before the -time option processing
171  label latestIdx = -1;
172  if (args.optionFound("latestTime"))
173  {
174  selectTimes = false;
175  latestIdx = timeDirs.size() - 1;
176 
177  // avoid false match on constant/
178  if (latestIdx == constantIdx)
179  {
180  latestIdx = -1;
181  }
182  }
183 
184  if (args.optionFound("time"))
185  {
186  // can match 0/, but can never match constant/
187  selectTimes = timeSelector
188  (
189  args.optionLookup("time")()
190  ).selected(timeDirs);
191  }
192 
193 
194  // add in latestTime (if selected)
195  if (latestIdx >= 0)
196  {
197  selectTimes[latestIdx] = true;
198  }
199 
200  if (constantIdx >= 0)
201  {
202  // only add constant/ if specifically requested
203  selectTimes[constantIdx] = args.optionFound("constant");
204  }
205 
206  // special treatment for 0/
207  if (zeroIdx >= 0)
208  {
209  if (args.optionFound("noZero"))
210  {
211  // exclude 0/ if specifically requested
212  selectTimes[zeroIdx] = false;
213  }
214  else if (argList::validOptions.found("zeroTime"))
215  {
216  // with -zeroTime enabled, drop 0/ unless specifically requested
217  selectTimes[zeroIdx] = args.optionFound("zeroTime");
218  }
219  }
220 
221  return subset(selectTimes, timeDirs);
222  }
223  else
224  {
225  return timeDirs;
226  }
227 }
228 
229 
231 (
232  Time& runTime,
233  const argList& args
234 )
235 {
236  instantList timeDirs = timeSelector::select(runTime.times(), args);
237 
238  if (timeDirs.empty())
239  {
240  FatalErrorIn(args.executable())
241  << "No times selected"
242  << exit(FatalError);
243  }
244 
245  runTime.setTime(timeDirs[0], 0);
246 
247  return timeDirs;
248 }
249 
250 
251 // ************************ vim: set sw=4 sts=4 et: ************************ //