<< Click to Display Table of Contents >> 8. Change Attribute Values |
|
Show/Hide Hidden Text |
In this run, we will use actions to move cows from one pasture to another by changing the value of the "pasture" attribute.
Stages of Ventity™ Modeling |
In this run, we will ... |
Stage 1 - Define entity types
|
Modify the cow entity type to include an action that will change the cow's pasture assignment.
|
Stage 2 - Initialize the model
|
No change from the previous run.
|
Stage 3 - Run the model Configure time settings and perform calculations
|
No change from the previous run.
|
Stage 4 - Examine results See model behavior in graphs and tables
|
Look at numbers of cows in each pasture to see the effect of the action. |
1. Begin by making a copy of Exercise 6 Complete, and call it Exercise 8. Exercise 6 Complete can be found in your User > Documents > Ventity Projects > Sample Projects directory, or by clicking [here].
We will imagine that from time to time, cows wander from one pasture to the next. To keep it simple we'll assume that they go the same direction, so cows in a particular pasture all go the same new pasture when they move. Thus, which pasture is "next" depends not on the cow, but on which pasture the cow is in at the moment. It makes sense to define which pasture is next in the pasture entity definition, not the cow.
2. In the pasture entity, create a new attribute by dragging a node from the palette or clicking the "new attribute" button on the attribute tab of the inspector, and call it "next pasture" or by right-clicking on the diagram and selecting "New Attribute".
Note that we can leave "refers to" set to "<none>". Although each "next pasture" is indeed a pasture entity, we will not be needing any information about that entity other than its name, so we do not need to create a reference to that next pasture. We can also leave the default initial value blank since there is no value that makes sense to use for everyone as a default. We will set specific values during the initialization phase below.
Next we'll create an action whose job is to change a cow's pasture from one value to the next. Actions tell Ventity what to change, and we'll also need to create a trigger specifying when to change. Actions and triggers can be created in either order. Here, we'll begin by defining the action.
3. Create a new action for the cow entity either by right-clicking "cow" in the Model Overview and choosing "New Action", or click the "New Action" button at the bottom of the actions tab of the cow entity inspector. A new Action Inspector is created, called Action 1.
4. Edit it as follows:
Rename from "Action1" to "Switch Pastures"
Change the Kind to "Command". (Read about different kinds of actions in Defining Entity Types).
Add a description.
This sets up a command action, which can reset attribute or stock values, move things between stocks, or trigger other actions. In this case, we want to reset the value of the cow's "pasture" attribute. We will do this by putting a reference to the cow.pasture attribute on the diagram of the action to act as a surrogate, and entering the new value there.
When you show the references tab of the action inspector, you see two references already exist: parent and invoker. Every action includes these references. "Parent" refers to the entity that owns the action, in this case, the cow entity. ("Invoker" refers to the entity that owns the trigger. Since we have not yet defined a trigger for this action, the Invoker reference is not defined. Until we specify otherwise, Ventity will assume the Invoker will be a cow entity as well.) We want this action to change the value of the cow's "pasture" attribute.
5. Drag the pasture attribute from the Parent reference on to the action's diagram:
The Parent•pasture node is a surrogate; editing a surrogate is how you tell Ventity what the new value of the attribute should be. You can make surrogates of attributes or stocks, whose values will be reset by the action. You can also add flows into, out of, or between stocks, and the action will make a single transfer of the amount you specify in the flow in, out or between the stocks.
6. Right-click to edit the Parent•pasture node, and set the "new value" to parent.pasture.next pasture.
The rationale is: we want the new value to be the "next pasture." Which next pasture? The one assigned to the pasture the cow is currently in. Which cow? The cow that is the parent of this action. In other words, the cow under consideration is the parent of this action, so we want to change the parent's pasture to the parent's pasture's next pasture.
We have now defined the next pastures cows will go to from their current pastures (to be specified during initialization), and created an action that makes the change. We still need to define the trigger that signals when to make the change.
7. Notice that this reference is two layers deep, indicated by the presence of two "." in the expression. This will run, but you can't diagram the two-hop reference without a warning. A cleaner option is to create a reference to point to parent.pasture, so that it can be used directly. To do that, switch to the Reference tab of the action's inspector:
If you expand the Parent reference, you can see the Parent.pasture.
Now use the [+] icon to add a new reference. Rename it something like "Parent pasture" and change the Target Type to "Pasture" using "Parent.pasture" as the Value to Match:
Now you can rewrite the surrogate's expression, using this reference, and right-click to add the diagram element:
8. In the cow entity diagram, add a trigger. You can do this by (a) dragging a trigger node from the palette, (b) clicking "new trigger" at the bottom of the actions tab in the cow inspector, or (c) dragging the action "Switch Pastures" from the cow inspector's actions tab onto the diagram.
9. We will define the trigger so that cows move on to the next pasture whenever the amount they are eating is less than they desire. Thus, the trigger will depend on desired consumption rate and actual consumption rate, so draw arrows so indicating.
10. Right-click the trigger and edit it as follows:
Rename the trigger to "move", or if you wish to be more descriptive, "move when hungry".
Set to Period End. If the cow moves, she moves immediately after the flow (grazing) has happened, so she will be reported in the next pasture at the beginning of the next timeslice.
For "Trigger If:", write in the expression "actual consumption rate < desired consumption rate." Whenever this is true, the action will be invoked.
The action that will be invoked is "Switch Pastures". Since no reference is given, Ventity takes this to mean "the action named Switch Pastures that is owned by the same entity who owns this trigger". See actions for more information.
Add a description.
Each time step, Ventity will check the "Trigger If" condition for each cow. When the condition is met for any particular cow, Ventity will invoke the Switch Pastures action for that cow.
We have now •added a "next pasture" attribute to each pasture, indicating where cows move on to, •added a "Switch Pastures" action to cows, which moves them on to the next pasture, and •added a "move" trigger to cows, which invokes the Switch Pastures action anytime a cow's consumption is less than she desires.
We are ready to move on to initializing the simulation.
|
We need to provide information about the value of "next pasture". From the Input Data section of the Model Overview, double-click "many pastures" to edit it, and in the pasture tab, provide each pasture with the name of the next pasture that cows will move to:
As shown above, a cow that is in the amber waves pasture will move, when its Switch Pastures action is triggered, to green gables. A cow starting in green gables will move to clover fields, and so on.
While we're here, uncheck the "thistle hill" cows from the cow tab, so we don't keep getting annoyed by the undefined pasture issue.
(Or if you prefer, add a "thistle hill" pasture to the model on the pasture tab.)
|
Run the model! |
What do we expect? In exercise 6, all cows had enough to eat except for the four cows in Green Gables, who ate faster than their pasture could recharge. So we would expect cows all to stay where they are, except for those four, who at some point should move from Green Gables to Clover Fields.
In the variables tab of the cow[pasture] inspector, right-click "count" and create a line chart by plotting the variable. As expected, the number of cows in Green Gables drops from 4 to 0 at the same time that the number of cows in Clover Fields increases from 2 to 6.
If we make a line chart of Grass Height from the Pasture entity,
we see Green Gables grass height decreasing to near zero, then recovering once the cows have moved on to Clover Fields. When the cows move, Clover Fields now has more cows grazing on it, so its net grass growth rate slows down.
Things are working as expected. Let's make things a little more complicated by making two changes:
1. In the pasture diagram, change the rate of grass growth from 0.1 cm/day to 0.01 cm/day:
2. Right-click to edit "Run Control" in the Model Overview, and extend the time of the run for at least two years (731 time steps):
Check the "overwrite" box so we replace the previous run, and run again. What results do you expect?
Look again at the line chart of count in the cow[pasture] collection:
Cows leave Green Gables for Clover Fields as before, but then those 6 cows denude Clover Fields and join the two in Dairy Home Companion. When that runs out of grass, all eight cows decamp for Pasteurized Pastures. Meanwhile, Amber Waves pasture maintains a steady population of 3 cows. Are they always the same 3?
Right click the run under "Results" in the Model Overview and choose "View Data". On the "cow" tab, drag "pasture" up to the Group By bar. Scrolling down through the results for Amber Waves, we can verify that the same 3 cows (cow-1, cow-2 and cow-12) are there the whole time. We can imagine their peace won't last long though, because when Pasteurized Pastures runs out of grass, those 9 cows are headed to Amber Waves, as we can verify by revisiting the Many Pastures input data set:
Looking at Grass Height from the pasture entity,
Amber Waves grass height is slowly being munched away by those three cows. Meanwhile, the 9-cow load on Pasteurized Pastures is causing a steep loss of grass that will bottom out in 2017 sometime, and which will put Amber Waves under strain as all cows move there. Meanwhile, Green Gables and Clover Fields have been growing unmolested and may have recovered enough to provide forage for a number of cows for a while.
For another view of this phenomenon, right-click on the results run and select View Data -> As Data Grid. On this spreadsheet, sort by cow id by selecting the cow entity tab and dragging cow id to the header bar. Now, expand cowid: Cow-10 to view only the data for Cow-10. Scrolling down, we see that, once actual consumption becomes less than desired consumption, the cow immediately moves from its current desolate pasture to its "Next Pasture" in search of more food.
In the end, the total amount of grass growth is less than the total desired consumption, and so eventually, the cows will run out of grass. If determining this was your modeling goal, then the detailed tracking of cows and pastures in this model is not necessary. If your need is to study the movement of cows from one pasture to another and to understand how much time each pasture might have to recover, then an entity view is helpful.
In this exercise, we used command actions, invoked by triggers, to change attribute values of entities -- in this case to change the pastures to which individual cows were assigned. In the next exercise we will use create and self-delete actions to add and remove cows from the simulation. |