Title: Chapter 6 Methodology: How to Model and Simulate
1Chapter 6 Methodology How to Model and Simulate
- Methodology
- Suggested Project Report Outline
- Avoiding Some Common Formalism Violations
- Using Object Copy methods to Avoid Entanglement
among Multiple Receivers - SimView display elements message contents and
component states - Event list and Applications
- Plotting with CellGridPlot
- Categorizing Simulation Modes and Packages in
DEVSJAVA 2.7 - Switching from structure/behavior viewing to
fast simulation
2MS Methodology
- First think about your objectives- find a level
of difficulty that seems achievable in the time
available. - Develop the experimental frames first to meet
these objectives. - Develop your atomic models and coupled models and
and test them in hierarchical stage wise fashion
in SimView. - Start your exploratory phase -- get some
preliminary results of execution within
experimental frames. What is the lay of the
land? Which factors appear to matter most? - Start your production runs (for final results) by
concentrating on the factors that seem to be
important from your initial exploration. - If you need better performance, remove all
unessential code, including output and print
statements. Switch execution from SimView to
fast-as-can simulation as shown next. - For greater performance migrate your model to
parallel/distributed fast-as-can simulation (not
currently available). - If your objectives were to develop real-time
execution models, migrate them to real-time
execution (distributed, non-distributed) as shown
next.
3Suggested Project Report Outline
- Problem statement Objectives of the
Project - General Description of the System to be
Studied - Objectives of the Modeling and Simulation
Study - The Simulation Model
- System Entity Structure or Hierarchical diagrams
and - explanation of operation
- Illustrative DEVSJAVA code or pseudo code
-
- Experimental frame and how it serves to achieve
the Objectives - Experiments
- Results ( or expected results)
- Conclusions (what did you learn from this
work - Future Work
-
- References
- Appendix more details or code
4Avoiding Some Common Formalism Violations
This means that the state after receiving a bag
of inputs is uniquely determined by the current
state, the elapsed time, and in particular the
bag of inputs. Since a bag is an unordered
collection, the result cannot depend on the order
used in examining the inputs In the example on
the left, the order of examining the bag
a,b matters since if a is in the first
content to be examined the result is to do A,
while if b is thein first conent, the result
is to do B. The example on the right completely
examines the bag for occurrence of a and then
occurrence of b. The resulis always to do A for
the bag a,b.
public void deltext(double e, message x)
Continue(e) for (int i 0 i lt x.getLength()
i) if (messageOnPort(x, a", i))
ltdo Agt for (int i 0 i lt x.getLength()
i) else if (messageOnPort(x, b", i))
ltdo Bgt
public void deltext(double e, message x)
Continue(e) for (int i 0 i lt x.getLength()
i) if (messageOnPort(x, a", i)) ltdo Agt
else if (messageOnPort(x, b", i)) ltdo Bgt
result is undefined
result is uniquely defined
5Avoiding Some Common Formalism Violations
SimpArc .procQ
This means that the output function does not have
an effect on the state it cant change it,it
can only look at it. The following violates
this requirement.
public message out( ) message m new
message() if (phaseIs("transmit")) m.add(makeCon
tent("out", new entity("packet "
count''destination))) count count 1
Here the intent is that the state variable, count
is incremented by the call to the output
function. But DEVS simulator is guaranteed only
to use the return result of the call as specified
in the DEVS simulation protocol, not to obey the
side-effect of changing the count The correct way
to update the count is in the internal
transition function which is called immediately
after the output function
public void int( ) if (phaseIs("transmit")) cou
nt count 1
6Sending/Receiving/Interpreting Messages how to
use casting to receive instances of arbitrary
entity subclasses
SimpArc .procQ
coupled model
entity
in
out
A
B
doubleEnt
doubletEnt(double)
double
double
getv() ? double
coupling (A,out,A,in)
public message out( ) message m new
message() m.add( makeContent("out", new
doubleEnt(1.2)) return m
in
out
cast
message
doubleEnt
add
p
getv()
val
doubleEnt
deltext(double e,message) x)if
(somethingOnPort(x,"in") entity val
getEntityOnPort(x,"in") doubleEnt f
(doubleEnt)val double v f.getv()
v
content
double
casting the received entity down to the doubleEnt
subclass
7Sending/Receiving/Interpreting Messages
(contd) multiple copies of an object are needed
to avoid hard-to-find dependencies.
SimpArc .procQ
coupled model
entity
in
out
A
B
job
- job(procTime)
- update(e)
- procTime e
- copy() return new
- job(procTime)
job
job
coupling (A,out,A,in)
This instance of job is now shared in common by
both A and B if either makes a change to its
state, then the other will also be subject to
it. For example, if B does
job.update(10) then the instance at A will be
similarly altered. This can lead to mysterious
effects (similar to quantum entanglement) where
components of a model can influence each other
outside of their interface couplings. It is
difficult to trace this kind of non-modularity.
Suppose A sends its instance of job directly to
B public message out( ) message m new
message() m.add( makeContent("out", job) return
m
The right way B stores a copy of its
input deltext(double e,message) x) if
(somethingOnPort(x,"in)) job temp
getEntityOnPort(x,"in") myJob
temp.copy() where copy() is a method you define
to create a new instance of job and give it
values of an existing one.
out
and B stores it as its instance deltext(double
e,message) x) if (somethingOnPort(x,"in")) myJob
getEntityOnPort(x,"in")
The cure is simple create a new instance as a
local copy of an entity if it is to be altered
(this happens automatically when using toString()
and toObject(), see chap. 12)
8SimView Using toString() to display an entities
contents, and getTooltipText () to show component
state information.
receiver
sender
SimView displays the value returned by
getToolTipText
public message out( ) message m new
message() m.add(makeContent("out",
new vect2DEnt(x,y))) return m
SimView displays the value returned by
toString() in the moving window that represents
transmitting a message
The modeler must define toString() for the
simulator to use polymorphically. For example
public String toString() return
doubleFormat.niceDouble( x )
","doubleFormat.niceDouble(y) public String
getName() return toString()
public String getTooltipText () return
super.getTooltipText() "\n" "Cost "
linkCost
9Using toString() and toObject() to facilitate
deploying models in distributed simulation
receiver
sender
DEVS simulator uses toString() to encode the
entity as a String which is sent across the wire
public message out( ) message m new
message() m.add(makeContent("out",
new vect2DEnt(x,y))) return m
public void deltext(double e ,message x) for
(int i0 ilt x.getLength()i) if
(messageOnPort(x,in",i)) entity en
x.getValOnPort(in",i) position
vect2DEnt.toObject(en)
The modeler also needs to define toObject() and
use this method in decoding the message. public
static vect2DEnt toObject(String nm) int
commaIndex nm.indexOf(",") String xs
nm.substring(0,commaIndex) String ys
nm.substring(commaIndex1,nm.length()) return
new vect2DEnt(Double.parseDouble(xs),Double.parseD
ouble(ys)) public static vect2DEnt
toObject(entity ent) return toObject(ent.getName(
))
The modeler must define toString() for the
simulator to use polymorphically. For example
public String toString() return
doubleFormat.niceDouble( x )
","doubleFormat.niceDouble(y) public String
getName() return toString()
10Event Lists and Applications
11JobQueue an event list that illustrates DEVS
closure under coupling
- DEVS closure under coupling asserts that every
coupled model is behaviorally equivalent to a
basic DEVS - This makes hierarchical construction possible
- Class JobQueue illustrates how coupled models
can be expressed as atomic models (hence as basic
DEVS) - this constructive approach is to given an atomic
model an event list with which it simulates the
transitions of the coupled model it represents
(it mimics the formal proof given within the DEVS
formalism for closure under coupling) - JobQueue delays incoming jobs by a fixed delay
time - it can easily be modified to allow arbitrary
delay times including accepting the time advances
of components of a coupled model as delays
public class JobQueue extends ViewableAtomic
The jobs that have arrived at this
job-queue. protected Relation arrived
new Relation() Those jobs that have
become due. protected Bag due
This component's record of what the current
simulation time is. protected double
clock The length of time after a job
arrives until it is due. protected
double jobDueDelay Entity wrapper
for he minimum time of all the jobs that have
arrived. protected doubleEnt
minimumJobTime
CellGridPlot extends JobQueue where jobs become
point plots and the delay is used to do a second
plot to overwrite the first giving the dimming
effect.
genDevs.Modeling. BasicModes. JobQueue
12JobQueue continued
Creates a bag of jobs that are due
consisting of those that have arrived mand have
the minimum time. protected void
detmDueJobs() for each arrived
job due new Bag() Iterator i
arrived.iterator() while (i.hasNext())
// if the job is one of those that
has the minimum time Pair pair
(Pair)i.next() if (pair.getKey().equa
ls(minimumJobTime)) //add to
this job to the bag of those that are due
due.add(pair.getValue())
Removes all the jobs of the minimum time from
the container of arrived jobs.
protected void removeAllMinimumJobs()
for each arrived job Iterator i
arrived.iterator() while (i.hasNext())
// if the job is one of those that
has the minimum time Pair pair
(Pair)i.next() if (pair.getKey().equa
ls(minimumJobTime)) //remove
the job from the arrived jobs container
arrived.remove(pair.getKey(),
pair.getValue())
///////////////////// public void initialize()
passivate() clock 0
super.initialize() arrived new
Relation() due new Bag()
minimumJobTime new doubleEnt(INFINITY)
///////////////////// public void deltint()
clock clock sigma
deltintHook1() //hook for
use by CellGridPlot removeAllMinimumJobs(
) holdUntilNextJob()
///////////////////// protected void
deltintHook1() ///////////////////// public
message out() message m new
message() if (phaseIs("active"))
Iterator i due.iterator()
while (i.hasNext())
m.add(makeContent
("out", (entity)i.next()) return m
///////////////////// public void deltext(double
e, message m) clock clock
e Continue(e) for (int i 0 i
lt m.getLength() i) if
(messageOnPort(m, "in", i))
entity value m.getValOnPort("in", i)
arrived.put (
new doubleEnt(clock jobDueDelay),
value)
deltextHook1(message)
//hook for use by CellGridPlot
holdUntilNextJob() /////////////////////
protected void deltextHook1(message message)
////////////////// public void
deltcon(double e, message message)
// the order needed here is the reverse of the
default deltcon order deltext(e,
message) deltint()
Makes this job-queue hold in phase
"active" until the time of the next job of
minimum time Also determines the new due jobs
protected void holdUntilNextJob()
detmMinimumJobTime() if
(!arrived.isEmpty())
holdIn("active",
minimumJobTime.getv() - clock)
else passivate() detmDueJobs()
13Plotting with CellGridPlot
genDevs.plots cellGridPlot
- timePlot and pulsePlot input ports accept real
valued entities (doubleEnt). - timePlot displays time trajectories
- pulsePlot draws lines from the x axis to the
plotted points
Example BoxCar
CellGridPlot sumP new CellGridPlot("Sum
Plot",1,200) sumP.setCellGridViewLocation(600,500
) sumP.setSpaceSize(100,40) sumP.setCellSize(5)
sumP.setTimeScale(50) add(sumP) addCoupling(s
um,"out", sumP,"pulsePlot")
- CellGridPlot is a subclass of ViewableAtomic
that provides graph plotting. - Each instance of CellGridPlot can draw on its
own instance of class CellGridView. or can share
instances of the latter. - CellGridPlot is treated in the same way as other
DEVS components This implies plotting occurs in
step with the simulation and in real-time or
distributed fashion as desired. Also plotters may
be decoupled allowing faster production runs of
core models. - Different constructors and different input ports
offer alternative drawing services and expect
different kinds of entity values. - CellGridPlot instances are hidden by default. To
show an instance use its method setHidden(false). - Since plotting occurs in real time dimming of
past values is - provided. This allows either erasing (using white
dimming) or tracking (using softer colors) past
trajectory segments. The delay time specified in
the constructor determines the size of the
non-dimmed segment.
- delay time for dimming
- veritical scale of plot
14Plotting with CellGridPlotcontinued
Random. oenDimCellSpace
Example oneDimCellSpace automates plots public
void addPlots ( double stateMax, int
transitionMax, double timeMax) //all cells
output ports are coupled to 3 common plots for
state, transition and time For example, the
transition plot is CellGridPlot transitionP
new CellGridPlot(" Transition Plot",1,
"location",numCells,
"transitions", transitionMax) //co
uple each cell to the plotter addCoupling(cell,
"outNum", transitionP, "drawCellToScale")
The output function of each oneDimCell is of the
form public message out() // m.add(makeContent
("outNum", new DrawCellEntity( drawPos,
numTransitions, Color.black, Color.gray))) //
draw color, dim color
each cell has its own drawPos and numTransitions
specify X and Y labels and scales
- drawCellToScale input port expects
DrawCellEntity as value and draws a point
specified by both I and j as well as draw and
dim colors. - drawI and drawJ input ports draw points with
the I and j coordinates respectively given by the
input using the last saved value of the other
coordinate. This is needed since usually i and j
dont change simultaneously. The ports expect
doubleEnt and drawing uses the user specified
scale. - drawCell input port expects DrawCellEntity as
value and does not draw to scale - draw2D input port expects DrawCellEntity as
value and draws a color at i,j that is obtained
from a table with input k - drawString input port expects a drawCellEntity
and draws a string starting from the given
point.(see CelGridPlot class for more detail)
Example Harmonic Oscillator CellGridPlot t
new CellGridPlot("XY PhasePlot",1,
3initx,3initx) t.setCellGridViewLocation(500,10
0) add(t) addCoupling(x,"out",t,"drawI") addCo
upling(y,"out",t,"drawJ")
specify X and Y scales
Introduction. harmOsc
15Categorizing Simulation Modes and Packages in
DEVSJAVA 2.7
16Model Development using Model Continuity
Implementation/ Logical Simulation
Model Distribution/ Distributed Simulation
Real-Time Distributed Simulation/ Execution
Modeling
Checks Model Logical Behavior
Checks Model Logical Behavior in
Distributed Environment
Checks Model Temporal Behavior
DEVS Formalism
genDevs. simulation. distributed
genDevs. simulation. realTime
genDevs. simulation
17Using inheritance and polymorphism to allow easy
switching from structure/behavior viewing to
fast simulation
Later, when ready for production runs, execute
them without change in fast-as-can simulation
Even though ViewableAtomic and ViewableDigraph
models can hold information intended for
SimView, they need not be altered to run outside
of SimView. For example, to run a
ViewableDigraph model in a main routine
define public static void main(String
args) ViewableDigraph d new
(Random,rule30CellSpace) r new coordinator
(d) r.initialize() //to measure execution
time if desired initTime System.currentTimeMill
is() r.simulate(100) termTime
System.currentTimeMillis() This can be
executed in JBuilder of by changing directory to
DevsJava/classes and entering on the command line
gtjava Random.rule30CellSpace
You can develop models and test them in SimView
simView. ViewableDigraph
To understand how this is possible, consider that
in atomicSimulator the Devs Simulator Cycle
implementation includes hooks within its
methods, e.g., public void computeInputOutput(do
uble t) if(equalTN(t)) output
myModel.Out() elseoutput new message()
computeInputOutputHook1() These hooks are
dummy methods within atomicSimulator,
e.g., protected void computeInputOutputHook1()
In ViableAtomicSimulator the hooks are given
definitions that allow the SimViewCoordinator to
get the infromation it needs to display in
SimView, .e.g., protected void
computeInputOutputHook1() if (listener
null) return ContentIteratorInterface
iterator output.mIterator() while
(iterator.hasNext())
ContentInterface content iterator.next()
listener.contentOutputted((content)content
,\ viewableAtomic,
content.getPort().getName())
simView. ViewableAyatomic
18Deploying a coupled model onto a distributed,
decentralized, real-time simulation
For the coupled model define a RTCoordinatorServer
,e.g., public class StartVehicleSpaceServer
public static void main(String args)
try System.out.println("For use by clients,
this host is " InetAddress.getLocalHost().getHost
Address()) catch(Exception c) new
RTCoordinatorServer(new vehicleSpace(), 10)
You can develop models and test them in SimView
This will give you the address needed by clients
For each component model define a
RTCoordinatorClient, e.g., public class
StartEvaderClient public static void
main(String args) new RTCoordinatorClient
( new vehicle("evader",new
vect2DEnt(40,40)), "192.168.1.101",
//RTCoordinatorServers address
//or if on same machine as the
server //you can use "localhost",
Constants.serverPortNumber)
StartPursuer Client
StartVehicleSpaceServer
StartEvader Client
Continuity. StartVehicleSpaceServer
intranet or internet
Later, when ready for production runs, execute
them without change in distributed, real0time,
decentralized simulation
You can now distribute these classes onto one or
more computers and execute them from jBuilder or
from the command line as illustrated before.
You can also distribute hierarchically using
RTCoordinatorServerAndClient