problems_buffer.cpp
Go to the documentation of this file.
00001 /*************************************************************************** 00002 file : $URL: http://svn.code.sf.net/p/frepple/code/trunk/src/model/problems_buffer.cpp $ 00003 version : $LastChangedRevision: 1713 $ $LastChangedBy: jdetaeye $ 00004 date : $LastChangedDate: 2012-07-18 11:46:01 +0200 (Wed, 18 Jul 2012) $ 00005 ***************************************************************************/ 00006 00007 /*************************************************************************** 00008 * * 00009 * Copyright (C) 2007-2012 by Johan De Taeye, frePPLe bvba * 00010 * * 00011 * This library is free software; you can redistribute it and/or modify it * 00012 * under the terms of the GNU Affero General Public License as published * 00013 * by the Free Software Foundation; either version 3 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 * This library is distributed in the hope that it will be useful, * 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00019 * GNU Affero General Public License for more details. * 00020 * * 00021 * You should have received a copy of the GNU Affero General Public * 00022 * License along with this program. * 00023 * If not, see <http://www.gnu.org/licenses/>. * 00024 * * 00025 ***************************************************************************/ 00026 00027 #define FREPPLE_CORE 00028 #include "frepple/model.h" 00029 00030 namespace frepple 00031 { 00032 00033 00034 DECLARE_EXPORT void Buffer::updateProblems() 00035 { 00036 // Delete existing problems for this buffer 00037 Problem::clearProblems(*this); 00038 00039 // Problem detection disabled on this buffer 00040 if (!getDetectProblems()) return; 00041 00042 // Loop through the flowplans 00043 Date excessProblemStart; 00044 Date shortageProblemStart; 00045 bool shortageProblem = false; 00046 bool excessProblem = false; 00047 double curMax(0.0); 00048 double shortageQty(0.0); 00049 double curMin(0.0); 00050 double excessQty(0.0); 00051 for (flowplanlist::const_iterator iter = flowplans.begin(); 00052 iter != flowplans.end(); ) 00053 { 00054 // Process changes in the maximum or minimum targets 00055 if (iter->getType() == 4) 00056 curMax = iter->getMax(); 00057 else if (iter->getType() == 3) 00058 curMin = iter->getMin(); 00059 00060 // Only consider the last flowplan for a certain date 00061 const TimeLine<FlowPlan>::Event *f = &*(iter++); 00062 if (iter!=flowplans.end() && iter->getDate()==f->getDate()) continue; 00063 00064 // Check against minimum target 00065 double delta = f->getOnhand() - curMin; 00066 if (delta < -ROUNDING_ERROR) 00067 { 00068 if (!shortageProblem) 00069 { 00070 // Start of a problem 00071 shortageProblemStart = f->getDate(); 00072 shortageQty = delta; 00073 shortageProblem = true; 00074 } 00075 else if (delta < shortageQty) 00076 // New shortage qty 00077 shortageQty = delta; 00078 } 00079 else 00080 { 00081 if (shortageProblem) 00082 { 00083 // New problem now ends 00084 if (f->getDate() != shortageProblemStart) 00085 new ProblemMaterialShortage 00086 (this, shortageProblemStart, f->getDate(), -shortageQty); 00087 shortageProblem = false; 00088 } 00089 } 00090 00091 // Note that theoretically we can have a minimum and a maximum problem for 00092 // the same moment in time. 00093 00094 // Check against maximum target 00095 delta = f->getOnhand() - curMax; 00096 if (delta > ROUNDING_ERROR) 00097 { 00098 if (!excessProblem) 00099 { 00100 // New problem starts here 00101 excessProblemStart = f->getDate(); 00102 excessQty = delta; 00103 excessProblem = true; 00104 } 00105 else if (delta > excessQty) 00106 excessQty = delta; 00107 } 00108 else 00109 { 00110 if (excessProblem) 00111 { 00112 // New excess qty 00113 // New problem now ends 00114 if (f->getDate() != excessProblemStart) 00115 new ProblemMaterialExcess 00116 (this, excessProblemStart, f->getDate(), excessQty); 00117 excessProblem = false; 00118 } 00119 } 00120 00121 } // End of for-loop through the flowplans 00122 00123 // The excess lasts till the end of the horizon... 00124 if (excessProblem) 00125 new ProblemMaterialExcess 00126 (this, excessProblemStart, Date::infiniteFuture, excessQty); 00127 00128 // The shortage lasts till the end of the horizon... 00129 if (shortageProblem) 00130 new ProblemMaterialShortage 00131 (this, shortageProblemStart, Date::infiniteFuture, -shortageQty); 00132 } 00133 00134 00135 00136 DECLARE_EXPORT string ProblemMaterialExcess::getDescription() const 00137 { 00138 ostringstream ch; 00139 ch << "Buffer '" << getBuffer() << "' has material excess of " << qty; 00140 return ch.str(); 00141 } 00142 00143 00144 DECLARE_EXPORT string ProblemMaterialShortage::getDescription() const 00145 { 00146 ostringstream ch; 00147 ch << "Buffer '" << getBuffer() << "' has material shortage of " << qty; 00148 return ch.str(); 00149 } 00150 00151 00152 }