problems_buffer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * *
3  * Copyright (C) 2007-2012 by Johan De Taeye, frePPLe bvba *
4  * *
5  * This library is free software; you can redistribute it and/or modify it *
6  * under the terms of the GNU Affero General Public License as published *
7  * by the Free Software Foundation; either version 3 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This library is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU Affero General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU Affero General Public *
16  * License along with this program. *
17  * If not, see <http://www.gnu.org/licenses/>. *
18  * *
19  ***************************************************************************/
20 
21 #define FREPPLE_CORE
22 #include "frepple/model.h"
23 
24 namespace frepple
25 {
26 
27 
29 {
30  // Delete existing problems for this buffer
32 
33  // Problem detection disabled on this buffer
34  if (!getDetectProblems()) return;
35 
36  // Loop through the flowplans
37  Date excessProblemStart;
38  Date shortageProblemStart;
39  bool shortageProblem = false;
40  bool excessProblem = false;
41  double curMax(0.0);
42  double shortageQty(0.0);
43  double curMin(0.0);
44  double excessQty(0.0);
45  for (flowplanlist::const_iterator iter = flowplans.begin();
46  iter != flowplans.end(); )
47  {
48  // Process changes in the maximum or minimum targets
49  if (iter->getType() == 4)
50  curMax = iter->getMax();
51  else if (iter->getType() == 3)
52  curMin = iter->getMin();
53 
54  // Only consider the last flowplan for a certain date
55  const TimeLine<FlowPlan>::Event *f = &*(iter++);
56  if (iter!=flowplans.end() && iter->getDate()==f->getDate()) continue;
57 
58  // Check against minimum target
59  double delta = f->getOnhand() - curMin;
60  if (delta < -ROUNDING_ERROR)
61  {
62  if (!shortageProblem)
63  {
64  // Start of a problem
65  shortageProblemStart = f->getDate();
66  shortageQty = delta;
67  shortageProblem = true;
68  }
69  else if (delta < shortageQty)
70  // New shortage qty
71  shortageQty = delta;
72  }
73  else
74  {
75  if (shortageProblem)
76  {
77  // New problem now ends
78  if (f->getDate() != shortageProblemStart)
80  (this, shortageProblemStart, f->getDate(), -shortageQty);
81  shortageProblem = false;
82  }
83  }
84 
85  // Note that theoretically we can have a minimum and a maximum problem for
86  // the same moment in time.
87 
88  // Check against maximum target
89  delta = f->getOnhand() - curMax;
90  if (delta > ROUNDING_ERROR)
91  {
92  if (!excessProblem)
93  {
94  // New problem starts here
95  excessProblemStart = f->getDate();
96  excessQty = delta;
97  excessProblem = true;
98  }
99  else if (delta > excessQty)
100  excessQty = delta;
101  }
102  else
103  {
104  if (excessProblem)
105  {
106  // New excess qty
107  // New problem now ends
108  if (f->getDate() != excessProblemStart)
110  (this, excessProblemStart, f->getDate(), excessQty);
111  excessProblem = false;
112  }
113  }
114 
115  } // End of for-loop through the flowplans
116 
117  // The excess lasts till the end of the horizon...
118  if (excessProblem)
120  (this, excessProblemStart, Date::infiniteFuture, excessQty);
121 
122  // The shortage lasts till the end of the horizon...
123  if (shortageProblem)
125  (this, shortageProblemStart, Date::infiniteFuture, -shortageQty);
126 }
127 
128 
129 
131 {
132  ostringstream ch;
133  ch << "Buffer '" << getBuffer() << "' has material excess of " << qty;
134  return ch.str();
135 }
136 
137 
139 {
140  ostringstream ch;
141  ch << "Buffer '" << getBuffer() << "' has material shortage of " << qty;
142  return ch.str();
143 }
144 
145 
146 }