Main Page | Class Hierarchy | Class List | File List | Class Members

/home/nutarojj/Desktop/adevs/include/adevs_dess.h

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 
00036 template <class X> class DESS: public Atomic<X>
00037 {
00038         public:
00040                 DESS();
00046                 virtual void evolve_func(double h) = 0;
00054                 virtual double next_event_func(bool& is_event) = 0;
00059                 virtual void discrete_action_func(const Bag<X>& xb) = 0;
00065                 virtual void discrete_output_func(Bag<X>& yb) = 0;
00075                 virtual void state_changed() = 0;       
00077                 void delta_int();
00079                 void delta_ext(double e, const Bag<X>& xb);
00081                 void delta_conf(const Bag<X>& xb);
00083                 void output_func(Bag<X>& yb);
00085                 double ta();
00087                 virtual ~DESS(){}
00088 
00089         private:
00090                 // Time until the next event
00091                 double sigma;
00092                 // The phase can be step, event, or output
00093                 enum { DESS_STEP, DESS_EVENT, DESS_OUTPUT } phase;
00094                 // Empty bag for internal events
00095                 Bag<X> empty_bag;
00096                 // Temporary bag for discrete output values
00097                 Bag<X> ytmp;
00098 };
00099 
00100 template <class X>
00101 DESS<X>::DESS()
00102 {
00103         sigma = 0.0;
00104         phase = DESS_STEP;
00105 }
00106 
00107 template <class X>
00108 void DESS<X>::delta_int()
00109 {
00110         if (phase == DESS_OUTPUT)
00111         {
00112                 ytmp.clear();
00113                 bool event = false;
00114                 sigma = next_event_func(event);
00115                 if (event) phase = DESS_EVENT;
00116                 else phase = DESS_STEP;
00117         }
00118         else
00119         {
00120                 // Evolve the continuous variables
00121                 evolve_func(sigma);
00122                 // Notify derived class of state change
00123                 state_changed();
00124                 // If this is an internal discrete event
00125                 if (phase == DESS_EVENT)
00126                 {
00127                         // Get the output
00128                         discrete_output_func(ytmp);
00129                         // Change the state 
00130                         discrete_action_func(empty_bag);
00131                         // Notify derived class of the event
00132                         state_changed();
00133                         phase = DESS_OUTPUT;
00134                         sigma = 0.0;
00135                 }
00136                 // Otherwise, just schedule the next event or 
00137                 // integration step
00138                 else
00139                 {
00140                         bool event = false;
00141                         sigma = next_event_func(event);
00142                         if (event) phase = DESS_EVENT;
00143                         else phase = DESS_STEP;
00144                 }
00145         }
00146 }
00147 
00148 template <class X>
00149 void DESS<X>::delta_ext(double e, const Bag<X>& xb)
00150 {
00151         // Update the continuous variables
00152         evolve_func(e);
00153         // Notify the derived class
00154         state_changed();
00155         // Apply the discrete state change function
00156         discrete_action_func(xb);
00157         // Notify the derived class again
00158         state_changed();
00159         // Schedule the next step or event
00160         bool event = false;
00161         sigma = next_event_func(event);
00162         if (event) phase = DESS_EVENT;
00163         else phase = DESS_STEP;
00164 }
00165 
00166 template <class X>
00167 void DESS<X>::delta_conf(const Bag<X>& xb)
00168 {
00169         // If it is not a state event, then this is just an input coinciding with
00170         // some book keeping operations
00171         if (phase == DESS_OUTPUT || phase == DESS_STEP)
00172         {
00173                 ytmp.clear();
00174                 delta_ext(sigma,xb);
00175         }
00176         // Confluence of a state/time event an external input requires special
00177         // handling
00178         else if (phase == DESS_EVENT)
00179         {
00180                 // Update the continuous variables
00181                 evolve_func(sigma);
00182                 // Notify the derived class
00183                 state_changed();
00184                 // Compute the output
00185                 discrete_output_func(ytmp);
00186                 // Compute the discrete state change
00187                 discrete_action_func(xb);
00188                 // Notify the derived class
00189                 state_changed();
00190                 // Send the output
00191                 phase = DESS_OUTPUT;
00192                 sigma = 0.0;
00193         }
00194 }
00195 
00196 template <class X>
00197 void DESS<X>::output_func(Bag<X>& yb)
00198 {
00199         typename Bag<X>::iterator iter = ytmp.begin();
00200         for (; iter != ytmp.end(); iter++)
00201         {
00202                 yb.insert(*iter);
00203         }
00204 }
00205 
00206 template <class X>
00207 double DESS<X>::ta()
00208 {
00209         return sigma;
00210 }
00211 
00212 } // end of namespace
00213 
00214 #endif

Generated on Mon Jun 1 09:53:42 2009 for adevs by  doxygen 1.3.9.1