adevs
|
00001 /*************** 00002 Copyright (C) 2000-2006 by James Nutaro 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Lesser General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public 00015 License along with this library; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 Bugs, comments, and questions can be sent to nutaro@gmail.com 00019 ***************/ 00020 #ifndef _adevs_dess_h_ 00021 #define _adevs_dess_h_ 00022 #include "adevs_models.h" 00023 00024 namespace adevs 00025 { 00026 00038 template <class X> class DESS: public Atomic<X> 00039 { 00040 public: 00042 DESS(); 00048 virtual void evolve_func(double h) = 0; 00056 virtual double next_event_func(bool& is_event) = 0; 00061 virtual void discrete_action_func(const Bag<X>& xb) = 0; 00067 virtual void discrete_output_func(Bag<X>& yb) = 0; 00077 virtual void state_changed() = 0; 00079 void delta_int(); 00081 void delta_ext(double e, const Bag<X>& xb); 00083 void delta_conf(const Bag<X>& xb); 00085 void output_func(Bag<X>& yb); 00087 double ta(); 00089 virtual ~DESS(){} 00090 00091 private: 00092 // Time until the next event 00093 double sigma; 00094 // The phase can be step, event, or output 00095 enum { DESS_STEP, DESS_EVENT, DESS_OUTPUT } phase; 00096 // Empty bag for internal events 00097 Bag<X> empty_bag; 00098 // Temporary bag for discrete output values 00099 Bag<X> ytmp; 00100 }; 00101 00102 template <class X> 00103 DESS<X>::DESS() 00104 { 00105 sigma = 0.0; 00106 phase = DESS_STEP; 00107 } 00108 00109 template <class X> 00110 void DESS<X>::delta_int() 00111 { 00112 if (phase == DESS_OUTPUT) 00113 { 00114 ytmp.clear(); 00115 bool event = false; 00116 sigma = next_event_func(event); 00117 if (event) phase = DESS_EVENT; 00118 else phase = DESS_STEP; 00119 } 00120 else 00121 { 00122 // Evolve the continuous variables 00123 evolve_func(sigma); 00124 // Notify derived class of state change 00125 state_changed(); 00126 // If this is an internal discrete event 00127 if (phase == DESS_EVENT) 00128 { 00129 // Get the output 00130 discrete_output_func(ytmp); 00131 // Change the state 00132 discrete_action_func(empty_bag); 00133 // Notify derived class of the event 00134 state_changed(); 00135 phase = DESS_OUTPUT; 00136 sigma = 0.0; 00137 } 00138 // Otherwise, just schedule the next event or 00139 // integration step 00140 else 00141 { 00142 bool event = false; 00143 sigma = next_event_func(event); 00144 if (event) phase = DESS_EVENT; 00145 else phase = DESS_STEP; 00146 } 00147 } 00148 } 00149 00150 template <class X> 00151 void DESS<X>::delta_ext(double e, const Bag<X>& xb) 00152 { 00153 // Update the continuous variables 00154 evolve_func(e); 00155 // Notify the derived class 00156 state_changed(); 00157 // Apply the discrete state change function 00158 discrete_action_func(xb); 00159 // Notify the derived class again 00160 state_changed(); 00161 // Schedule the next step or event 00162 bool event = false; 00163 sigma = next_event_func(event); 00164 if (event) phase = DESS_EVENT; 00165 else phase = DESS_STEP; 00166 } 00167 00168 template <class X> 00169 void DESS<X>::delta_conf(const Bag<X>& xb) 00170 { 00171 // If it is not a state event, then this is just an input coinciding with 00172 // some book keeping operations 00173 if (phase == DESS_OUTPUT || phase == DESS_STEP) 00174 { 00175 ytmp.clear(); 00176 delta_ext(sigma,xb); 00177 } 00178 // Confluence of a state/time event an external input requires special 00179 // handling 00180 else if (phase == DESS_EVENT) 00181 { 00182 // Update the continuous variables 00183 evolve_func(sigma); 00184 // Notify the derived class 00185 state_changed(); 00186 // Compute the output 00187 discrete_output_func(ytmp); 00188 // Compute the discrete state change 00189 discrete_action_func(xb); 00190 // Notify the derived class 00191 state_changed(); 00192 // Send the output 00193 phase = DESS_OUTPUT; 00194 sigma = 0.0; 00195 } 00196 } 00197 00198 template <class X> 00199 void DESS<X>::output_func(Bag<X>& yb) 00200 { 00201 typename Bag<X>::iterator iter = ytmp.begin(); 00202 for (; iter != ytmp.end(); iter++) 00203 { 00204 yb.insert(*iter); 00205 } 00206 } 00207 00208 template <class X> 00209 double DESS<X>::ta() 00210 { 00211 return sigma; 00212 } 00213 00214 } // end of namespace 00215 00216 #endif