ENH: autoLayerDriver: better layering information message
[OpenFOAM-2.0.x.git] / src / OpenFOAM / db / Time / timeSelector.C
blob07bc6be37d820ca7bcc5e61958c74e77da02a007
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
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.
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.
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/>.
24 \*---------------------------------------------------------------------------*/
26 #include "timeSelector.H"
27 #include "ListOps.H"
28 #include "argList.H"
29 #include "Time.H"
30 #include "IStringStream.H"
32 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
34 Foam::timeSelector::timeSelector()
36     scalarRanges()
40 Foam::timeSelector::timeSelector(Istream& is)
42     scalarRanges(is)
46 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
48 bool Foam::timeSelector::selected(const instant& value) const
50     return scalarRanges::selected(value.value());
54 Foam::List<bool> Foam::timeSelector::selected(const List<instant>& Times) const
56     List<bool> lst(Times.size(), false);
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     }
67     // check specific values
68     forAll(*this, rangeI)
69     {
70         if (operator[](rangeI).isExact())
71         {
72             scalar target = operator[](rangeI).value();
74             int nearestIndex = -1;
75             scalar nearestDiff = Foam::GREAT;
77             forAll(Times, timeI)
78             {
79                 if (Times[timeI].name() == "constant") continue;
81                 scalar diff = fabs(Times[timeI].value() - target);
82                 if (diff < nearestDiff)
83                 {
84                     nearestDiff = diff;
85                     nearestIndex = timeI;
86                 }
87             }
89             if (nearestIndex >= 0)
90             {
91                 lst[nearestIndex] = true;
92             }
93         }
94     }
96     return lst;
100 Foam::List<Foam::instant> Foam::timeSelector::select
102     const List<instant>& Times
103 ) const
105     return subset(selected(Times), Times);
109 void Foam::timeSelector::inplaceSelect
111     List<instant>& Times
112 ) const
114     inplaceSubset(selected(Times), Times);
118 void Foam::timeSelector::addOptions
120     const bool constant,
121     const bool zeroTime
124     if (constant)
125     {
126         argList::addBoolOption
127         (
128             "constant",
129             "include the 'constant/' dir in the times list"
130         );
131     }
132     if (zeroTime)
133     {
134         argList::addBoolOption
135         (
136             "zeroTime",
137             "include the '0/' dir in the times list"
138         );
139     }
140     argList::addBoolOption
141     (
142         "noZero",
143         "exclude the '0/' dir from the times list, "
144         "has precedence over the -zeroTime option"
145     );
146     argList::addBoolOption
147     (
148         "latestTime",
149         "select the latest time"
150     );
151     argList::addOption
152     (
153         "time",
154         "ranges",
155         "comma-separated time ranges - eg, ':10,20,40-70,1000:'"
156     );
160 Foam::List<Foam::instant> Foam::timeSelector::select
162     const List<instant>& timeDirs,
163     const argList& args
166     if (timeDirs.size())
167     {
168         List<bool> selectTimes(timeDirs.size(), true);
170         // determine locations of constant/ and 0/ directories
171         label constantIdx = -1;
172         label zeroIdx = -1;
174         forAll(timeDirs, timeI)
175         {
176             if (timeDirs[timeI].name() == "constant")
177             {
178                 constantIdx = timeI;
179             }
180             else if (timeDirs[timeI].value() == 0)
181             {
182                 zeroIdx = timeI;
183             }
185             if (constantIdx >= 0 && zeroIdx >= 0)
186             {
187                 break;
188             }
189         }
191         // determine latestTime selection (if any)
192         // this must appear before the -time option processing
193         label latestIdx = -1;
194         if (args.optionFound("latestTime"))
195         {
196             selectTimes = false;
197             latestIdx = timeDirs.size() - 1;
199             // avoid false match on constant/
200             if (latestIdx == constantIdx)
201             {
202                 latestIdx = -1;
203             }
204         }
206         if (args.optionFound("time"))
207         {
208             // can match 0/, but can never match constant/
209             selectTimes = timeSelector
210             (
211                 args.optionLookup("time")()
212             ).selected(timeDirs);
213         }
216         // add in latestTime (if selected)
217         if (latestIdx >= 0)
218         {
219             selectTimes[latestIdx] = true;
220         }
222         if (constantIdx >= 0)
223         {
224             // only add constant/ if specifically requested
225             selectTimes[constantIdx] = args.optionFound("constant");
226         }
228         // special treatment for 0/
229         if (zeroIdx >= 0)
230         {
231             if (args.optionFound("noZero"))
232             {
233                 // exclude 0/ if specifically requested
234                 selectTimes[zeroIdx] = false;
235             }
236             else if (argList::validOptions.found("zeroTime"))
237             {
238                 // with -zeroTime enabled, drop 0/ unless specifically requested
239                 selectTimes[zeroIdx] = args.optionFound("zeroTime");
240             }
241         }
243         return subset(selectTimes, timeDirs);
244     }
245     else
246     {
247         return timeDirs;
248     }
252 Foam::List<Foam::instant> Foam::timeSelector::select0
254     Time& runTime,
255     const argList& args
258     instantList timeDirs = timeSelector::select(runTime.times(), args);
260     if (timeDirs.empty())
261     {
262         FatalErrorIn(args.executable())
263             << "No times selected"
264             << exit(FatalError);
265     }
267     runTime.setTime(timeDirs[0], 0);
269     return timeDirs;
273 // ************************************************************************* //