Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Data Structures   File List   Namespace Members   Data Fields   Globals   Related Pages   Examples  

Base1.cpp

The basic simulation techniques of ODEMx are introduced.

A process simulation contains a number of processes that describe the active elements in a model. A process contains a sequence of actions. These actions are timeless. Time consumption is realised with special time-operations. In this example several of this time-operations are presented together with an example process.

//----------------------------------------------------------------------------
//      Copyright (C) 2002, 2003 Humboldt-Universitaet zu Berlin
//
//      This library is free software; you can redistribute it and/or
//      modify it under the terms of the GNU Lesser General Public
//      License as published by the Free Software Foundation; either
//      version 2.1 of the License, or (at your option) any later version.
//
//      This library is distributed in the hope that it will be useful,
//      but WITHOUT ANY WARRANTY; without even the implied warranty of
//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//      Lesser General Public License for more details.
//
//      You should have received a copy of the GNU Lesser General Public
//      License along with this library; if not, write to the Free Software
//      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//----------------------------------------------------------------------------
#include <odemx/base/Process.h>

#include <iostream>

using namespace std;
using namespace odemx;

//
// The first Process is a simple SimTime timer.
// It does write a '.' every full (1.0) tic in SimTime.
//
class TimerA : public Process {
public:
        //
        // We label all instances of this class 'TimerA'.
        // ODEMx changes the label on its own to prevent 
        // confusion. It will add a number to the label
        // if more than one Timer is created in the
        // simulation. This procedure guarantees that
        // every label is unique in a simulation.
        //
        // When we create a Timer object we will have to
        // provide a pointer to the Simulation we want it
        // to participate with.
        //
        TimerA(Simulation* sim) : Process(sim, "TimerA") {}

        //
        // The behaviour of a user process must be defined
        // by an implementation of the pure virtual function
        // 'int main()'. The return value of this function
        // is stored and can be accessed with 'getReturnValue()'.
        // As long as 'main()' hasn't finished, the return
        // value is not valid. You can use 'hasReturned()'
        // to check this condition.
        //
        virtual int main() {
                while (true) {
                        //
                        // We use 'holdFor()' to let the SimTime pass.
                        // 'holdFor()' requires a time period. We could
                        // also use 'activateIn()'.
                        // The difference between these two is seen if
                        // there is more than one process scheduled at
                        // the same time. 'holdFor' would than schedule
                        // the current process as the last while 'activateIn'
                        // would schedule the current process as the first one.
                        //
                        holdFor(1.0);

                        cout << '.';
                }

                return 0;
        }
};

int main(int argc, char* argv[]) {
        //
        // For this example we can use the DefaultSimulation.
        // In more complex applications it is recommended to
        // provide a custom-made simulation class.
        //
        TimerA* myTimer=new TimerA(getDefaultSimulation());

        //
        // The new process is just created by now.
        // It won't be executed because it is not activated.
        // A process can be activated by any of these methods:
        //
        // 'hold()'
        // 'holdFor()'
        // 'holdUntil()'
        // 'activate()'
        // 'activateIn()'
        // 'acitvateAt()'
        //
        // 'hold()' and 'activate()' are equal to 'holdFor(0.0)'
        // and 'activateIn(0.0)'. 'holdUntil(t)' and 'activateAt(t)'
        // are equal to 'holdFor(t-now)' and 'activateIn(t-now)'.
        //
        myTimer->activate();

        //
        // There are three ways to compute a simulation.
        // Firstly, you can 'run()' the simulation until it is
        // finished. A simulation is finished if there is no active 
        // process left or it is stopped with 'exitSimulation()'.
        // Secondly, you can compute a simulation 'step()' by step.
        // Thirdly, you can run a simulation until a given SimTime is
        // reached or passed with 'runUntil()'.
        //
        // Because TimerA is running for ever we shouldn't use
        // 'run()'. Instead we try both 'step()' and 'runUntil()'.
        //
        cout << "Basic Simulation Example" << endl;
        cout << "========================" << endl;

        for (int i=1; i<5; ++i) {
                getDefaultSimulation()->step();
                cout << endl << i << ". step time=" << getDefaultSimulation()->getTime() << endl;       
        }

        cout << endl;
        cout << "continue until SimTime 13.0 is reached or passed:";
        getDefaultSimulation()->runUntil(13.0);
        cout << endl  << "time=" << getDefaultSimulation()->getTime() << endl;

        cout << "========================" << endl;

        return 0;
}


Generated on Mon Aug 11 10:36:06 2003 for ODEMx by doxygen1.3