Sunteți pe pagina 1din 196

Universal Simulator Explained

Niels Holst
niels.holst@agrsci.dk
www.ecolmod.org

8 June 2015
Draft in progress

Department of Agroecology
Aarhus University
Denmark

About this book


Universal Simulator is a software package for collaborative ecological modelling. It is composed
of a GUI main module which is used to open and execute model specifications read from XML
files. The XML files specify the components constituting a model. The functionality of these
components are defined in plug-in libraries. This makes UniSim extendible and open for re-use.
It is programmed in standard C++ but relies on Qt. Universal Simulator is open source and
released under the terms of the GNU General Public License version 3.0 or later.
This book tells you how to download and run existing models developed for Universal
Simulator. You are instructed how to change the parameters and outputs of existing models (in
some cases also how to change the composition of sub-models). In-depth chapters explains how
the models were coded in C++.
This book is in the writing. Upcoming chapters will show you how to provide your own
models, coded in C++, as plug-in modules to Universal Simulator.
Universal Simulator currently runs only on Microsoft Windows; Linux and Mac OS versions
of Universal Simulator are in preparation.
Copyrights. Universal Simulator Explained by Niels Holst, Aarhus University, Denmark
is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Citation. Holst, N. (2013). A universal simulator for ecological models. Ecological
Informatics 13:70-76. dx.doi.org/10.1016/j.ecoinf.2012.11.001.
Acknowledgements. The development of Universal Simulator and the writing of this
book were supported by ENDURE (EU Network of Excellence) during 2007-2010, ICROFS
(International Centre for Research in Organic Food Systems) during 2008-2011 and PURE (EU
FP7) 2011-2014 . This document was produced using Lout, an open-source document-formatting
system.

Contents
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..

ii

.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Chapter 1. Installation
1.1. Installing Universal Simulator
.. .. .. .. .. .. .. .. .. .. .. ..
1.2. Running simulations .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..

1
1
1

About this book

Writing recipes .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Recipe structure and context
.. .. .. .. .. .. .. .. .. .. ..
References to parameters and variables .. .. .. .. .. .. .. .. ..
Parameter elements
.. .. .. .. .. .. .. .. .. .. .. .. .. ..
The integrator element
.. .. .. .. .. .. .. .. .. .. .. .. ..
Model elements
.. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Additional input files
.. .. .. .. .. .. .. .. .. .. .. .. ..
Output and trace elements
.. .. .. .. .. .. .. .. .. .. .. ..
Applications .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
2.8.1. Application 1. Life stage sequence
.. .. .. .. .. .. ..
2.8.2. Application 2. Random parameter values
.. .. .. .. ..
2.8.3. Application 3. Stage-structured population dynamics
.. ..
2.8.4. Application 4. Stage-structured SEIR epidemics model .. ..
2.8.5. Application 5. Functional response: predation, parasitisation,
fection .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
2.8.6. Application 6. Multi-way functional response
.. .. .. ..
2.9. Advanced handling of many models
.. .. .. .. .. .. .. .. ..

..
..
..
..
..
..
..
..
..
..
..
..
..
in..
..
..

3
3
4
6
6
7
8
8
11
11
14
18
20

..
..
..
..
..
..
..
..

43
43
44
47
51
53
57
62

.. .. .. .. .. .. .. .. .. .. .. .. .. ..
Chapter 4. The BtButTox model
4.1. Scenario simulations .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
4.2. Scenario recipes .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..

64
64
65

Chapter 2.
2.1.
2.2.
2.3.
2.4.
2.5.
2.6.
2.7.
2.8.

Chapter 3.
3.1.
3.2.
3.3.
3.4.
3.5.
3.6.
3.7.

Working with source code ..


Downloading source code
..
Navigating source code .. ..
Building from source code
..
Universal Simulator algorithm
Communicating with models
Navigating model structure ..
Plug-in structure .. .. .. ..

..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..

28
32
36

4.3. Scenario outputs


Chapter 5.
5.1.
5.2.
5.3.
5.4.
5.5.

.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..

Conductance model
Plant model
.. ..
Community model
Weather model
..
Running the model
Discussion
.. ..

..
..
..
..
..

..
..
..
..
..
..

Chapter 6. The INTERCOM model


6.1. Light absorption explained
6.2. Light absorption refactored

..
..
..
..
..
..

..
..
..
..
..
..

..
..
..
..
..
..

..
..
..
..
..
..

..
..
..
..
..
..

..
..
..
..
..
..

..
..
..
..
..
..

..
..
..
..
..
..

..
..
..
..
..
..

..
..
..
..
..
..

..
..
..
..
..
..

..
..
..
..
..
..

65

..
..
..
..
..
..

70
70
75
78
78
80

.. .. .. .. .. .. .. .. .. .. .. .. ..
.. .. .. .. .. .. .. .. .. .. .. .. ..
.. .. .. .. .. .. .. .. .. .. .. .. ..

82
82
93

.. .. .. .. .. .. .. ..
Chapter 7. Student projects
7.1. Lake oxygen model .. .. .. .. .. .. .. ..
7.1.1. Introduction
.. .. .. .. .. .. ..
7.1.2. Calculations
.. .. .. .. .. .. ..
7.1.3. Predicting NCP in Real Lakes
.. ..
7.1.4. Unit of output .. .. .. .. .. .. ..
7.1.5. Setting the stochastic sampling number
7.1.6. Plotting .. .. .. .. .. .. .. .. ..
7.1.7. Output from the model
.. .. .. ..
7.2. Microbial community model
.. .. .. .. ..
7.2.1. Introduction
.. .. .. .. .. .. ..
7.2.2. Population model .. .. .. .. .. ..
7.2.3. Population Growth
.. .. .. .. ..
7.2.4. Competition Model
.. .. .. .. ..
7.2.5. Reaction Models
.. .. .. .. .. ..
7.2.6. GeneralEffect Model .. .. .. .. ..
7.2.7. Community Model
.. .. .. .. ..

..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..

94
94
94
94
96
97
97
97
98
99
99
99
99
100
102
106
108

.. ..
Appendix A. Plug-ins Reference
A.1. awe plugin
.. .. .. .. ..
A.2. conductance plugin .. .. ..
A.3. dynamic_photosynthesis plugin
A.4. ecotox plugin
.. .. .. ..
A.5. intercom plugin .. .. .. ..
A.6. MicrobialCommunity plugin
A.7. mussel_bed plugin
.. .. ..

..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..

..
..
..
..
..
..
..
..

111
111
117
119
120
124
132
137

iv

.. .. .. ..
.. .. .. ..
.. .. .. ..
.. .. ..
.. .. .. ..
.. .. .. ..
.. .. .. ..
.. .. .. ..

..
..
..
..
..
..
..
..

A.8. rvf plugin


.. .. ..
A.9. seed_emergence plugin
A.10. strawberry plugin
..
A.11. UniSim plugin .. ..
A.12. vg plugin
.. .. ..

..
..
..
..
..

141
143
144
145
162

.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..

181

.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..

183

References
Index

..
..
..
..
..

..
..
..
..
..

..
..
..
..
..

..
..
..
..
..

..
..
..
..
..

..
..
..
..
..

..
..
..
..
..

..
..
..
..
..

..
..
..
..
..

..
..
..
..
..

..
..
..
..
..

..
..
..
..
..

..
..
..
..
..

Chapter 1. Installation
This chapter takes you through the steps of downloading and installing Universal Simulator from
Internet and running your first simulations with Universal Simulator.
1.1. Installing Universal Simulator
First you must install the necessary software. Download the Universal Simulator installation file
from www.ecolmod.org. Execute this installation file and accept all default suggestions. After
installation you should be able to find the flying squirrel icon of Universal Simulator among
your programs.
Universal Simulator is installed in a folder inside your standard folder for programs, for
example C:/Program Files/UniSim-1-37, where 1-37, or something similar, refers to
the version of Universal Simulator. If different versions of Universal Simulator are installed, they
will simply occupy different folders and will not interfere with each other.
Inside

the

Universal

Simulator

program

folder,

for

example

C:/Program Files/UniSim-1-37, there will be a folder with the GraphViz program which

is used by Universal Simulator to construct model diagrams.


Another folder with the same name will have been created in your standard documents
folder, for example C:/Users/Nho/Documents/UniSim-1-37. This folder contains a
recipes folder with recipes for existing models, an output folder for generated simulation
output and a temp folder for temporary files generated during simulation. The easiest way to
navigate to these folders is to run Universal Simulator and via its File menu select Locations.
Here you can see (and change, if you want) the location of these and other folders used by
Universal Simulator. For instance, you can re-direct simulation output to some other folder.
Currently, File|Locations does not function intuitively: If you want to change the location
of a standard folder, you must click on a file (any file) inside the new folder location, rather than
clicking the new folder location itself. This will be fixed
1.2. Running simulations
Now is a good time to test your installation. First, start Universal Simulator. Open one of the simulation recipes, for example ambrosia DK.xml, which is found in the recipes/ambrosia
folder. Use the File|Open menu.
Universal Simulator will read the recipe, which is stored as an XML file, and from that
construct a diagram which shows the hierarchial structure of models that makes up the recipe.
The diagram is actually constructed by GraphViz which is always installed together with
Universal Simulator.
You can inspect the XML code of the recipe through the Edit|Model menu. If nothing
happens then follow the steps explained in the Edit|Help menu and try again. If you want to

Chapter 1. Installation

change parameter values, or what is shown as output (in plots on screen or in tab-separated text
files), you always do this in three steps:
1.

Edit the recipe in the XML file using a text or XML editor.

2.

In the editor, save the changed XML file.

3.

In Universal Simulator, open the XML file again using File|Open or File|Reopen.

After opening (or re-opening) an XML recipe file you can run the simulation with Simulation|Run. This will result in a display of output plots on the screen and maybe some files in the
output folder. If you forgot where the output folder is, you can check the File|Locations menu.
Instructions on how to read and edit XML recipe files can be found in the next chapter.

Chapter 2. Writing recipes


Universal Simulator recipes have much in common with recipes used in the kitchen. They
contain a list of models (ingredients), parameter values (measures), and how the models should
be connected (cooking instructions). Universal Simulator recipes are formulated as XML files
as explained below. A general introduction to XML can easily be found on Internet and is not
included here. First the basic recipe elements are described (2.1-2.7). Then follow examples
showing typical applications (2.8.1-2.8.2). Finally, an advanced section describes how to write
recipes with many (hundreds or thousands) similar models (2.9).
Note: The upcoming major revision of Universal Simulator will offer a more intuitive and
flexible input language, in addition to XML.
2.1. Recipe structure and context
When you start the Universal Simulator program, it first creates a simulation environment inside
the computers memory. The simulation environment is then equipped with a library of models
loaded from the available plug-in files. Now the simulation environment is ready to receive
recipes from the user.

When the user provides a recipe (an XML file selected through the File|Open menu), Universal
Simulator creates live versions of the models listed in the recipe, as objects living in the
3

Chapter 2. Writing recipes

simulation environment. The recipe specifies, by name and type, which models will take part
in the simulation and with which parameter values. To create the live models, the simulation
environment finds their code in the plug-in libraries. Some recipes may specify additional input,
such as weather data, provided as text file records.
When the user selects Simulation|Run on the menu, all the model objects created in the
simulation environment go into gear, each carrying out its specific behaviour (or logic,
if you prefer). Interaction with other model objects present in the simulation environment is
usually an important part of model behaviour. This allows, for example, leaf models to access
daily irradiation readings from a weather model, and predator models to feed on prey models.
Finally, when the simulations ends (as determined by the recipe, or when the user interrupts the
simulation), output is produced from the simulation environment, in terms of plots on the screen
and records in text files. Which output to produce is also described in the recipe.
The recipe is written in a much reduced subset of the XML language (see sections 2.1-2.7).
To edit XML files you can use a general purpose text editor or a dedicated XML editor. On MS
Windows, Notepad will do, but NotePad++ with its XML syntax highlighting is a better choice.
The most complete, free tool for XML editing seems to be Komodo Edit, which helps you even
more writing correct XML code.
The general structure of a recipe written in XML looks like this
<?xml version="1.0" encoding="ISO-8859-1"?>
<simulation name="Forest">
... one integrator ...
... one or more models ...
... one or more outputs ...
</simulation>

The root of the XML document must be a simulation element. You should give the simulation
a meaningfull name with the name attribute, in this case Forest. The simulation element
must contain in order: an integrator element, one or more model elements, and one or more
output elements. The integrator and model elements may hold additional model elements
inside. In addition, integrator, model and output elements may hold parameter elements.
The trace element can only be used inside output elements.
Elements may be given various attributes, such as name above, to provide detailed information. The elements that can be used in recipes, their attributes and their meaning are all described
below. First, however, comes an explanation of parameter and variable references, because we
often need to refer to a parameter or variable from one place in the recipe to another.
2.2. References to parameters and variables
The logic of a model is not accessible from the recipe. It is behind closed doors, written in C++
not XML. Models, however, provide a public interface which allows outsiders (the recipe and
other models) to set their parameters and to query the current value of their parameters and
variables. Note, however, that only the model itself (in its C++ code) can change its variables.
The syntax for referring to a parameter and a variable is the same. You supply a model name,
that is unique within the recipe, followed by the name of the parameter or variable in brackets.

2.2. References to parameters and variables

Here is a reference to the parameter or variable named lossRate inside the mass model:
mass[lossRate]

If mass is not unique inside the recipe, i.e. more than one model has the name mass, then you
must nail it down more precisely by providing its location. For instance, if you have a mass
model inside both a larva and a pupa model, you can refer to the latter by writing
pupa/mass[lossRate]

You can provide as a long a path as needed to make the reference unique:
drosophila/pupa/mass[lossRate]

All the examples above are examples of references. They can be used in the ref attribute of
parameter (2.3) and trace (2.7) elements.
A common usage of references is when several parameters logically must have the same
value, or when the parameter of one model is referring to the current value of a state variable
in another model. This example demonstrates this and also shows how to make use of relative
references, which are refences starting with one or two periods:
<model name="colony">
<model name="egg" type="Vespa::Egg">
<parameter name="newEggs" ref="../queen[eggsLaid"/>
<parameter name="newFertilisedEggs" ref=".[newEggs]"/>
<model name="mass" type="UniSim::Stage">
<parameter name="duration" value="2"/>
<parameter name="k" value="30"/>
</model>
<model name="number" type="UniSim::Stage">
<parameter name="duration" ref="../mass[duration]"/>
<parameter name="k" ref="../mass[k]"/>
</model>
</model>
<model name="queen" type="Vespa::Queen">
</model>
</model>

Here, the parameter newEggs is referring to the eggsLaid variable, which is maintained by
the model named queen. The double-period notation means, go one step up, in the hierarchy. In
this case to the colony model. Thus one double-period (../) takes you to a sibling model, two
(../../) to an uncle model and so forth.
The single-period (./) refers to the element itself. Hence, newFertilisedEggs will take
on the same value as the newEggs parameter in the same model.
The value of parameters duration and k are fixed in the mass model. Because they

Chapter 2. Writing recipes

must have the same values in the number model, the number model defines its parameters by
reference to the mass model. Note that references may refer to models anywhere, upwards or
downwards, in the recipe.
2.3. Parameter elements
The parameter element is used to set the value of a parameter. Here the k parameter is set to
the value 30:
<parameter name="k" value="30"/>

Note the XML syntax: Since a parameter element never holds another element inside, it
will always end with a slash (/) before the closing sharp parenthesis (>). The format of the
parameters value attribute depends on the type of the parameter:
Parameter type

Examples

Integer

-11, 0, 30

Floating point

-2.4, 1e6

String

paris_1919.txt

Boolean

true, false, yes, no

Date

18/8/2011, 2011/8/18

Time

21:48:10, 9:13

Dates follow the European (dd/mm/yyyy) or international (yyyy/mm/dd) convention. Since year
must be given with four digits, it is clear which convention is meant. Time of day can be given
with (hh:mm:ss) or without seconds (hh:mm).
The parameters available for each model can be looked up in the Plug-ins Reference. For
example, if you look up the k parameter of the Stage model in the UniSim plug-in (page 157),
you find both an explanation of its use and its default value. All models come with default values
for their parameters. Unless you change the parameter value in the recipe, the parameter will keep
its default value.
If you use the ref attribute instead of the value attribute, the parameter value will be
retrieved from another parameter or a variable. For example:
<parameter name="mortality" ref="herbicide[effect]"/>

In this example, you cannot tell whether effect in the model named herbicide is a parameter
or a variable but the result will be the same: mortality will take on the current value of
effect.
2.4. The integrator element
An integrator element should always be the first element inside the simulation element,
which makes up the outermost element, also called the root element. Moreover there can only

2.4. The integrator element

be one integrator element. The integrator is, in fact, just a model with a special role: it
determines for how may time steps the simulation should be running. For example,
<integrator type="UniSim::Steps">
<parameter name="maxSteps" value="365"/>
</integrator>

The type attribute is used to select the kind of integrator needed, here the Steps integrator,
which belongs to the Universal Simulator standard plug-in, named UniSim. Currently, this is
the only type of integrator available but one for sensitivity analysis is under development
(autumn 2013).
The duration of the simulation is given in terms of time steps. In this example, it has been
set to 365 which suggest that the length of a time step is one day. Time step length, however, is
not determined by the integrator. Most UniSim XML documents will have a calender model
(page 145) to manage the time scale.
If the simulation contains stochastic models, it is useful to run the simulation for several
iterations. This is specified by including a child model named runIterator:
<integrator type="UniSim::Steps">
<parameter name="maxSteps" value="365"/>
<model name="runIterator" type="UniSim::RunIteratorFixed">
<parameter name="numIterations" value="30"/>
</model>
</integrator>

In this case the model will be running for 30 iterations.


2.5. Model elements
Model elements define the configuration and settings of models in the simulation. A model
element can hold additional model elements inside to any depth thus forming a hierarchy of
models. Before a parent model is handled in the simulation, all its child models will be handled
in a recursive fashion. Sibling models will be handled in the order they appear in the recipe.
A model element has two attributes: name and type. One or both can be left out: name
defaults to anonymous and type defaults to UniSim::AnonymousModel. You should,
however, use the name attribute to give the model a meaningful name. The type attribute tells
which model, of those defined in the available plug-ins, is wanted. The two-parts type name
consists of the plug-in name (for example, UniSim) glued together by :: with the name of the
model class (for example, Stage). You can leave out the plug-in name but then you rely on, that
the model class name alone is (and will remain) unique among all plug-ins.
In this example, the model ChickenFlock holds three sibling models inside: time, eggs
and juveniles. The first will create a model of the type Days found in the UniSim plug-in.
The two others will create a model of type Stage, likewise found in the UniSim plug-in:
<model name="ChickenFlock">
<model name="time" type="UniSim:.Days"/>

Chapter 2. Writing recipes

<model name="eggs" type="UniSim::Stage">


<parameter name="duration" value="21"/>
</model>
<model name="juveniles" type="UniSim::Stage">
<parameter name="duration" value="140"/>
<parameter name="inflow" ref="../eggs[outflow]"/>
</model>
</model>

2.6. Additional input files


Some models may need access to additional input files, quite often column-oriented text files, as
used by the Records model in the UniSim plug-in. For example,
<model name="weather" type="UniSim::Weather">
<model name="records" type="UniSim::Records">
<parameter name="fileName" value="ngorongoro.txt"/>
</model>
</model>

The question is where the file ngorongoro.txt should be located? The Records model,
and other models that need text file input, will look for input files in various locations in the
following order:
1.

In the same folder as the recipe (the recipe folder)

2.

In a child folder of the recipe folder named input

3.

In the parent folder of the recipe folder

4.

In a child folder of that parent folder named input

5.

The last two steps are repeated for the grandparent folder and levels further up

This allows you to place input files where they can be shared by the relevant recipes.
2.7. Output and trace elements
The trace element is used only inside output elements where it used to define the model
parameter or variable to show in the output, for example, as a curve in a plot or a column in a
table. For output plots, the first trace defines the x-axis. The subsequent traces each define a
curve to display:
<output type="plot">
<parameter name="title" value ="Larva population dynamics"/>
<trace label="Day" ref="calendar[dayInYear]"/>

2.7. Output and trace elements

<trace label="Mass" ref="larva/mass[value]"/>


<trace label="Number" ref="larva/number[value]"/>
</output>

Here the type attribute has been set to plot to show this output as a plot on the screen, and the
ensuing parameter element sets the title of that plot. The label attribute of the first-coming
trace element (here, Day) is used to label the x-axis. The label attribute of subsequent trace
elements are used to label each curve. In this case, two curves labelled Mass and Number. The
ref attributes of the trace elements refers to variables (dayInYear, value and value) found
in the respective models (calendar, larva/mass and larva/number). Similar output, sent
to a text file named larva_pop_dyn.txt, and with three columns, labelled Day, Mass and
Number, would be produced by this code:
<output type="table">
<parameter name="fileName" value ="larva_pop_dyn.txt"/>
<trace label="Day" ref="calendar[dayInYear]"/>
<trace label="Mass" ref="larva/mass[value]"/>
<trace label="Number" ref="larva/number[value]"/>
</output>

Currently, only floating point variables and parameters (C++ type double) will be shown
correctly in output. If the ref attribute inside a trace cannot be resolved then that trace
element will silently by ignored. If less than two traces are found for a plot output or no traces
are found for a table output, an error message will appear.
Sometimes you may want to log-transform the y-axis or to set the minimum and maximum
value of the y-axis. The following example shows how to achieve this through the parameters
logy, ymin and ymax. You can use one or more of these parameters in any combination. Here,
they are used in concert:
<output type="plot">
<parameter name="title" value ="Larva population dynamics"/>
<parameter name="logy" value ="true"/>
<parameter name="ymin" value ="0.01"/>
<parameter name="ymax" value ="1e7"/>
<trace label="Day" ref="calendar[dayInYear]"/>
<trace label="Mass" ref="larva/mass[value]"/>
<trace label="Number" ref="larva/number[value]"/>
</output>

With these parameter values, the y-axis will be shown as log10-transformed values; zero-valued
y-values will be ignored. The minimum and maximum values always refer to the original scale.
You can scale an axis by using the multiplier or divisor attributes. Here time is
divided by 7 and mass is multiplied by 1000, before they are shown on the axes:
<output type="plot">
<parameter name="title" value ="Growth"/>
<trace label="Week" ref="calendar[totalTimeSteps]"
divisor=7/>

10

Chapter 2. Writing recipes


<trace label="Mass (g)" ref="larva/mass[value]"
multiplier=1000/>
</output>

Traces will be shown as lines by default but they can also be shown as symbols, or both line and
symbols. This is set by the type attribute of trace elements:
<output type="plot">
<parameter name="title" value ="Larva population dynamics"/>
<parameter name="logy" value ="true"/>
<parameter name="ymin" value ="0.01"/>
<parameter name="ymax" value ="1e7"/>
<trace label="Day" ref="calendar[dayInYear]"/>
<trace label="Number" ref="larva/number[k]" type="Line"/>
<trace label="Mass" ref="larva/mass[value]" type="Symbols"/>
<trace label="Number" ref="larva/number[value]" type="Both"/>
</output>

If you put a run iterator inside the integrator element (page 6) to run the simulation multiple
times, then output will be produced for every simulation run. For output elements of type plot,
additional output will simply be added producing a trace in the plot for every run. For output
elements of type table, the output from each run will go into a separate file; the files will be
numbered from 1 and onwards.
You can also request for additional output to summarise the result of multiple simulation
runs. For example, you might want to see a plot with the maximum population density, achieved
in each simulation run, plotted against some parameter. For this purpose you use summary plots.
To request summary output, you use the summary attribute of the trace element. For instance,
if you set a fecundity parameter to some random value before each simulation run, and you want
to see the simulated response in terms of maximum larval density, you could write
<output type="plot" >
<parameter name="title" value ="Max. larva mass"/>
<trace label="Fecundity" ref="adult[fecundity]"/>
<trace label="Mass" ref="larva/mass[value]" summary="max"/>
</output>

The default type of a trace element that holds a summary attribute is Symbol. So this code
will show a plot with as many symbols as the number of simulation runs. You can include more
than one summary trace in a plot, although in practice you most often have just one. You can also
use the summary attribute for trace elements to produce file output, i.e. for output elements
with type attribute set to table.
Different values for the summary attribute results in different values:

2.7. Output and trace elements

11

Summary

Meaning

max

Maximum value achieved during a simulation run

min

Minimum value achieved during a simulation run

avg

Average of all values achieved during a simulation run

sum

Sum of all values achieved during a simulation run

final

Final value achieved at the end of a simulation run

xAtMax

X-value (e.g. time) at which the maximum value was achieved during a
simulation run
X-value (e.g. time) at which the minimum value was achieved during a
simulation run

xAtMin

2.8. Applications
This section shows a selection of recipes for various applications. The recipes can all be found
in the recipes/unisim_explained/writing_recipes folder.
2.8.1. Application 1. Life stage sequence
If you work with stage-structured models of populations dynamics, you often need to string
life stages together, transferring individuals from one stage to the next as they develop. The
Stage model of the UniSim plug-in can be used to model the development in each individual
stage. To pass individuals on to the following stage, you use outflow (a variable of the Stage
model) and inflow (a parameter of the Stage model). Naturally, the outflow from a life stage
must be modelled and computed by the life stage itself, whereas the inflow to it is coming
from outside and is thus a parameter for the life stage. This recipe simulates the life stages of a
holometabolous insect:
<?xml version="1.0" encoding="ISO-8859-1"?>
<simulation name="insect">
<integrator type="UniSim::Steps">
<parameter name="maxSteps" value="100"/>
</integrator>
<model name="calendar" type="UniSim::Calendar">
</model>
<model name="weather" type="UniSim::Weather">
<model name="records" type="UniSim::Records">
<parameter name="fileName" value="Harlingen2008.txt"/>
</model>
</model>

12

Chapter 2. Writing recipes


<model name="insect">
<model name="egg">
<model name="time" type="UniSim::DayDegrees">
<parameter name="T0" value="4.5"/>
</model>
<model name="number" type="UniSim::Stage">
<parameter name="duration" value="41"/>
<parameter name="k" value="30"/>
<parameter name="initialInflow" value="100"/>
</model>
</model>
<model name="larva">
<model name="time" type="UniSim::DayDegrees">
<parameter name="T0" value="6.7"/>
</model>
<model name="number" type="UniSim::Stage">
<parameter name="duration" value="205"/>
<parameter name="k" value="30"/>
<parameter name="inflow"
ref="egg/number[outflow]"/>
</model>
</model>
<model name="pupa">
<model name="time" type="UniSim::DayDegrees">
<parameter name="T0" value="8.2"/>
</model>
<model name="number" type="UniSim::Stage">
<parameter name="duration" value="98"/>
<parameter name="k" value="30"/>
<parameter name="inflow"
ref="larva/number[outflow]"/>
</model>
</model>
<model name="adult">
<model name="time" type="UniSim::Days"/>
<model name="number" type="UniSim::Stage">
<parameter name="duration" value="30"/>
<parameter name="k" value="10"/>
<parameter name="inflow"
ref="pupa/number[outflow]"/>
</model>
</model>
</model>

2.8. Applications

13

<output type="plot">
<parameter name="title" value ="Harlingen weather log"/>
<trace label="Day" ref="calendar[totalTime]"/>
<trace label="Temperature" ref="weather[Tavg]"/>
</output>
<output type="plot">
<parameter name="title" value ="Insect numbers"/>
<trace label="Day" ref="calendar[totalTime]"/>
<trace label="Eggs" ref="egg/number[value]"/>
<trace label="Larvae" ref="larva/number[value]"/>
<trace label="Pupae" ref="pupa/number[value]"/>
<trace label="Adults" ref="adult/number[value]"/>
</output>
</simulation>

The integrator of the simulation tells it to run for 100 time steps. A Calendar model
keeps track of time, and a Weather model reads weather records from a weather log file. The
Stage models runs on different time scales, either days or day-degrees, as given by the sibling
model named time. The DayDegrees models will automatically search for a model named
weather and will pull daily temperature readings from the weather model. At the end, one plot
shows the daily temperature reading, and another plot shows the resulting insect development:

Chapter 2. Writing recipes

14

Note that several models simply acts as containers of other models: insect, egg, larva,
pupa and adult. These models add no behaviour of their own. Consequently, they have no
type attribute.
2.8.2. Application 2. Random parameter values
If some parameters are uncertain, or if you want to explore the sensitivity of the model to
variance in some parameters, you need to run the simulation repeatedly to assess the possible
outcomes. In this continuation of the example above, we want to explore the sensitivity of the
model to the lower temperature threshold for development of the three immature life stages:
<?xml version="1.0" encoding="ISO-8859-1"?>
<simulation name="SHBmodel">
<integrator type="Steps">
<parameter name="maxSteps" value="100"/>
<model name="runIterator" type="RunIteratorFixed">
<parameter name="numIterations" value="100"/>
</model>
</integrator>
<model name="calendar" type="Calendar">
</model>
<model name="weather" type="UniSim::Weather">
<model name="records" type="UniSim::Records">
<parameter name="fileName" value="Harlingen2008.txt"/>
</model>
</model>
<model name="random">
<model name="eggT0" type="UniSim::RandomUniform">
<parameter name="minValue" value="0"/>
<parameter name="maxValue" value="8"/>
</model>
<model name="larvaT0" type="UniSim::RandomUniform">
<parameter name="minValue" value="0"/>
<parameter name="maxValue" value="8"/>
</model>
<model name="pupaT0" type="UniSim::RandomUniform">
<parameter name="minValue" value="0"/>
<parameter name="maxValue" value="8"/>
</model>
</model>
<model name="insect">
<model name="egg">
<model name="time" type="UniSim::DayDegrees">

2.8. Applications
<parameter name="T0" ref="random/eggT0[value]"/>
</model>
<model name="number" type="UniSim::Stage">
<parameter name="duration" value="41"/>
<parameter name="k" value="30"/>
<parameter name="initialInflow" value="100"/>
</model>
</model>
<model name="larva">
<model name="time" type="UniSim::DayDegrees">
<parameter name="T0" ref="random/larvaT0[value]"/>
</model>
<model name="number" type="UniSim::Stage">
<parameter name="duration" value="205"/>
<parameter name="k" value="30"/>
<parameter name="inflow"
ref="egg/number[outflow]"/>
</model>
</model>
<model name="pupa">
<model name="time" type="UniSim::DayDegrees">
<parameter name="T0" ref="random/pupaT0[value]"/>
</model>
<model name="number" type="UniSim::Stage">
<parameter name="duration" value="98"/>
<parameter name="k" value="30"/>
<parameter name="inflow"
ref="larva/number[outflow]"/>
</model>
</model>
<model name="adult">
<model name="time" type="UniSim::Days"/>
<model name="number" type="UniSim::Stage">
<parameter name="duration" value="30"/>
<parameter name="k" value="10"/>
<parameter name="inflow"
ref="pupa/number[outflow]"/>
</model>
</model>
</model>
<output type="plot">
<parameter name="title" value ="Harlingen weather log"/>

15

Chapter 2. Writing recipes

16

<trace label="Day" ref="calendar[totalTime]"/>


<trace label="Temperature" ref="weather[Tavg]"/>
</output>
<output type="plot">
<parameter name="title" value ="Insect numbers"/>
<trace label="Day" ref="calendar[totalTime]"/>
<trace label="Eggs" ref="egg/number[value]"/>
<trace label="Larvae" ref="larva/number[value]"/>
<trace label="Pupae" ref="pupa/number[value]"/>
<trace label="Adults" ref="adult/number[value]"/>
</output>
<output type="plot">
<parameter name="title" value ="Sensitivity to egg
temperature threshold"/>
<trace label="Egg T0" ref="random/eggT0[value]"/>
<trace label="Peak adults day" ref="adult/number[value]"
summary="xAtMax"/>
</output>
<output type="plot">
<parameter name="title" value ="Sensitivity to larva
temperature threshold"/>
<trace label="Larva T0" ref="random/larvaT0[value]"/>
<trace label="Peak adults day" ref="adult/number[value]"
summary="xAtMax"/>
</output>
<output type="plot">
<parameter name="title" value ="Sensitivity to pupa
temperature threshold"/>
<trace label="Pupa T0" ref="random/pupaT0[value]"/>
<trace label="Peak adults day" ref="adult/number[value]"
summary="xAtMax"/>
</output>
</simulation>

We have added a model named runIterator inside the iterator element to achieve
repeated simulations. In this case, we have sete numIterations to achieve 100 repeated runs
of the model.
The random model is simply a container for three models producing random numbers.
The numbers are uniformly distributed between the minimum and maximum values, yielding
evenly distributed values in the range 0 to 8 from all three models. The RandomUniform model
produces a new random value immediately before each simulation run.

2.8. Applications

17

The parameter values for T0 which were previously set to fixed values by the value
attribute have now been set to refer to the pertinent random values. This has been effectuated by
replacing the value attribute with a ref attribute.
Three plots have been added at then end to show the sensitivity of the model to the lower
temperature thresholds of each of the three immature life stages. Each plot shows the value of the
temperature threshold on the x-axis and the time, at which the adult density peaked, on the y-axis.
These plots are constructed by using the summary attribute for the second trace element in
the plot. Here, the summary has been set to xAtMax. For other possible values of the summary
attribute, see page 10.
As can be seen in the plots, weather was the same all simulations (there is only one temperature curve), while the 100 sets of curves showing population numbers illustrate the variability
caused by the random temperature threshold values:

18

Chapter 2. Writing recipes

In conclusion, the model was most sensitive to variability in the lower temperature threshold
of the larvae, probably because they had the longest development time. Note that all three
parameters varied at the same time. If you want to see the effect of just one random threshold,
you must set the other two threshold to fixed values using the value attribute instead of the
ref attribute.
2.8.3. Application 3. Stage-structured population dynamics
In Application 1 we modelled only the phenology of one generation of an insect. To include
population dynamics, we must add insect reproduction to the recipe. We achieve this be
introducing a Stage model called eggsToBeLaid with a growthRate corresponding to the
life time fecundity of an adult:

2.8. Applications

19

<model name="adult">
<model name="time" type="UniSim::Days"/>
<model name="number" type="UniSim::Stage">
<parameter name="duration" value="30"/>
<parameter name="k" value="10"/>
<parameter name="inflow" ref="pupa/number[outflow]"/>
</model>
<model name="eggsToBeLaid" type="UniSim::Stage">
<parameter name="duration" value="10"/>
<parameter name="k" value="20"/>
<parameter name="inflow" ref="pupa/number[outflow]"/>
<parameter name="growthRate" value="60"/>
</model>
</model>

For every unit that flows into eggsToBelaid, 60 units will eventually flow out; These are the
eggs laid, and they are added as inflow to the egg stage:
<model name="egg">
<model name="time" type="UniSim::DayDegrees">
<parameter name="T0" value="4.5"/>
</model>
<model name="number" type="UniSim::Stage">
<parameter name="duration" value="41"/>
<parameter name="k" value="30"/>
<parameter name="initialInflow" value="100"/>
<parameter name="inflow"
ref="adult/eggsToBeLaid[outflow]"/>
</model>
</model>

With these settings, the adult will live 30 days on average, and eggs will be laid by females at
the age of 10 days on average. If the population has a sex ratio of 50% then a growthRate
of 60 means, that the life time fecundity of a female is 120 eggs. If the model is later extended
with a mortality factor on adults, one should remember to effectuate mortality on both stages,
number and eggsToBeLaid inside adult. In the simulation output, it is difficult to discern the
generations on a linear scale:

20

Chapter 2. Writing recipes

However, on a log-scale we can see that two new generations result from the original cohort
of 100 eggs:

2.8.4. Application 4. Stage-structured SEIR epidemics model


Models of epidemiology can become quite complex due to the many interactions between
populations. The complexity is exacerbated if the populations are stage-structured and, even
more, if vectors of the pathogen are involved. A standard conceptual framework is provided
by the SEIR family of models, in which individuals can go through the phases: S)usceptible,
E)xposed, I)nfectious and R)esistent. As an example we can imagine this system:

2.8. Applications

21

The host has two stages J)uvenile and A)dult but only the adult stage can become infected
and, after infection, eventually becomes resistent. The adults only die from old age; their
expected lifespan is unaffected by the disease. The juvenile stage receives inflows from all four
adult sub-populations, irrespective of which phase of infection they are in. It should be noted
that adults of the S, E and I sub-populations can leave their current either by ageing (they die) or

Chapter 2. Writing recipes

22

their phase (they proceed to the next step of infection). The disease is not promoted from mother
to child, hence all offspring enter as susceptible juveniles. Only adults can become infected, and
the infection rate depends on the density of infectious adult vectors.
The vector is an insect with four life stages: E)gg, L)arva, P)upa and A)dult. Only the adults
can be infected; the infection rate depends on the density of infectious adult hosts. In addition,
all eggs laid by infectious adults will eventually themselves become infectious adults, whereas
eggs laid by exposed adults go into the egg stage of the susceptible sub-population. Just as for
the host population, adult vectors in the S and E stages have two possible fates: either they die or
they pass on to the next phase of infection.
We will begin with the part of the recipe that describes the host model. For the susceptible
phase S we have
<model name="host">
<model name="time" type="UniSim::Days"/>
<model name="S">
<model name="juvenile" type="UniSim::Stage">
<parameter name="initialInflow" value="80"/>
<parameter name="inflow" ref="../toBeBorn[outflow]"/>
<parameter name="duration" value="1095"/>
<parameter name="k" value="30"/>
</model>
<model name="adult" type="UniSim::Stage">
<parameter name="initialInflow" value="50"/>
<parameter name="inflow" ref="../juvenile[outflow]"/>
<parameter name="duration" value="3650"/>
<parameter name="k" value="30"/>
<parameter name="phaseOutflowProportion" value="0.01"/>
</model>
<model name="toBeBorn" type="UniSim::Stage">
<parameter name="inflow" ref="../juvenile[outflow]"/>
<parameter name="duration" value="730"/>
<parameter name="k" value="30"/>
<parameter name="growthRate" value="2.5"/>
</model>
</model>
<...>
</model>

We apply the technique from the previous application (2.8.3) to model reproduction.We introduce
a Stage model called toBeBorn which takes the same inflow as the adult stage. In this case,
where adults in all phases produce juveniles in the susceptible phase, it simplifies matters: the
toBeBorn model is only needed here, as a sub-model of the susceptible phase S. Host development is measured in days, as set by the time model. The parameter values correspond to some

2.8. Applications

23

imaginary vertebrate species. For simplicity, the toBeBorn model is not shown in the figure.
The adult stage has a parameter which defines the proportion of the adults that will
bchanging phase in the next time step. The name of this parameter is phaseOutflowProportion. In a more complete version of the e model, this proportion would be dynamic, varying
with the attack rate of the infectious vector population. In this first version, it is kept simple as a
fixed rate of 1% per day.
The adult stage has two outflows, which can be accessed through the variables outflow
and phaseOutflow. In this case, outflow simply is the loss due to old age while the phaseOutflow must be taken up by the adult stage in the subsequent, exposed phase (E). To link the
flow between phases, the phaseInflow parameter is used, as seen in the subsequent phases of
the host model E, I and R:
<model name="E">
<model name="adult" type="UniSim::StageAndPhase">
<parameter name="duration" ref="../S/adult[duration]"/>
<parameter name="k" ref="../S/adult[k]"/>
<parameter name="timeStep" ref="../time[step]"/>
<parameter name="phaseInflow"
ref="../S/adult[phaseOutflow]"/>
<parameter name="phaseDuration" value="10"/>
<parameter name="phaseK" value="15"/>
<parameter name="phaseTimeStep" ref="../time[step]"/>
</model>
</model>
<model name="I">
<model name="adult" type="UniSim::StageAndPhase">
<parameter name="duration" ref="../S/adult[duration]"/>
<parameter name="k" ref="../S/adult[k]"/>
<parameter name="timeStep" ref="../time[step]"/>
<parameter name="phaseInflow"
ref="../E/adult[phaseOutflow]"/>
<parameter name="phaseDuration" value="20"/>
<parameter name="phaseK" value="15"/>
</model>
</model>
<model name="R">
<model name="adult" type="UniSim::Stage">
<parameter name="duration" ref="../S/adult[duration]"/>
<parameter name="k" ref="../S/adult[k]"/>
<parameter name="phaseInflow"
ref="../I/adult[phaseOutflow]"/>

Chapter 2. Writing recipes

24
</model>
</model>

There are several linkages between different models defined here. To start with the simple ones,
the parameters duration and k of the adult models in the E, I and R phases, all refer back to
the same parameters in the S phase. Thus adult ageing is not affected by the infection.
Next, the models for the E and I phases are of type StageAndPhase, instead of Stage. A
StageAndPhase model has two development processes going on simultaneously: development
by ageing (vertical arrows in the figure) and development to the next phase of the infection
(rightwards arrows in the figure). Both processes need parameters to characterise the average
duration and dispersion of development time: duration and k for life stage development, and
phaseDuration and phaseK for phase development.
Parameters specifying the inflow and the duration of the time step, are supplied as
parameters, inflow and timeStep, and phaseInflow and phaseTimeStep, respectively.
Note, that for models of Stage type, we did not specify the timeStep parameter. This is not
necessary because Stage models automatically look up the nearest model called time and pulls
the step variable from that. But for StageAndPhase model we have to specify the time step
parameter for both directions of development.
In the final phase (R), the adult model again is a Stage model because development only
occurs in one direction, which is ageing.
The vector model is more complicated than the host model, because it has more life
stages. In the host model, we introduced a toBeBorn stage to model reproduction. Likewise,
we introduce a toBeLaid stage in each of the three vector phases. The recipe for the susceptible phase is simply a series of Stage models, one for each life stage and one for the toBeLaid stage:
<model name="vector">
<model name="time" type="UniSim::DayDegrees">
<parameter name="T0" value="8"/>
</model>
<model name="S">
<model name="egg" type="UniSim::Stage">
<model name="inflows" type="UniSim::Sum">
<parameter name="toAdd" value="(../toBeBorn[outflow]
vector/E/toBeBorn[outflow])"/>
</model>
<parameter name="initialInflow" value="100"/>
<parameter name="inflow" ref="./inflows[value]"/>
<parameter name="duration" value="50"/>
<parameter name="k" value="30"/>
</model>
<model name="larva" type="UniSim::Stage">
<parameter name="inflow" ref="../egg[outflow]"/>
<parameter name="duration" value="250"/>
<parameter name="k" value="30"/>

2.8. Applications

25

</model>
<model name="pupa" type="UniSim::Stage">
<parameter name="inflow" ref="../larva[outflow]"/>
<parameter name="duration" value="80"/>
<parameter name="k" value="30"/>
</model>
<model name="adult" type="UniSim::Stage">
<parameter name="inflow" ref="../pupa[outflow]"/>
<parameter name="duration" value="100"/>
<parameter name="k" value="30"/>
<parameter name="phaseOutflowProportion" value="0.04"/>
</model>
<model name="toBeLaid" type="UniSim::Stage">
<parameter name="inflow" ref="../pupa[outflow]"/>
<parameter name="duration" ref="../adult[duration]"/>
<parameter name="k" ref="../adult[k]"/>
<parameter name="growthRate" value="50"/>
<parameter name="phaseOutflowProportion"
ref="../adult[phaseOutflowProportion]"/>
</model>
</model>
<...>
</model>

Since the egg model takes input from two models, toBeLaid both in the S and E phase, we use
a Sum type model to add the outflows from these. A Sum model has just one parameter toAdd
which contains a list of references to add.
The other Stage models are standard in their parameter settings, except for the toBeBorn
stage for which we must remember to set the same phaseOutflowProportion as for the
adult stage. Biologically, we should think of the eggs to be laid as developing inside the adults.
Then it follows logically that adult and toBeBorn populations should walk hand in hand
through the phases of infection.
All vector stages run on a day-degree scale as set by the time model. The life history
parameters settings suggest that the vector is an invertebrate species, for example, a mosquito.
The phaseOutflowProportion has been set to a fixed value of 4% per day. In a complete
model this parameter would be dynamic depending on the attack rate of susceptible vectors on
infectious hosts.
The exposed phase of the vector only contains the adults. Hence we should expect a simple
recipe for that phase. However we must remember to include a toBeLaid stage:
<model name="E">
<model name="adult" type="UniSim::StageAndPhase">
<parameter name="duration" ref="../S/adult[duration]"/>
<parameter name="k" ref="../S/adult[k]"/>
<parameter name="timeStep" ref="vector/time[step]"/>

26

Chapter 2. Writing recipes


<parameter name="phaseInflow"
ref="../S/adult[phaseOutflow]"/>
<parameter name="phaseDuration" value="20"/>
<parameter name="phaseK" value="15"/>
<parameter name="phaseTimeStep" ref="vector/time[step]"/>
</model>
<model name="toBeLaid" type="UniSim::StageAndPhase">
<parameter name="duration" ref="../S/toBeLaid[duration]"/>
<parameter name="k" ref="../S/toBeLaid[k]"/>
<parameter name="growthRate"
ref="../S/toBeLaid[growthRate]"/>
<parameter name="timeStep" ref="vector/time[step]"/>
<parameter name="phaseInflow"
ref="../S/toBeLaid[phaseOutflow]"/>
<parameter name="phaseDuration"
ref="../adult[phaseDuration]"/>
<parameter name="phaseK" ref="../adult[phaseK]"/>
<parameter name="phaseTimeStep" ref="vector/time[step]"/>
</model>
</model>

Both of the models in the exposed phase undergo development in two directions. Followingly
they are modelled as StageAndPhase models. It is worth noticing that the only parameters
particular to the exposed phase are phaseDuration (20) and phaseK (15). Moreover, as adults
and eggs to be laid go hand in hand, the two parameters are set to the same values in the adult
and toBeLaid models.
The remaining parameters are set by reference to those parameters, that they are logically
equivalent to. There are no inflows set by the inflow parameter but the phaseInflow parameter links both the adult and toBeLaid models to their similar models in the susceptible phase.
In the final, infectious phase there is only one direction of development. So, all life stage
models are back to the Stage type:
<model name="I">
<model name="egg" type="UniSim::Stage">
<parameter name="inflow" ref="../toBeLaid[outflow]"/>
<parameter name="duration" ref="vector/S/egg[duration]"/>
<parameter name="k" ref="vector/S/egg[k]"/>
</model>
<model name="larva" type="UniSim::Stage">
<parameter name="inflow" ref="../egg[outflow]"/>
<parameter name="duration"
ref="vector/S/larva[duration]"/>
<parameter name="k" ref="vector/S/larva[k]"/>
</model>

2.8. Applications

27

<model name="pupa" type="UniSim::Stage">


<parameter name="inflow" ref="../larva[outflow]"/>
<parameter name="duration" ref="vector/S/pupa[duration]"/>
<parameter name="k" ref="vector/S/pupa[k]"/>
</model>
<model name="adult" type="UniSim::Stage">
<parameter name="inflow" ref="../pupa[outflow]"/>
<parameter name="duration"
ref="vector/S/adult[duration]"/>
<parameter name="k" ref="vector/S/adult[k]"/>
<parameter name="phaseInflow"
ref="vector/E/adult[phaseOutflow]"/>
</model>
<model name="toBeLaid" type="UniSim::Stage">
<parameter name="inflow" ref="../pupa[outflow]"/>
<parameter name="duration"
ref="vector/S/toBeLaid[duration]"/>
<parameter name="k" ref="vector/S/toBeLaid[k]"/>
<parameter name="growthRate"
ref="vector/S/toBeLaid[growthRate]"/>
<parameter name="phaseInflow"
ref="vector/E/toBeLaid[phaseOutflow]"/>
</model>
</model>

The recipe is straightforward, except for all the references that must be set to reflect the correct
biological bindings. No new parameter values are needed.
When a recipe contains many information flows between models, it is always a good idea to
test that the plumbing is correct. In this case, the initial inflow marked a in the figure should equal
the sum of the two outflows marked b and c, provided that there is no reproduction. To check this
assertion we make a special version of the recipe, in which no reproduction occurs. All in all, we
expect these balance equations to hold (with reference to the figure): a=b+c, c=d+e, e=f . This
is what we see for 1 years simulation:

28

Chapter 2. Writing recipes

The final values of flows a-f can be read off the plot by clicking the curves but they can
also be retrieved from the output file produced by the recipe. We find a=100, b=65.17, c=34.82,
d=5.71, e=29.11, f =29.11 from which we confirm that all balances hold as expected.
Next we can add reproduction back into the recipe and follow the dynamics of hosts and
vectors. We should remember though that the epidemics are still not modelled realistically, since
we still hold the infection rates of susceptible hosts and susceptible vectors at fixed values (1 and
4% per day, respectively).The host population shows a steady increase in the resistent population,
while the first juveniles of the next generation are on their way (as the toBeborn population):

The initial 100 eggs of the vector population resulted in two generations of adult vectors:

The population of exposed vectors continues to increase at the end of the year, but this is
an artifact of the model: the rate of susceptible adults turning exposed is 4% per day, while the
development rate of exposed adults into infectious runs on a day-degree scale, that by the end of
the year has come to a halt due to falling temperatures. Clearly, the infection rates should not be
fixed but rely on some biologically realistic model.
2.8.5. Application 5. Functional response: predation, parasitisation, infection
In Universal Simulator, the FunctionalResponseGB model implements the GutierrezBaumgrtner functional response model:

2.8. Applications

29

X
S = D 1 exp
D

This model works with the concepts demand (D), supply (S) and ressource apparancy () with
populations denoted as consumer/predator/parasite/patogen (Y) and resource/prey/host (X). For
a predator-prey system with a time step of one day, the demand and supply could be modelled
in units of, for example, biomass per m2 per day. The demand will be time-varying, as it will
increase with the density of the predator population. For a predator working on a day-degree
scale, the demand will moreover increase with temperature. The demand is often calculated as
D = dY t
where d is the per capita demand rate per time unit, Y is the predator density and t is the time
step measured on the predator time scale.
Demand is a possibly multi-layered concept. If a predator needs a certain input for
growth, it will need to eat more than this to satisfy that demand, because it also spends energy on metabolism. Moreover, it needs to kill more prey than the total demand for growth and
metabolism: Part of the prey will go unutilised, either because it was never eaten (for example,
the skeleton), or because it was quickly ejected (for example, the honey dew excreted by aphids).
One should be aware of these demands at different physiological levels when using the functional
response model.
The demand puts an upper limit on the supply rate; the predator population cannot acquire
more than it needs. How close the supply (S) gets to the demand (D) depends on prey density
and the search efficiency of the predator. In the (G-B) functional response, this is parameterised
as the apparancy () of the prey, a number between zero and one (inclusive). Search behaviour
is difficult to measure, and it makes sense that this difficult aspect is translated into a single
parameter, which usually must be determined by calibration (i.e. fitting of model output to
observed field data).
In

this

example

(the

recipe

can
be
found
in
the
recipes/unisim_explained/writing_recipes folder), apparancy has been set to = 0
.8 and demand to D = 10 with prey density in the range X = 0..100:

Egestion and base metabolic rate have both been set to zero. Supply can be seen to reach

30

Chapter 2. Writing recipes

the demand asymptotically. Next, we set the egestion ratio to 20%:

The supply curve now increases less steeply with increasing prey density, because the
predator needs to kill more to obtain the same net supply. In a final step we add basic metabolic
rate as a constant with the value 1. Again, we see the supply curve slacken; an even higher prey
density is needed to obtain the same net supply::

The allocation of the acquired net supply lies outside the logic of the FunctionalResponseGB model. Further losses my incur, for example the cost of growth respiration (i.e., conversion costs of food intake).
Energy budget considerations can have a dramatic effect on the predicted number of prey
killed. The three models above all have an asymptote of net supply equal to 10, but by including
losses first to egestion and then to basic metabolism, the potential number of prey killed rises:

2.8. Applications

31

In this last graph the variable totalSupply is shown, whereas the previous three graphs
showed the supply, egestion and respiration variables of the FunctionalResponseGB model. Hence supply denotes the net supply, which is the totalSupply corrected for
egestion and respiration.
A final variable that is commonly calculated is the supply/demand ratio. The example shows
how this is decreasing when losses to egestion and base respiration are included:

The above description fits a functional response in a predator-prey or consumer-resource


system. With some consideration it can also be used for a parasitoid-host, parasite-host or
patogen-host system. The demand will then be defined by the optimal egg-laying rate of the
parasitoid or the maximal contact rate between infectuous hosts (or vectors) and susceptible
hosts. The supply, meaning the number of parasitoid eggs laid or the number of host-vector
contacts achieved, follow the same logic as for predators: it is limited by the density of the host
and the search efficiency of the parasitoid or vector.
Some parasitoids will lay one egg only per host, in that sense they function like predators,
which can only eat each prey once. However, some parasitoids will lay more than one egg per
host. For diseases it may be inconsequential whether one or more contacts with the pathogen
occured, although one could imagine a dose-response relationship for some pathogens.
Therefore we need to compute not only the number of attacks (eggs laid or vector contacts)
but also how these are distributed in the host population: 1, 2, 3, .. attacks. If we assume that
attacks occur at random in the host population, they will follow a Poison distribution defined by

Chapter 2. Writing recipes

32
the average number of attacks per host,
m = S
X

Commonly we would be interested in knowing the number of hosts attacked (X a), which we
can infer from the zero term of the Poisson distribution,
X a = X 1 exp( m)

The FunctionalResponseGB model gives access to these variables as attacksPerHost,


numHostsAttacked and propHostsAttacked. If, for example, 20 hosts are attacked 8
times (X = 20, S = 8), we get attacksPerHost = 8/20 = 0.4, numHostsAttacked = 20(1 exp(0.4)) = 6.6 and propHostsAttacked = 6.6/20 = 0.33.
2.8.6. Application 6. Multi-way functional response
The Predation model solves the problem when many predators feed upon many prey. For
example, we could imagine a scenario with leopard (Y1) and lion (Y2) feeding on gazella (X 1), gnu
(X 2) and zebra (X 3). The hunger of the predators would be defined by their demand (Dj), and the
search rates defined by a matrix addressing all predator(j)-prey(i) combinations (ij). We could
let lions eat a leapard now and them by including leopards as both predator and prey:

Prey apparancy
Predator

Demand

Gazella

Gnu

Zebra

Leopard

Leopard

12

0.05

0.001

0.02

Lion

18

0.08

0.01

0.04

0.0005

Prey density
100

200

150

The single zero occuring among the apparancy values implies that leopards are not cannibalistic.
Whatever applies in nature, the Predation model would accept cannibalism too.
application_6_predation.xml
The
recipe
(found
in
the
recipes/unisim_explained/writing_recipes folder) calculates the predation rates
that would result from the table above. However, in this recipe only the the Predation model
is truely functional, whereas the five animal models are just mockups with fixed values for Density and Demand. In a realistic model Density and Demand would be time-varying. Here, the

model keeps calculating the same predation rates, without any kills being effectuated:
<simulation version="1.0">
<integrator type="Steps">
<parameter name="maxSteps" value="10"/>
</integrator>

2.8. Applications

33

<model name="calendar" type="unisim::Calendar">


</model>
<model name="Gazella" type="UniSim::Fixed">
<parameter name="parameters" value="((Density 100.0)) "/>
</model>
<model name="Gnu" type="UniSim::Fixed">
<parameter name="parameters" value="((Density 200.0)) "/>
</model>
<model name="Zebra" type="UniSim::Fixed">
<parameter name="parameters" value="((Density 150.0)) "/>
</model>
<model name="Leopard" type="UniSim::Fixed">
<parameter name="parameters" value="((Density 5.0) (Demand
12.0)) "/>
</model>
<model name="Lion" type="UniSim::Fixed">
<parameter name="parameters" value="((Demand 18.0)) "/>
</model>
<model name="Predation" type="UniSim::Predation">
<parameter name="apparancyMatrix"
value="application_6_predation_apparancies.txt"/>
</model>
<output type="plot">
<parameter name="title" value="Predation.prn"/>
<trace label="TotalTimeSteps"
ref="calendar[totalTimeSteps]"/>
<trace label="Gazella" ref="Gazella[Density]"/>
<trace label="LionGazella" ref="predation[Lion-Gazella]"/>
<trace label="LionLeopard" ref="predation[Lion-Leopard]"/>
<trace label="LeopardGazella"
ref="predation[Leopard-Gazella]"/>
<trace label="LeopardSupply"
ref="predation[Leopard-Supply]"/>
<trace label="LeopardLoss" ref="predation[Leopard-Loss]"/>
<trace label="GnuLoss" ref="predation[Gnu-Loss]"/>
</output>

The apparancy parameters are provided as the parameter apparancyMatrix to the Predation
model as a tab-separated, text file with the following format:

Chapter 2. Writing recipes

34

Leopard[demand]
Lion[demand]

Gazella[density]

Gnu[density]

Zebra[density]

Leopard[density]

0.05

0.001

0.02

0.08

0.01

0.04

0.0005

The first column contains references to predator demands. A column label is optional and
inconsequential. The following columns all bear column headings that are references to the
variables holding the density of prey. Both prey densities and predator demands can obviously
be time-varying, so the model needs references to keep track of them. The entries in the main
body of the table shows the apparancy values for each predator-prey combination. The apparancy
values are constant.
With the apparancy matrix above and the prey densities shown in the earlier table, the
Predation model will yield these predation rates when updated:

Gazella

Gnu

Zebra

Leopard

Supply

Leopard

3.410

0.169

2.241

0.000

5.821

Lion

5.000

1.491

3.990

0.002

10.481

Loss

8.410

1.660

6.230

0.002

16.302

You can reproduce these numbers by running the application_6_predation.xml recipe.


As you can see the leopard population got a total supply of 5.821 compared to its demand of 12,
and the lion population got a supply of 10.481 compared to its demand of 18. The distribution of
predation rates among prey populations reflects both their relative population densities and their
apparancy values (the apparancy matrix above). In a real simulation these predation rates would
be applied as mortality rates on the prey populations and as a ressource input to the predator
populations. For this purpose different models would need to pick up the relevant predations rates
from the above table.
The predation rates are not actually written to a table, as it would become quite tedious to
read the predation rates from a file in every time step. Instead the Predation model creates
variables which can be used to pull values from the table above. These variables are of the form
predator-prey. If you have named the Predation model predation, you can refer to, for example, predation[Lion-Gazella] (equal to 5.000) but not predation[Gazella-Lion].
In addition, there are variables for the totals, named Supply and Loss, for example, predation[Lion-Supply] (equal to 10.481) and predation[Gazella-Loss] (equal to 8.410).
For models that appear both as predator and prey, both totals would be present, for example,
predation[Leopard-Supply] (equal to 5.821) and predation[Leopard-Loss] (equal
to 0.002).
If

model

reference

in

the

apparancy

matrix

contains

slashes,

as

in

Lion/female[demand] and Lion/female[demand], these are replaced by underscores in


the variable names of the Predation model. This is because slashes are not allowed in variable

2.8. Applications

35

names. So, the variables names would be for instance, predation[Lion_female-Gazella]


and predation[Lion_male-Gazella].
Multiway parasitisation and infection are modelled by the Infection model, which also
has an apparancyMatrix parameter. We can imagine three butterfly species being infected by
two species of parasitoids, a fly and a wasp. To ease comparison with the Predation model,
the matrix is the same, except for the names:

Host apparancy
Parasitoid

Demand

io

levana

paphia

io/fly

Fly

12

0.05

0.001

0.02

Wasp

18

0.08

0.01

0.04

0.0005

Host density
100

200

150

For the Infection model, the demand denotes the potential egg-laying rate of a parasitoid, or
for a vector, the potential rate of encounters between vector and host. The number of interactions
can grow dramatically as parasitoids, vectors and hosts are added to the system, because host
populations may need to be split into different sub-populations. Thus sub-populations may be
needed to keep separate, parasitised and non-parasitised hosts, and different phases of infection
(susceptible, exposed, infectious and recovered). Here we include only one such sub-population
named io/fly which denotes io butterflies parasitised by the fly. According to the apparancy
matrix above, fly-parasitised io cannot be attacked by the fly again, but it can be attacked by the
wasp (at a very low rate).
The application_6_infection.xml recipe yields this simulation output:

io

levana

paphia

io/fly

Attacks

Fly

3.500

0.170

2.272

0.000

5.941

Wasp

5.088

1.491

4.020

0.002

10.601

Attacks

8.588

1.661

6.291

0.002

16.542

The outcome of the Infection model is shown here in terms of the number of attacks. If you
compare this outcome with that of the Predation model, you will find that the Infection
model yields slightly higher numbers. This is because infections can overlap; one host can
receive more than one parasitoid egg or encounter more than vector during a time step. For many
purposes you would also be interested in the number of hosts attacked, in addition to the number
of attacks. The number of hosts attacked will be slightly smaller than the number of attacks,
because a few hosts by chance will have been attacked more than once:

Chapter 2. Writing recipes

36
io

levana

paphia

io/fly

Attacked

Fly

3.439

0.170

2.255

0.000

5.863

Wasp

4.961

1.486

3.966

0.002

10.415

Attacked

8.400

1.655

6.221

0.002

16.278

These rates, denoting the number of hosts attacked, are inbetween those of predation and number
of attacks, as you can verify by comparing the three respective tables above. The last table still
contains some overlap, as hosts can be attacked by both fly and wasp. For instance, for the io
population the 3.500 attacks (eggs laid) by the fly population led to 3.439 io indivuals being
attacked (having 1 on or more parasitoid eggs inside), and the 5.088 attacks (eggs laid) by the
wasp population led to 4.961 individuals being attacked. Of those individuals attacked some
would have been attacked coincidentally by both fly and wasp. How to sort this out depends on
the biology of the involved species.
The Infection model computes more variables than the Predation model. These variables are named parasitoid-host or vector-host. For the number of attacks, attacks is appended to the name, for example, infection[Fly-paphia-attacks] (equal to 2.272) or infection[Wasp-io_fly-attacks] (equal to 0.002). As noted for the Predation model,
slashes (/) are not allowed in variable names and will be replaced by underscores by the Infection model; here we must write io_fly, instead of io/fly. For the number of hosts attacked, attacked is appended to the name, for example infection[Fly-paphia-attacked]
(equal to 2.255). The totals are named by just the parasitoid, vector or host followed by attacks or attacked, for example infection[Wasp-attacks] (equal to 10.601) or infection[paphia-attacked] (equal to 6.221).
2.9. Advanced handling of many models
Suppose you need several instances of the same model; they have the exact same settings for
parameters and any child models. Then you use the instances attribute:
<model name="generation" type="Insect" instances="3">
...
</model>

I this example you would get three instance of the Insect model. They would be named
generation(1), generation(2) and generation(3). You would need these names, for
instance, when referring to the models in an output element.
In other cases you may need several instances but with different parameter values. Maybe
you have got hundreds of farms each represented by a Farm model. Specifying all these in an
XML recipe would be very cumbersome. Just imagine the first four out of many hundreds:
<model name="landscape" type="My::Landscape">
<model name="A" type="My::Farm">
<parameter name="FarmType" value="Cattle"/>;
<parameter name="SoilType" value="Sand"/>;

2.9. Advanced handling of many models

37

<parameter name="Economy" value="Business"/>;


</model>
<model name="B" type="My::Farm">
<parameter name="FarmType" value="Cattle"/>;
<parameter name="SoilType" value="Sand"/>;
<parameter name="Economy" value="Leisure"/>;
</model>
<model name="C" type="My::Farm">
<parameter name="FarmType" value="Plant"/>;
<parameter name="SoilType" value="Sand"/>;
<parameter name="Economy" value="Business"/>;
</model>
<model name="D" type="My::Farm">
<parameter name="FarmType" value="Plant"/>;
<parameter name="SoilType" value="Clay"/>;
<parameter name="Economy" value="Business"/>;
</model>
</model>

In this example the plug-in called My defines models of type Landscape and Farm. In the above,
one Landscape model with four Farm models inside is created.
Usually such information would stem from a spreadsheet or database. If you export the
information into a tab-separated text file then you can get the same result as above much more
conveniently, irrespectively of the number of models you want to create:
<model name="landscape" type="My::Landscape">
<model type="My::Farm" table="farms.txt">
</model>
</model>

Where the farms.txt file has this content (with tab-seperated columns):

*My::Farm

FarmType

SoilType

Economy

Cattle

Sand

Business

Cattle

Sand

Leisure

Plant

Sand

Business

Plant

Clay

Business

Note that the parameter values are taken from the columns, identified by the column heading.
These column headings function like the usual name attribute. The name of the model itself is
taken from the column with a heading that matches the models type, in this case My::Farm.
To mark this special functionality it must be preceeded by an asterisc *My::Farm.
The next level of complexity arises once we realize that the farms differ in their acreage of

Chapter 2. Writing recipes

38

different crops, and we need a Crop model for each of these on each farm. Could we somehow
use the same syntax?
<model name="landscape" type="My::Landscape">
<model type="My::Farm" table="farms.txt">
<model type="My::Crop" table="crops_on_farms.txt">
</model>
</model>
</model>

That certainly does look neat. Now, the crops_on_farms.txt file must hold columns both for
the farm and the crop to specify the parameters for each farm x crop combination:

*My::Farm

*My::Crop

Area

Oats

10

SBarley

30

Oats

20

WBarley

40

SBarley

15

WBarley

25

Oats

55

Here farms A and B each have two crops, farm C has none, and farm D has three. In this
example, the Crop model only has one parameter called Area. Or, if the Crop model holds more
parameters, they will keep their default value as defined in the C++ code for the Crop class.
You can re-apply this principle to any level. In this case, you could for example add a field
operations level telling the date when different operations were carried out in each crop on
each farm:
<model name="landscape" type="My::Landscape">
<model type="My::Farm" table="farms.txt">
<model type="My::Crop" table="crops_on_farms.txt">
<model type="My::Operation"
table="operations_on_crops_on_farms.txt"/>
</model>
</model>
</model>

With this input in operations_on_crops_on_farms.txt:

2.9. Advanced handling of many models

39

*My::Farm

*My::Crop

*My::Operation

Date

Oats

Sowing

20/4/2010

Oats

Harvest

15/8/2010

SBarley

Sowing

21/4/2010

SBarley

Harvest

16/8/2010

Oats

Sowing

22/4/2010

Oats

Harvest

17/8/2010

WBarley

Sowing

15/9/2009

WBarley

Spraying

1/10/2009

WBarley

Harvest

25/7/2010

SBarley

Sowing

23/4/2010

SBarley

Harvest

18/8/2010

WBarley

Sowing

16/9/2009

WBarley

Spraying

2/10/2009

WBarley

Harvest

26/7/2010

Oats

Sowing

24/4/2010

Oats

Harvest

19/8/2010

But now we realize this does not solve the problem completely, because when we look at the
Operation model it has two more parameters besides Date. These parameters are Cost and
IsOrganic. In fact, we have them in this table:

*My::Operation

Cost

IsOrganic

Sowing

100

yes

Harvest

350

yes

Spraying

20

no

It would be a bad design to duplicate these values into the table above but, of course, if all
these tables are maintained by database software that could be an option. However, we can also
formulate this more succinctly in the XML recipe:
<model name="landscape" type="My::Landscape">
<model type="My::Farm" table="farms.txt">
<model type="My::Crop" table="crops_on_farms.txt">
<model type="My::Operation"
table="operations_on_crops_on_farms.txt"/>
<parameter table="operations.txt"/>

Chapter 2. Writing recipes

40
</model>
</model>
</model>

One should take note of the two different functionalities of the table attribute exposed here.
When a table is attributed to a model element, one model instance will be created for each line
in the table; parameter values will be set from those given in the table columns. When a table
is attributed to a parameter element, it is simply used to look up parameter values for the parent
model. In this example, when an Operation instance with the name Harvest is created, then
its Cost parameter will be set to 350 and its IsOrganic parameter to yes.
If you need to build a model with a complex data structure like in this example, you should
not try to build it all at once. Start from the outermost level and work yourself inwards. You
should also notice that your C++ coding will look just the same whether you create models
and set parameters with the table attribute, or whether you use the much simpler method of
specifying each model and each parameter individually in the XML code. This is only natural.
Your C++ code should work the same, no matter how many objects of type Farm, Crop and
Operation are present in the simulation. You can find an example of C++ code implementing
Farm, Crop and Operation in src/plugins/test_models.
There are a few more possibilities to cover. Suppose you have the data on crop acreage
represented in cross-tabular format as in this file crops_area_on_farms.txt:

*My::Farm

Oats

SBarley

WBarley

10

30

20

40

55

15

25

This is also readable by Universal Simulator if you use the crosstab attribute in stead of the
table attribute. In addition you must supply the parameter name (Area, in this case) in the
parameter attribute:
<model name="landscape" type="My::Landscape">
<model type="My::Farm" table="farms.txt">
<model type="My::Crop" name="Area"
crosstab="crops_area_on_farms.txt">
</model>
</model>
</model>

Note that with this method all farms get the full complement of crops. In this case the missing
crops are given an area of zero. You are only allowed to specify one key column with this method.
Each entry in the table is identified by the value in the first column and the name of the parent in
the column heading.

2.9. Advanced handling of many models

41

If you have additional parameter values in the same form, these can be added as a parameter element. For example, if you have the number of fields for each farm x crop combination:
<model name="landscape" type="My::Landscape">
<model type="My::Farm" table="farms.txt">
<model type="My::Crop" name="Area"
crosstab="crops_area_on_farms.txt">
<parameter name="numFields"
crosstab="crops_num_fields_on_farms.txt">
</model>
</model>
</model>

with this content of the file crops_num_fields_on_farms.txt:

*My::Farm

Oats

SBarley

WBarley

You can add as many as you need of these parameter tables and, indeed, combine this method
with any of the above.
In all of the examples above, key columns were used to define the context of the table by
the name of one or more ancestors (parent, grandparent, ) of the parameter. However, you
can also define the context by the value of one of the ancestors parameters. This is easiest to
understand by example: Lets say that nitrogenNorm is a parameter of Crop. But the value of
nitrogenNorm depends both on the Crop and on the soilType of the Farm. This is easy to
define in a table:

*SoilType

Oats

SBarley

WBarley

Clay

90

110

120

Sandy

105

130

145

When Universal Simulator searches for the key value named SoilType in the column heading,
it will find it as a parameter of the Farm, and the value will be extracted from there. The XML
code is straightforward:
<model name="landscape" type="My::Landscape">
<model type="My::Farm" table="farms.txt">
<model type="My::Crop" name="Area"

Chapter 2. Writing recipes

42
crosstab="crops_area_on_farms.txt">
<parameter name="numFields"
crosstab="crops_num_fields_on_farms.txt">
<parameter name="nitrogenNorm"
crosstab="nitrogen_norms.txt">
</model>
</model>
</model>

Chapter 3. Working with source code


This chapter takes you through the steps needed to download and unpack the source code of
Universal Simulator (3.1). Subsequently, you are shown how to navigate the source code to find
the implementation of specific plug-ins and models (3.2). For the expert, instructions are given
how to build your own version of Universion Simulator from the downloaded source code (3.3).
This latter step is needed, if you want to develop your own plug-ins and models.
3.1. Downloading source code
You find the source code of Universal Simulator in the download section of www.ecolmod.org.
Follow the instructions there to download the UniSim source code package. The package is
complete and contains all Universal Simulator code which is written in C++ and XML.
To study the C++ and XML files, you can use an all-purpose text editor, such as Notepad
found on MS Windows. However, a much better choice is Notepad++, which offers syntax-highlighting of both C++ and XML code. It can be downloaded for free at notepad-plus-plus.org. For
XML files you may find Komodo Edit a superior tool, as it will help you write XML code that is
valid. Freely available at www.activestate.com/komodo-edit.
Once you have downloaded the source code package, which comes as one huge zip file,
create a folder to hold your source code, for example, C:/dev. Unpack the zip file there, and
a sub-folder will be created with the contents of the zip file. After unzipping the file, feel free to
rename the resulting folder. Here you see a successful installation of the source code, where the
folder was renamed UniSim:

Do not clutter your folder structure. You can, for example, easily find yourself in this situation
after unpacking:

43

44

Chapter 3. Working with source code

Keep your folder structure as simple as possible. In this case, delete the unnecessary duplication
of UniSim folders. Otherwise, confusion is imminent. You will soon have plenty of folders and
files to keep track of.
If you later on download newer versions of the source code, you can end up with several
versions in sibling folders:

This developer seemingly chose to keep a folder for each of three different versions of the source
code: versions 1.36 and 1.37 and then maybe the newest version. This will cause no problems
(other than, potentially, your own confusion). At any time you can delete folders with outdated
versions of the source code but always consider whether some files should be salvaged first.
Maybe your own XML files, or even C++ files, are hiding inside those older folders.
3.2. Navigating source code
The folder, where you unpacked the source code, is called the root folder of Universal Simulator.
In this example, the root folder is located in C:/dev/UniSim:

3.2. Navigating source code

45

The C++ files are found in the src folder. To enable different modellers to program in welldefined work spaces, the source code is split into modules called plug-ins, which are found in the
src/plugins folder. In the example above, the files inside the ecotox plug-in are shown.
The XML files, which form the recipes that you can open and execute with
the Universal Simulator program, are found in the src/recipes folder. For example, you can find the XML files, used as examples in the previous chapter, in the
src/recipes/unisim_explained/writing_recipes folder:

46

Chapter 3. Working with source code

If you previously installed the Universal Simulator program (Chapter 1), you will already
have these XML recipes present on your computer. They are in the Universal Simulator folder inside your standard documents folder. Possibly, you also wrote some additional XML
recipes yourself earlier and, most likely, you also saved them there. Take care not to confuse

3.2. Navigating source code

47

the two different recipes folders: the one inside the Universal Simulator root folder (e.g.,
C:/dev/UniSim/src/recipes) and the one possibly inside your standard documents folder
(e.g., C:/Users/niels/Documents/UniSim-1-41/recipes).
3.3. Building from source code
This section is only for the reader who has previous experience with C++ programming, and who
wants to extend the existing set of models available for Universal Simulator. Before you start
writing your own code, you must build Universal Simulator from the downloaded source code.
The download procedure was described in section 3.1.
If you earlier on installed the end-user version of Universal Simulator (as described in
Chapter 1) then you automatically installed the Graphviz software as well. Graphviz is used by
Universal Simulator to draw diagrams. However, you may have gone directly to this chapter,
skipping the end-user installation, which is fine but then you have to install Graphviz yourself. Go
here to install Graphviz: www.graphviz.org. Follow the download and subsequent links. Pick
the version for your operating system and finally pick the current stable release version. First
time you run Universal Simulator, you will be asked in which folder you installed Graphviz.
To build Universal Simulator, you need to download the Boost library found at
www.boost.org. Click on the Get Boost link found there and follow the links to download the
latest version as a zip file. Unpack the zip file in a separate folder, together with the folder for the
Universal Simulator source code, for example in C:/dev/boost_1_48_0. To prevent confusion, avoid nested sub-folders, such as C:/dev/boost_1_48_0/boost_1_48_0.
Qt Creator is the IDE (Integrated Development Environment) used to build Universal Simulator. You can install Qt Creator from Qt Project. Notice that there are many diffent versions
depending on your computing platform. The interactive installation program will show you available options. To follow this tutorial, you should install Qt Creator on Windows with the MinGW
32-bits tool. After that crucial choice, simply accept all default suggestions during installation.
To prepare your computer for building Universal Simulator, you must set three environment
variables:
1.

Create the BOOST_ROOT environment variable. Typically as C:\dev\boost_1_48_0.

2.

Create

QT_ROOT
environment
C:\Qt\5.1.0\mingw48_32\bin.

3.

Amend the Path environment variable. Typically with the same path as set for QT_ROOT.

the

variable.

Typically

as

Note: You typically will have later version numbers for both Boost and Qt.
Sometimes it may occur that you have no folder called C:\Qt\5.1.0\mingw48_32.
Maybe you picked the wrong installation file and installed a version of Qt Creator meant
to work together with MS Visual Studio. In that case, you will have a folder named
C:\Qt\5.1.0\msvc2010 or similar. However, in this manual we do not use that tool, so you
need to fix your Qt installation. Go to the Windows program menu, find the Qt folder and inside that click on the Qt Maintainance Tool application. In this application, choose Package
manager and proceed. In the options tree that appears, drill down this track (using the triangle
icon to move down one step): Qt - Qt 5.1.0. There, place a check mark to select the MinGW

48

Chapter 3. Working with source code

component. Now proceed and let the installation complete. Afterwards check that the folder
C:\Qt\5.1.0\mingw48_32\bin is now present.
To access the environment variables: right-click Computer, click Properties, click
Advanced system settings, click Environment Variables, and you are brought to a view of you
environment variables.
Under User variables click New and create a variable called BOOST_ROOT with a value
referring to the folder where you put the Boost library, for instance, C:\dev\boost_1_48_0:

Repeat this procedure and create the QT_ROOT variable. Its value should refer to the folder
specifying your version of the Qt libraries. This folder is located inside the folder with the Qt
Creator installation, usually C:\Qt. The complete path, which you should put in the QT_ROOT
variable, should be something like C:\Qt\5.1.0\mingw48_32\bin:

3.3. Building from source code

49

You might have a higher version number of the Qt library than version 4.8.1 as in this example.
Check the folder structure on your computer and use the version number that you find.
Finally, find the Path variable under System variables. Double-click that and you will
see that its value is a long string of folder names, separated by semicolons. You may find it
convenient to copy and paste the whole string into a text editor, to get an overview of what
it contains.
The Path variable tells the Windows operating system in which folders to look for
executable files. Universal Simulator relies on a few libraries which reside in folders, that you
must include in the Path. Otherwise, the Universal Simulator version that you are about to build
will not work.
You need to append one additional folder to the Path. Luckily, it is the exact same folder as
you just set for QT_ROOT, i.e. C:\Qt\5.1.0\mingw48_32\bin, or similar. To add this folder
to the Path variable, type a semicolon at the end of the string that lists all the Path folders and
then add the path at the end:

50

Chapter 3. Working with source code

The Universal Source code is found in the src folder:

To begin with you should go to the src/build/win folder and execute the batch file found
there called build_all.bat. This will cause a complete build of the Universal Simulator
program and all its plug-ins. You can follow the progress, both in the rolling text window that
appears and in the folders, where the build products are saved.

3.3. Building from source code

51

In the src/library folder, two library files will be produced. Their names begin with
base and engine and will be of DLL file type. In the src/plugins folder, one plug-in library
will be produced for each of the sub-folders in the src/plugins folder. They will be named
after their folder and will also be of DLL type. Together with a DLL file, you will always find a
file with the same name, except with lib in front.
Finally, in the src/applications folder, the Universal Simulator itself will appear. Its
name begins with UniSim. Another program, to run the suite of unit tests that follows Universal
Simulator, is built as well. Its name begins with test-unisim.
All the files built end with -n-nd, where n-n stands for the version number and the d stands
for developer. The d is put there to distinguish these files from those destined for the end-user.
The end-user files are those that are installed by the Universal Simulator installer, as described
in Chapter 1.
If you previously installed the Universal Simulator (Chapter 1), and if the building process
by build_all was successful, you now have two versions of Universal Simulator on your
computer. The first one is the end-user version, which you can execute through the Programs
menu. The second one is the developer version, which you can execute by double-clicking the
UniSim-n-nd.exe file found in src/applications. You can change the C++ code of the
developer version but not of the end-user version. However, both versions will accept the same
XML recipe files.
When you run Universal Simulator, you can tell easily whether it is the developer or
end-user version: The developer version has an x appended to its version number, wheres the
end-user version has not. For example, version 1.37.x vs. version 1.37. The version number is
displayed in the title line of the application and under Help|About.
If an error message appears when you try to run Universal Simulator, complaining about
a missing .dll file, it is because the Path variable on your computer was not set up correctly.
Check the steps explained previously in this section (3.3). The name of the missing .dll can
maybe guide you to find the correct folder to put in the Path.
You will find it a lot easier to navigate the source code, now that you have Qt Creator
installed. From its menu you can choose File|Open project and open any of the project files
(recognised by their type which is .pro). Notably, there is one inside each of the src/plugins
folders.
3.4. Universal Simulator algorithm
When you develop your own models, you define a new model class for each kind of model that
you need. A Model base class is supplied for this purpose. Its header file is in the folder of the
usbase library, and the Model class resides in the UniSim namespace. To set your models
apart from those of other developers, you pick you own namespace. In this case the modeller has
picked meadow for his namespace:
#include <usbase/model.h>
namespace meadow {
class Frog : public UniSim::Model

52

Chapter 3. Working with source code


{
public:
Frog(UniSim::Identifier name, QObject *parent);
void reset();
void update();
private:
// parameters
double initDensity, lengthOfJump;
// variables
double n, totalDistance;
};
}

namespace The Model base class declares six virtual methods which are all defined empty in the
base class. You equip your model class with the desired behaviour by re-defining one or more
of these virtual methods. For the Frog class, methods reset and update were re-defined; the
constructor Frog(name, parent) will be called by Universal Simulator should a Frog model
be required by the recipe.
Here are the names and typical usage of the six virtual methods of the Model base class:
amend()
Called once just after the recipe has been opened by the user. The amend method allows you
to create model objects in addition to those already specified in the recipe. This can be used
to make quite sophisticated models. For instance, an EcologicalCommunity model could
take the number of species as a parameter.The amend method of EcologicalCommunity
could then create the appropriate number of Species models.
initialize()
The initialize method is called once, just after the user has started a simulation run. The
initialize method is commonly used for the model object to find other models that it
will collaborate with. Such connections are held in pointers, which will then usually be used
by the reset and update methods.
reset()
The reset method is called once before every iteration of the simulation. If the simulation
is only carried out once, then the reset method will likewise be called only once. The
reset method is defined for most models because its main purpose is to set all state
variables to their initial value. For the Frog class, totalDistance could be set to zero.
update()
The update method is usually the most important of the six methods, incarnating most
of the biological behaviour of the model. The update method is called once every time
step. Its main purpose is to update all state variables. In the Frog class, totalDistance
could be incremented with lengthOfJump. This would result in a linear increase in
totalDistance with time.
cleanup()
The cleanup method is called once after a simulation iteration has completed. It is not used

3.4. Universal Simulator algorithm

53

very often. Its typical use is to summarise the results of the simulation iteration.
debrief()
The debrief method is called once after the last simulation iteration has completed. It is
used even less than the cleanup method.
Since these methods will be called, once or repeatedly, for all model objects present in a simulation, it is important to know the order in which they are called. First of all, the logic explained
above is described equivalently and more succinctly, by this algorithm:
user opens recipe with File|Open menu;
amend all models;
show model diagram on screen;
user starts simulation with Simulation|Run menu;
initialize all models;
for each iteration {
reset all models;
for each time step
update all models;
clean-up all models;
}
debrief all models;
show output on screen and in files;

Whenever one of the six Model base class methods (amend, initialize, reset, update,
cleanup, debrief) is called in this algorithm, it is called for all models present in the simulation. Moreover, they are always called in the order in which the appear in the recipe. If some
models reside inside another model then the models inside will be handled first - in their order of
appearance in the recipe. These nested method invocations can go on to any depth, as defined by
the model hierarchy found in the recipe.
3.5. Communicating with models
The data members of your models should be private to the class, as exemplified by the Frog
class above. Yet, some data members must be made accessible, both for the recipe and for other
models, to enable your model to communicate. There are two ways to create access to a data
member: it can serve as an input, which gives others both read and write access to it, or as an
output, which only provides read access.
In the Universal Simulator framework, access is provided by the functions (actually, they are
C++ macros but you can disregard that detail) Input and Output. You use Input and Output
to set up the desired interface to the data members of your model. The correct place to add inputs
and outputs is in the model constructor:
#include <usbase/parameter.h>
#include <usbase/variable.h>

Chapter 3. Working with source code

54
#include "frog.h"
#include "publish.h"
using namespace UniSim;
namespace Meadow {
PUBLISH(Frog)

Frog::Frog(UniSim::Identifier name, QObject *parent)


: Model(name, parent)
{
Input(double, initDensity, 500.);
// Initial density of frogs
(per km2)"
Input(double, lengthOfJump, 12.);
// Average length of a
jump (cm)");
Output(double, density);
// Density of frogs (per km2)
Output(double, totalDistance);
// Total distance jumped during
the simulation (cm)
}
} // namespace

The inputs and outputs must all be declared in the header file, in this case in frog.h. In the
example above, they have all been declared of type double. The type given here must match
how the parameter or variable was declared (in the header file), otherwise a compilation error
will ensue. The valid types are int, double, bool, QString, QDate and QTime.
To make the model available in the XML recipe, it must be published in the source file.
This is accomplished by the PUBLISH macro as shown. The PUBLISH macro is included from
publish.h.
Inputs have the benefit that their values can be set in the recipe. In this example, the user has
set initDensity to 800, while lengthOfJump is not mentioned and thus retains its default
value (12):
<model name="Rana" type="Pond::Frog">
<parameter name="initDensity" value="800"/>
</model>

Outputs cannot be changed from the recipe but you can refer to them, for instance, to be shown
in the output:
<output type="plot">
<parameter name="title" value="Total distance"/>
<trace name="time" ref="calendar[totalTime]"/>
<trace name="Total" ref="Rana[totalDistance]"/>
</output>

3.5. Communicating with models

55

Lets say that we implement a Stork model, which needs frog density as an input to calculate
its food intake. Its constructor could look like this:
Stork::Stork(UniSim::Identifier name, QObject *parent)
: Model(name, parent)
{
}

This code sets preyDensity to a default of 50 but the user would likely prefer to link that value
to the actual population density of prey, e.g., the frogs. That could be achieved in the recipe:
<model name="stork" type="Pond::Stork">
<parameter name="preyDensity" ref="Rana[density]"/>
</model>

Would it be possible somehow to set that reference as the default value, so that the user in most
cases would not have to bother? Yes, we can do it, like this, in the Stork constructor:
Stork::Stork(UniSim::Identifier name, QObject *parent)
: Model(name, parent)
{
Input(double, initDensity, 500.);
// Initial density of storks
(per km2)
InputRef(double, preyDensity, "Rana[density]");
// Density of
prey (per km2)
Output(double, density);
// Density of storks (per km2)
}

However, if the user happens to have put no model named Rana in the recipe, this will cause
an error when the recipe is opened, because the reference cannot be found. The problem would
persist, even if the user added a Frog model but with another name than Rana, for example,
Rana_esculenta:
<model name="Rana_esculanta" type="Pond::Frog">
<parameter name="initDensity" value="800"/>
</model>

The question then arise if we could make the Stork model itself intelligent enough, that it would
look up any model in the recipe of the class Frog? Or, indeed, any number of models of classes
Frog, Fish or whatever would be allowed in the pond universe? Here, we will limit ourselves
to find just a single Frog model:
// In stork.h
#include <usbase/model.h>
namespace meadow {
class Stork : public UniSim::Model

Chapter 3. Working with source code

56

{
public:
Stork(UniSim::Identifier name, QObject *parent);
void initialize();
void reset();
void update();
private:
// parameters
double initDensity;
// variables
double density;
// links
const double *preyDensity;
};
} // namespace
// In stork.cpp
#include "frog.h"
#include "publish.h"
#include "stork.h"
namespace meadow {
PUBLISH(Stork)
void Stork::initialize() {
Model *prey = seekOne<Frog*>("*");
preyDensity = prey->pullValuePtr<double>("density");
}
} // namespace

First of all, we do not need preyDensity as a parameter any more; the Stork model will
find that independently. In initialize(), the Stork model orientates itself to find the
Frog model. It finds the other model by the its class name Frog. By giving the model name
as a joker "*", any model of the class Frog will be found irrespective of its name, e.g., Rana,
Rana_esculanta or whatever.
The various seek and peek methods used to find model objects are explained below (3.6).
The prey pointer that we just obtained is asked, by way of the pullValuePtr method, for
a pointer to density. From now on Stork will have access to density through the pointer
variable preyDensity. The access will be read-only, as notified by the const modifier in the
declaration: const double *preyDensity.
It is not easy to judge whether a model should be imbibed with some intelligence to seek
out other models or not. As a general rule, you should only apply this technique when necessary.
In any case, it pays off first to establish all connections between models in the recipe only. Then,
as the model matures, inflexibilities may evolve which you can only solve by some built-in model

3.5. Communicating with models

57

intelligence. The drawbacks of the technique are that your C++ code becomes more complicated,
the recipe less clear - and maybe even less flexible, thus opposing your original intent.
3.6. Navigating model structure
Model structure is defined by the user via the recipe. You must decide what makes a valid recipe.
Does a Stork model require that a Frog model is also present? Would it be allowed for more
than one Frog model to be present? To check such conditions and set up the necessary links
between models, your model may need to orientate itself at some point. The best place to do
that is in the initialize method. The method will only be invoked once during a simulation
run, and you are certain that all model objects belonging to the simulation have been created at
that time.
The Model base class provides a suite of peek and seek methods. All these methods look
for objects of a certain class and with a certain name. A joker ("*") can be used for the name to
find all objects of a certain class. Here are some introductory examples:
// Find any Model object called weather
Model *weather = seekOne<Model*>("weather");
// Find any Records object called weather
Records *weather = seekOne<Records*>("weather");
// Find all Fish children of ocean
QList<Fish*> fish = ocean->seekChildren<Fish*>("*");
// Find all my Model siblings
siblings = seekSiblings<Model*>("*">

In all the following diagrams, the object orientating itself is painted blue and the part of the
family tree that is searched is painted yellow. None of the methods will return the object itself as
a result (the object itself is excluded from the search).
These facilities may seem quite overwhelming. It is good to know, that you are unlikely to
need them in your first steps of model development.

Chapter 3. Working with source code

58
Seeking any object

These methods search globally and are often used to find objects representing time and environment:
Model *calendar = seekOne<Model*>("calendar");
Model *weather = seekOne<Model*>("weather");

peekOne returns a pointer to object, or null if none was found, or throws an Exception

if more than one was found

seekOne returns a pointer to object, or throws an Exception if none or more than one

was found

seekMany returns a list of pointers to objects

Seeking children

Models commonly need to establish contact with their children. The Insect model in the
following code builds a list of all its Stage children, finds its egg child in particular (which must
exist) and peeks for a Model named mould inside the egg. This mould object may exist or not.
In the latter case mould will become null:

3.6. Navigating model structure

59

void Insect::initialize() {
QList<Stage*> stages = seekChildren<Stage*>("*");
Model *egg = seekOneChild<Model*>("egg");
Model *eggMould = egg->peekOneChild<Model*>("mould");
}

peekOneChild returns a pointer to object, or null if none was found, or throws an


Exception if more than one was found

seekOneChild returns a pointer to object, or throws an Exception if none or more than

one was found

seekChildren returns a list of pointers to objects

Seeking nearest object

The nearest object matching the given class and name is searched for in the order indicated by
numbers: first among the children, then among the ancestors children, step by step all the way
back to the root. The effect is close to the scope look-up rules for variable names in C++. This
offers great flexibility for the end-user. For example, it is used by UniSim::Stage to find the
nearest time object used for updating the development of the stage:
void Stage::initialize() {
Model *time = seekOneNearest<Model*>("time");
}

Thus the user can put a time model inside the Stage model to define a special chronology for
that Stage object. Or, the user can put it at a heigher level where it can be shared by many Stage
models, having this time model in common. Should a time model be placed both as a child and
further up search path (shown in the diagram above), then the result will be the first time object
one found (it being the nearest).

peekOneNearest returns a pointer to object, or null if none was found

seekOneNearest returns a pointer to object, or throws an Exception if none was

Chapter 3. Working with source code

60
found
Seeking parent

There can be at most one parent of an object, so there is no seekParents. Sometime a parent
is needed to find shared relatives. Here an Animal objects finds all models of the Plant class,
which are nested inside the Animal objects parent:
void Animal::initialize() {
Model *parent = seekParent<Model*>("*");
QList<Plant*> plants = parent->seekDescendants<Plant*>("*");
}

peekParent returns a pointer to object, or null if none was found

seekParent returns a pointer to object, or throws an Exception if none was found

Seeking siblings

A model my share an interest with its siblings. Perhaps they are predators and prey?

3.6. Navigating model structure

61

QList<Predator*> predators = seekSiblings<Predator*>("*");


QList<Prey*> prey = seekSiblings<Prey*>("*");

peekOneSibling returns a pointer to object, or null if none was found, or throws an


Exception if more than one was found

seekOneSibling returns a pointer to object, or throws an Exception if none or more

than one was found

seekSiblings returns a list of pointers to objects

Seeking descendants

Whenever you seek for an objects child or children, consider whether this is too strict. Maybe
it is enough to demand that objects you look for are among the objects descendants? Maybe you
just want to look for all Organs inside, or for any model that has a child called mass:
QList<Organs*> organs = seekDescendants<Organ*>("*");
QList<Model*> masses = seekDescendants<Model*>("mass");
QSet<Model*> hasMass;
for (int i = 0;i < masses.size(); ++i)
hasMass << masses[i]->seekParent<Model*>("*");

peekOneDescendant returns a pointer to object, or null if none was found, or throws an


Exception if more than one was found

seekOneDescendant returns a pointer to object, or throws an Exception if none or

more than one was found

seekDescendants returns a list of pointers to objects

Seeking ascendants

Chapter 3. Working with source code

62

The ascendant search is short. Often you want to find some containing model without knowing
how deep you are in the model hierarchy yourself. Maybe you are a leaf on a tree, but do not
know how many model layers (twig, trunk) are in between you and the Tree. So, you search
for an ancestor of class Tree, or maybe just any type of Model called tree:
Tree *tree = seekOneAscendant<Tree*>("*");
Model *model = seekOneAscendant<Model*>("tree");

Neither method accepts that more than one ancestor, matching the search criteria, are found.

peekOneAscendant returns a pointer to object, or null if none was found, or throws an


Exception if more than one was found

seekOneAscendant returns a pointer to object, or throws an Exception if none or more

than one was found

seekAscendants returns a list of pointers to objects

In addition, two methods work like peekOneAscendant and seekOneAscendant, except they refer to the nearest ascendant: peekNearestAscendant and seekNearestAscendant

3.7. Plug-in structure


All the source code of one plug-in goes into one Qt project. The source code resides in a folder
bearing the name of the plug-in. The folders with plug-in source code are all sub-folders of
src/plugins. The example plug-in in src/plugins/example exemplifies a minimal
plug-in, which defines only one model. It contains five files:

example.pro which is the Qt project file

example_factory.h and example_factor.cpp which provide the interface to

produce the models defined in the plug-in

even_odd.h and even_odd.cpp with source code for the EvenOdd model

The example plug-in is provided as a basis to create new plug-ins. You simple copy the folder

3.7. Plug-in structure

63

with contents and rename the copy. Software, such as Notepad++, provides search and replace
for all files in a folder and can help you renaming throughout the copied plug-in folder. These are
the necessary steps, for example to create a new plug-in called ocean. For the search-and-replace
operations, include files *.h;*.cpp;*.pro, unselect the option to match whole words only,
and select the option to match letter case:
1.

Copy src/plugins/example to src/plugins/ocean.

2.

Rename example.pro as ocean.pro, and example_factory.h and .cpp as


ocean_factory.h and .cpp.

3.

Search and replace "example" with "ocean".

4.

Search and replace "Example" with "Ocean".

5.

Search and replace "EXAMPLE" with "OCEAN".

6.

In Qt Creator, open the ocean project file and build it.

7.

Write an XML recipe to test that the plug-in works. Recipes found in recipes/examples
can be used as a starting point.

8.

Start Universal Simulator from src/applications, open your test recipe and run a simulation

Chapter 4. The BtButTox model


The BtButTox model simulates the side effects of Bt-maize on the Peacock butterfly Inachis io
living in the vicinity of Bt-maize fields. It is composed of three parts: a maize pollen deposition
model, a dose-response model and a butterfly model. The model runs for a whole year. The
butterfly overwinters as an adult and gives rise to 1-2 generations.
The model includes no density-dependent processes or mortalities, other than that caused
by larvae being exposed to Bt-maize pollen. Hence the model works in nominal numbers: one
female emerges from hibernation, and it produces only one egg. The number of larvae entering
pupation, to become the overwintering adults, marks the simulation end point. If Bt-maize has
no effect in the simulation, then one larva will enter pupation for every egg laid. The model is
further described by Holst et al. (2013).
The model can be changed by the end-user, both in terms of parameter values and model
structure, which are specified in XML recipe files. These files can be opened and the simulation
carried out with the Universal Simulator program. The installation of Universal Simulator is
described in Chapter 1 and the writing of XML recipes in Chapter 2. The organisation of the
model source code and how to download is described in Chapter 3.
4.1. Scenario simulations
Recipes for scenarios in Northern Germany (where I. io has one generation) and Southern Germany (where I. io has two generations) can be found in the recipes/BtButTox/scenarios
folder. There are three recipes for both scenarios, file names beginning with N or S, respectively.
The recipes define these simulations:
one year (files N_one_yr.xml and S_one_yr.xml)
The simulation runs for one year from 1 January to 31 December. Population dynamics are
shown on screen.
a few years (files N_few_yrs.xml and S_few_yrs.xml)
The simulation runs in 10 independent iterations, each lasting one year. Population
dynamics are shown on screen.
many years (files N_many_yrs.xml and S_many_yrs.xml)
The simulation runs in 1,000 independent iterations, each lasting one year. Sensitivity plots
are shown on screen. Summary statistics are written to a single file, while the population
dynamics of each simulated year are written to separate files.
Since the pollen deposition model contains random parameters, and the butterfly model is driven
by day-degrees according to a year picked at random, it makes sense to run the model iteratively
to assess the distribution of possible outcomes.

64

4.2. Scenario recipes

65

4.2. Scenario recipes


The six scenario recipes share many common attributes. For instance, the I. io model is the same
for all eight recipes, except that the number of generations differs between the Northern and
Southern Germany scenarios (one and two generations, respectively). To avoid duplication of
information between recipes, common parts have been formulated in separate recipes.
This table show how the six scenario recipes are put together from other recipes. A recipe depends on all those appearing in the stack of recipes below:
N_few_yrs
N_one_yr

S_few_yrs
N_many_yrs

base_N_records, base_N_output

S_one_yr

S_many_yrs

base_S_records, base_S_output

base_pollen, base_io, base_output

So if you change the base_io recipe, all six scenario recipes will be affected, and if you
change the base_N_records recipe the three North Germany recipes will be affected. Recipes
beginning with base do not formulate a complete recipe on their own. They are only used as
building blocks for the scenario recipes.
4.3. Scenario outputs
If we start out with the northern scenario defined in the N_few_yrs recipe, we will be granted
five figures of output when the simulation is run. They all have curves overlaid, representing ten
iterations of the simulation, and all have x-axes showing time as the number of days since the
beginning of the year. The first figure shows the average temperature during the year:

Next, the pollen figure shows the daily rate of pollen deposition on nettle leaves (pollen per cm2
per day in red), the actual density pollen on nettle leaves (pollen per cm2 in blue) and the total
accumulation of pollen deposited on nettle leaves, not corrected for loss of pollen from the leaves
(pollen per cm2 in yellow):

66

Chapter 4. The BtButTox model

Overwintering butterflies emerge in early spring according to the calendar. Hence, there is no
variation between years in their flight time. The development of subsequent stages, however, are
driven by day-degrees, which leads to variation between years:

To visualise the exposure of larvae to pollen, we combine the curves for pollen and larva density
in the same figure:

A log10-scale let us follow the predicted overlap also at low densities (values less than -2 not
shown). What we see is no overlap; the larvae finish their development before pollen deposition
begins

4.3. Scenario outputs

67

If larvae are exposed to pollen during their development, they will suffer an increased mortality, as determined by the dose-response curve included in the model. The net effect is illustrated in the last figure, which shows that, in this scenario, all larvae complete their development.
Consequently, the number of overwintering butterflies is the same at the end of the season as at
the beginning:

We can contrast these model predictions with those of the southern scenario defined in the
S_few_yrs recipe. Temperature is slightly higher, and the pollen season comes slightly earlier:

In this scenario, the butterfly has two generations. Both the emerging overwintering adults and
the newly produced first generation of adults are shown in the same figure:

68

Chapter 4. The BtButTox model

For the second generation, the prediction is that the pupae will not alwaus have time to complete
their development:

This prediction of incomplete pupal development has no impact on the risk analysis, however,
because the end point is taken, not as the number of hibernating adults at the end of the year, but
as the number of larvae completing their development.
When we consider exposure, we realise that 1. generation larvae is present earlier than the
pollen season, while the 2. generation larvae seems fully exposed:

The response of the population is evident. In quite many years, only a fraction of the larvae

4.3. Scenario outputs

69

complete their development:

In years with cold autumns, even the successful larvae do not all reach adulthood but, as
noted above, this prediction does not affect the risk analysis. For further details consult
Holst et al. (2013).

Chapter 5. Conductance model


The Conductance model is a model that simulates plant growth under competition for light,
either in monoculture or in bi-culture (Benjamin & Park 2007). In contrast to the INTERCOM
model which focuses on the vertical distribution of the canopy, the Conductance model deals
only with the horizontal distribution of leaf area.
The word conductance stems from early versions of the model which used the principle
of conductance to construct a synthetic time scale, based on several physiological time scales.
The Conductance model was implemented in the conductance_models plugin found
in the src/plugins/conductance_models folder inside your Unisim root folder. The
XML files can be found in the xml/models/conductance folder, also inside the UniSim
root folder.
5.1. Plant model
The Plant model (found in plant.h and plant.cpp) define quite many pull variables
whereby to track the state of the plant. For an overview you can either consult the C++ code in the
constructor Plant::Plant, or you can look up the documentation on page 117. The parameters
for the Plant model are described on the same page.
A Plant object needs some orientation during initialization:
void Plant::initialize() {
weather = seekOne<Model*>("weather");
other = 0;
QList<Plant*> siblings = seekSiblings<Plant*>("*");
if (siblings.size() > 1)
throw Exception("Max. 2 plants are allowed in "
"community", this);
other = siblings.isEmpty() ? 0 : siblings[0];
}

It looks up the weather object and also checks how many sibling Plant objects it has. Since
only zero or one sibling is allowed, it faults otherwise. The throw statement will result in an
error showing up on the user screen. The other variable is a pointer to a Plant object (see its
declaration in plant.h), which is set in initialize, either to null or to point to the other
Plant object.
Once every day the update function of all Models objects is automatically invoked. The
update function of the Plant model consists of three steps which update, in sequence, the
crown zone area, light interception and weight:
void Plant::update() {
70

5.1. Plant model

71

updateCrownZoneArea();
updateLightInterception();
updateWeight();
}

The crown zone area sz (sz in the code) is what makes the Conductance model special. It is the
area of the smallest circle that circumferences the whole canopy of one single plant. The plant is
considered to own this area. It is available only for the plant itself to fill up with leaf area. Thus
its dimension is
m2 ground area owned
[sz ] =
plant
The crown zone area is computed in one of three ways depending on which growth phase the
plant is currently in:
void Plant::updateCrownZoneArea() {
switch (phase) {
case Unlimited:
sz = A*pow(weight, phi);
break;
case UnderCompression:
sz = other ?
(1. - other->pullVariable("total_sz"))/n :
1./n;
break;
case WeightProportional:
Q_ASSERT(other);
sz = weight/(totalWeight +
other->pullVariable("totalWeight"));
}
total_sz = n*sz;
if (total_sz < 0)
sz = total_sz = 0.;
else if (total_sz > 1) {
total_sz = 1.;
sz = 1./n;
}
}

What is phase? It is a C++ enumeration. Enumerations are one of the simplest constructs in C++
and their explanation in any textbook is not frightening. The phase variable is declared in the
header plant.h, and the declaration of the Phase type is declared in phase.h.
In the Unlimited phase, the plant population simply grows as if each plant were growing
in isolation without competition. In that case, the crown zone area sz is computed according to
the allometric relation, given as a power function.

Chapter 5. Conductance model

72

In the UnderCompression phase, the plants (one or two populations, represented by one
or two Plant objects) completely fill out the available area. To understand the logic, let us have
a look at the dimensions of the involved variables. Plant density is denoted by n. Hence
[n] =

m2

plants
ground area available

If there is only one plant population present (in which case other is null, which in C++ is
equivalent to false) then
sz = 1 n
To make the dimensions match we can infer the suiting units of the enumerator 1 in 1 n,
[ enumerator ] =

m2 ground area owned


m2 ground area available

and thus
[1 n] =
m2 ground area owned
m2 ground area available

m2

plants
=
ground area available

m2 ground area owned


= [sz ]
plant
Hence an enumerator value of 1allows the plants to own only as much ground area as is available.
This sets the upper limit on the total crown zone area of all plants in the population:
nsz 1 m2 ground area owned per m2 ground area available
In case another population is present, we first subtract the total crown zone area total_sz
taken up by that other population. Then the remaining ground area is divided among the plants
of this population:
(1. - other->pullVariable<double>("total_sz"))/n

Notice the use of the pullVariable method to require the current value of a variable from the
model pointer to by other. A complete list of the pull variables available for Plant models is
found in the documentation for the Plant class beginning on page 117.
In the WeightProportional phase, both plant populations are alloted a total crown
zone area in proportion to their total weight (eqs. 21 and 22 in Benjamin & Park (2007)). For
population 1, the proportion is
w1n1
w1n1 + w2 n2

5.1. Plant model

73

The corresponding code is


Q_ASSERT(other);
sz = weight/(totalWeight + other->pullVariable("totalWeight"));

The assertion Q_ASSERT(other) will cause a run time error if other is null. That is because
this calculation only makes sense if two populatios are present. To obtain the crown zone area of
plants in population 1, we have divided with the density of plants (n1) to obtain
sz1 =

w1
w1n1 + w2 n2

A dimensional analysis of the right hand side shows the its dimension matches that of the crown
zone area. Moreover, it follows that the total crown zone area of both populations together adds
up to 1,
n1sz1 + n2 sz2 = 1 m2 ground area owned per m2 ground area available
The code is valid for either plant, so in the coding w1 is represented as weight, w1n1 as totalWeight and w2 n2 as totalWeight pulled from the other plant.
After updating the total population crown zone area total_sz, checks are made to ensure
that it remains inside the valid [0..1] interval:
total_sz = n*sz;
if (total_sz < 0)
sz = total_sz = 0.;
else if (total_sz > 1) {
total_sz = 1.;
sz = 1./n;
}

This is necessary to guard against rounding off errors. The checks also evens out when the model
overshoots the crown zone area at the passage from the Unlimited to the UnderCompression
phase and from the UnderCompression phase to the WeightProportional phase.
Since the concept of crown zone area is particular to the Conductance model, it comes as
no surprise that its calculation is also the most complicated part of the model. The remaining
calculations are comparatively simple. Let us review how far we have come in our walk throught
the code.
void Plant::update() {
updateCrownZoneArea();
updateLightInterception();
updateWeight();
}

We have just covered the updateCrownZoneArea function, so we are now ready to calculate
light interception.
The fraction of light intercepted fz is calculated from the leaf area index within the crown

Chapter 5. Conductance model

74
2

zone Lz (m leaf area per m2 ground area owned), which is calculated as the leaf area of a plant
divided by its crown zone area.
The plant leaf area LA_per_plant is estimated from plant weight assuming a simple
allometric relation. Thus we arrive at this implementation:
void Plant::updateLightInterception() {
LA_per_plant = F*pow(weight, theta);
Lz = LA_per_plant/sz;
fz = 1. - exp(-k*Lz);
}

where k is the light extinction coefficient of the plant species.


We are now ready to calculate and add the increment in plant weight dweight during this
time step of 1 day:
void Plant::updateWeight() {
double I = weather->pullVariable<double>("irradiation");
dweight = eps*I*sz*fz;
weight += dweight;
totalWeight = n*weight;
}

First we pull the daily global irradiation I from the weather object. We multiply I with the
light-to-dry weight conversion efficiency eps, the crown zone area sz which is the effective
area that takes up light, and the fraction of light intercepted fz.
Only half of the global irradiation is photosynthetically active radiation (PAR = I / 2).
However, (eps, in code) was parameterized to operate on I rather than PAR. This choice is
arbitrary and inconsequential but one should always be aware whether should be applied to I
or PAR.
Next we add the increment dweight (g per plant) to the plant weight, and we update the
total population plant weight (g per m2 ground area available) by multiplying with plant density
n.
The update updates the state of the Plant object, in terms of its crown zone area, leaf area
and weight. But the code we have inspected so far, does not change its growth phase, whether
it be Unlimited, UnderCompression or WeightProportional. So, a Plant object does
not determine itself when to change phase; this instruction comes from the outside. The method
for that is naturally called changePhase:
void Plant::changePhase(Phase newPhase) {
phase = newPhase;
_phase = int(phase);
Q_ASSERT(phase == Unlimited || phase == UnderCompression
|| other);
}

The code is inconspicuous. Apart from actually changing the phase variable, it also updates the

5.1. Plant model

75

related _phase which will take the value 0, 1or 2 depending on the phase. The _phase serves as
a pull variable so that the phase can be displayed as numeric figure, for example as a time trend.
The final assertion is put there to ensure consistency. It asserts that either we are in the Unlimited or UnderCompression phase, or there exist an other plant model. Thus it disallows being
in the WeightProportional phase, if there is only one Plant model present.
Now it is time to wonder what all this functionality is good for. The code is just sitting there.
Who is going to activate it? The UniSim framework will call the functions initialize once
and update daily. But who will be calling changePhase at the right time? We need some
powerful entity, another kind of object to oversee this business. This is what the Community
model is for.
But before continuing we need to add one more function to Plant, because Community
will need it: The function reUpdate undoes the weight increment of the last update and then
reinvokes update:
void Plant::reUpdate() {
weight -= dweight;
totalWeight = n*weight;
update();
}

Now, why would we possibly want that? Read on to find out.


5.2. Community model
The Community model has been rather boldly named, as it will accept only one or two Plant
objects being present. The plants are looked up during initialization:
void Community::initialize() {
plants = seekChildren<Plant*>("*");
if (plants.isEmpty())
throw Exception("Community has no plants", this);
else if (plants.size() > 2)
throw Exception("Max. 2 plants are allowed in community",
this);
}

Just as was the case for the Plant class, the update function of the Community class is doing
all the work with the help of a few other functions:
void Community::update() {
while (phaseChanged())
reUpdatePlants();
}

Before contemplating this code one should realise, that the automatic daily call of all update
functions proceeds in the order children-first. Thus the Plant objects are updated before the
Community object, because the plants are children of the community.

76

Chapter 5. Conductance model

What we see is a while loop which potentially can re-update the plants one or more times.
This depends on the outcome of the phaseChanged function.
The community is in the same phase as the plant(s), except when there are two Plant
models present and one of them is in the UnderCompression phase. Then the other one is,
by necessity, still in the Unlimited phase, and the whole community is considered to be in the
UnderCompression phase.
The phaseChanged function is all about changing the phases of both the Community
model and the Plant model(s), as needed. It returns as a result (bool) whether phase was
actually changed:
bool Community::phaseChanged() {
updateTotalCrownZoneArea();
if (phase == Unlimited)
return phaseUnlimitedChanged();
else if (phase == UnderCompression && plants.size() == 2)
return phaseUnderCompressionChanged();
return false;
}

First one function is called to calculate the total crown zone area of the Plant model(s). The
remainder of the work is passed on to two other functions, called if the community is currently
in the Unlimited or UnderCompression phase, respectively. In the latter case, the phase
can only change further if two Plant models are present; if only one Plant model is present
it cannot proceed further than the UnderCompression phase. If the community has reached
the final phase WeightProportional, it cannot proceed either, which means that no action is
needed and the function simply returns false.
The summation of the total crown zone area could not be simpler:
void Community::updateTotalCrownZoneArea() {
sum_sz = 0.;
for (int i = 0; i < plants.size(); ++i)
sum_sz += plants[i]->pullVariable<double>("total_sz");
}

Next let us consider the case when we are in the Unlimited phase. If the total crown zone area
sum_sz has reached 1 thus exhausting the available ground area, then phase must change to
UnderCompression. This is what the phaseUnlimitedChanged does:
bool Community::phaseUnlimitedChanged() {
bool availableAreaExhausted = sum_sz >= 1.;
if (availableAreaExhausted) {
sortPlants();
smaller->changePhase(UnderCompression);
phase = UnderCompression;
return true;
}
return false;

5.2. Community model

77

The sortPlants function finds out which of the plants are smaller by weight and sets the two
Plant pointers, smaller and larger, accordingly. Only the smaller plant will change phase
to UnderCompression while the larger (if present) will continue to grow Unlimited.
The code for sortPlants is straightforward:
void Community::sortPlants() {
bool onlyOnePlant = plants.size() == 1;
if (onlyOnePlant) {
smaller = plants[0];
larger = 0;
return;
}
bool firstIsSmaller =
plants[0]->pullVariable<double>("weight") <
plants[1]->pullVariable<double>("weight");
if (firstIsSmaller) {
smaller = plants[0];
larger = plants[1];
}
else {
smaller = plants[1];
larger = plants[0];
}
}

In case only one plant is present, that one defaults to be the smaller and larger is set to null,
meaning it does not exist.
The final piece of the Community phase change puzzle is the phaseUnderCompressionChanged function. This function does nothing until it happens that the leaf area index
inside the crown zone of the smaller plant has reached that of the larger plant. Since the
smaller plant has been UnderCompression, this may happen given enough time:
bool Community::phaseUnderCompressionChanged() {
bool plantsAreEven =
smaller->pullVariable<double>("Lz") >=
larger->pullVariable<double>("Lz");
if (plantsAreEven)
{
smaller->changePhase(WeightProportional);
larger->changePhase(WeightProportional);
phase = WeightProportional;
return true;
}
return false;

Chapter 5. Conductance model

78
}

The consequence is quite simple: both Plant models and the Community model goes into the
terminal WeightProportional phase.
Now it is time to revisit the while loop inside the update function:
void Community::update() {
while (phaseChanged())
reUpdatePlants();
}

All the code evoked by phaseChanged, that we just walked through, aimed to change phase
as needed and then returning false if phase remained unaltered and true, if it actually
were changed. We can see that in the latter case the plants will be re-updated. We need this
backtracking, because some conditions might otherwise remain broken; for example, the total
crown zone area might exceed 1.
This last function of Community contains no surprises:
void Community::reUpdatePlants() {
for (int i = 0; i < plants.size(); ++i)
plants[i]->reUpdate();
}

5.3. Weather model


To enable us to do simple experiments with the Conductance model, the influence of weather is
2
kept as simple as possible. In its basic version, it depends only on global irradiation MJ/m /day)
not on temperature. Consequently the Weather model is simplest possible:
Weather::Weather(UniSim::Identifier name, QObject *parent)
: Model(name, parent)
{
Input(double, irradiation, 10.);
}

The model just contains one input irradiation which will be used as an output as well. Its
value remain constant throughout the simulation.
5.4. Running the model
The Conductance model is simple and demands only six parameters to be estimated: two for
each of the allometric relationships, one for the extinction coefficient and one for the conversion
efficiency. The table shows parameter values for two crops and five weed species.

5.4. Running the model

79

Table. Parameter values for the Conductance model (from Park et al. 2007).
Leaf area

Crown zone area

Species

F (m / g)

A (m / g)

(g / MJ)

Cabbage

0.0158

0.840

0.0314

0.529

0.71

1.40

Carrot

0.00975

0.801

0.0255

0.591

0.65

1.23

Tripleurospermum
inodurum
Solanum nigrum

0.0185

0.890

0.0245

0.623

0.59

1.63

0.0171

0.866

0.0265

0.747

0.70

1.20

Stellaria media

0.0173

0.849

0.0455

0.585

0.71

0.90

Trifolium repens

0.0158

0.916

0.0273

0.692

0.54

1.13

Veronica persica

0.0162

0.869

0.0242

0.696

0.53

1.33

To get a better sense of the Conductance model, let us look at a cabbage-nightshade system.
Nightshade has a more expansive growth form than cabbae. At a certain biomass, a nightshade
plant has a wider crown zone and a larger leaf area than a cabbage plant of the same weight
(see Fig.). The two species are equally good at absorbing light per leaf area since the extinction
coefficients k are about equal. But cabbage is more efficient at utilizing the absormed light as
expressed by its higher light use efficiency .

Leaf area (m )

0.4
0.3
0.2
0.1
0.0

Crown zone area (m )

10

20

30

0.4
0.3
nightshade

0.2

cabbage

0.1
0.0
0

10

20

30

Plant dry weight (g per plant)

Figure. Allometric relations for cabbage and nightshade (Solanum nigrum). Parameters
from table.

Chapter 5. Conductance model

80

The question is what the net result of these differences in traits will be on the outcome of
competition. To address this problem we will do two experiments with the model: one simulation
with cabbage only and one with cabbage in competition with nightshade. The model XML files
to set up these simulations are found in the xml/models/conductance folder inside your
UniSim root folder.
Now is time to start the UniSim software and open the cabbage.xml file. You can see from
the model diagram, that shows up when you open the file, that the simulation has four models
inside it:
UniSim::TimeStepLimited

UniSim::Calendar
calendar
UniSim::Simulation
conductance::Weather
weather

conductance::Community
community

conductance::Plant
cabbage

The models include a Calendar to keep track of time. Calendar is part of the
UniSim package, as shown by the namespace qualification UniSim before its class name
UniSim::Calendar. In addition we find as expected, a Weather model and a Community
model to hold one or two Plant models. In this example only one Plant model, named cabbage, is presemt.
Try running (click the Simulation | Run menu) a simulation with cabbage alone (in file
cabbage.xml) and together with nightshade (in file cabbage-nightshade.xml). Verify that
the plots shown on screen makes sense. You can also study the output found in the output text
file, found in the folder you chose for output files.
To change the parameter values just open the XML file with a text editor such as
Notepad++. There is no need to close the UniSim program while you are editing the file. Save the
XML file in the editor when you are finished editing the parameters (let the editor remain open
too, for your convenience) and swap to UniSim where you click the File | Reopen menu to read
the XML file again and thus obtain the changed parameter settings. Run the simulation again and
study the output. You can swap between the editor and UniSim as you please keeping any XML
files open all the while.
5.5. Discussion
The Conductance model simulates only the growth of plants not their physiological development.
It would be quite simple though to add another model for plant development, say a day-degree
model for the period from emergence to flowering. At flowering growth would stop for species

5.5. Discussion

81

with determinate growth. For species with indeterminate growth, growth would continue maybe
until the first frost which could easily be pulled from a weather log file. A simple harvest model
would set harvest at a fixed date which would be the end of the story for many plants, even though
some weeds would re-grow from a stubble field.
In short, the Conductance model nicely encapsulates a period of plant growth in the field.
This makes it very easy to combine with other models.

Chapter 6. The INTERCOM model


The INTERCOM model, which simulates photosynthesis in a mixed-species canopy, is welldescribed in the free online book by Kropff & Laar (1993). The book describes the principles
and mathematics of the model and, in addition, contains the full FORTRAN source code, most
notably functions TOTASS (pp. 237-238) and ASSIMC (pp. 225-229). It is not a complex model,
yet the mixture of biology, physics, mathematics and FORTRAN coding can be overwhelming.
Here I will first describe the INTERCOM photosynthesis model in prose before presenting a new
implementation of the model in C++.
In section 6.1, the description given by Kropff and Laar is expanded with additional details
and with explanations of what was left implicit in the book. This exposition contains no code
or mathematics. The illustrations were all generated with R scripts (download) which optionally
can be studied further. The R code is equivalent to the FORTRAN code of Kropff and Laar. You
should read both the book and the treatise here, possibly twice.
In section 6.2, I explain how INTERCOM was re-implemented in C++ as a UniSim plugin.
The original FORTRAN code was completely refactored (=reorganised) into an object-oriented
and pluggable framework. This makes the UniSim version easier and more flexible to re-use. The
R code served the purpose of verifying the correctness of the C++ code.
6.1. Light absorption explained
The amount of energy radiated from the sun that would reach 1 m2 of the earth surface, if there
were no atmosphere, is called Angots value. This value depends on the solar constant (the
amount of solar energy intercepted by earth) and the elevation angle (height) of the sun, so it
2
varies according to both latitude and day of the year. Units in common use are MJ/m /d and
2
W/m . Remember that W equals J/s. Angots value is bimodal around the equinoxes near equator
and unimodal around the summer solstice at higher latitudes (unimodal around the winter
2
solstice on the southern hemisphere). INTERCOM measures Angots value in MJ/m /d units.

500

40

400
Angots value
2

[MJ/m /d]

[W/m ]

30
300
20

200

10

100

0
0

100

200
Day of year

82

300

0
30 N
60 N

6.1. Light absorption explained

83

A weather station will usually register total daily irradiation per m2. But to calculate daily
photosynthesis we need more detailed information than that: How much of the irradition is
diffuse and how much is direct? How is irradiation distributed over the day?
The fraction of light that gets dissipated and thus turns diffuse depends on the atmosphere,
foremost the cloud cover. However, there exists an empirical relation between the fraction of
light that gets through the atmosphere (i.e. the irradiation measured by the weather station in
proportion to Angots value) and the fraction of light that is diffuse.
1.0
0.8
Fraction of

0.6

diffuse light
[0;1]

0.4
0.2
0.0
0

10

20

30

40
2

Measured irradiation [MJ/m /d]

The figure show this relation at 55 N on Julian day 120. The fraction of diffuse light decreases
with increasing measured irradiation, from 100% at low light levels to a minimum of 23% when
the light is most intense.
The course of light intensity over the day goes from zero at sunrise to a maximum at midday,
when the sun is in zenith, and then down to zero again at sunset. The measured irradiation is the
average over the whole day, and it follows that the maximum intensity will be larger than the
measured daily average. Hours in this context are astronomically defined, irrespective of time
zones and daylight saving schedules. Only part of the sunlight is in the frequency spectrum
utilized by photosynthesis. This photosynthetically active radiation (PAR) comprises half of the
total sunlight energy.

300
PAR

total
200

direct

[W per m2 ground]

diffuse

100
0
0

12
Time of day [h]

18

24

Chapter 6. The INTERCOM model

84

The figure shows the course of indirect, direct and total PAR at 55 N on Julian day 120 with a
2
2
measured irradiation of 20 MJ/m /d (231 W/m , since 1W = 1J/s). A rough numerical integration
2
2
to calculate the average total PAR from this figure yields 115.7 W/m (9.996 MJ/m /d),
corresponding to half of the measured irradiation, as expected. INTERCOM measures PAR in
2
W/m units.
To calculate photosynthesis we must integrate over the whole day from sunrise to sunset.
To speed up this calculation INTERCOM applies Gaussian integration. For this, every day, the
rate of photosynthesis needs only to be calculated three times during the afternoon. The total
photosynthesis over the whole day is then calculated as a weighted average of these three point
values. The specific times will vary according to latiude and day of the year. At 55 N on Julian
day 120, for example, photosynthesis will be calculated on 12:50h, 15:43h and 18:58h. The
weights attributed to these are fixed (0.28, 0.44 and 0.28) and sum up to 1.
The density and structural characteristics of the plant canopy are important for the resulting
photosynthesis. First we will consider a canopy consisting only of the leaves of one species.
Later we will generalize this to any number of organs and any number of species. The vertical
distribution of leaf area can be summarized by an equation, such as a parabola, which will yield
a symmetric distribution of area on the vertical axis.
5
4
Leaf density
2

[m leaf per m space]

3
2
1
0
0.0

0.2

0.4

0.6

0.8

1.0

Height above ground [m]

Described this way, the variable actually is a leaf density measured in m2 leaf per m3 space. In this
example, maximum plant height was set to 1 m and the total leaf area index (LAI) of the canopy
was set to 3. The leaf density at 0.5 m is larger than 3 m-1, so if the canopy was this dense all over,
LAI would be larger than 3. But at the bottom and the top of the canopy, this is compensated for
by a leaf density smaller than 3 m-1, so it all adds up to LAI equal to 3.
If we integrate leaf density vertically, accumulating the total leaf density from a certain
height above the ground and up to the top of the canopy, we arrive at the LAI above that height.
After factoring in the vertical integration in meters, we get the proper LAI units of m2 leaf per
m2 ground.

6.1. Light absorption explained

85

LAI above height

[m leaf per m2 ground]

0
0.0

0.2

0.4

0.6

0.8

1.0

Height above ground [m]

To model photosynthesis down through the canopy, we must integrate photosynthesis from
the top of the canopy downwards. To achieve this INTERCOM again uses Gaussion integration
but, in stead of calculation at 3 points as for PAR during the day, we need 5 points to obtain proper
precision. The 5 points are located at 5%, 23%, 50%, 77% and 95% of maximum plant height.
Their weights (0.12, 0.24, 0.28, 0.24 and 0.12) again add up to 1 for the weighted average, which
is a mathematical approximation of the integrated photosynthesis over the whole canopy.
We are now all set to begin the actual calculation of light absorption and CO2 assimilation:
We know the latitude, day of the year, time of the day, diffuse and direct PAR, and the LAI above
and the leaf density at a certain height in the canopy. We must repeat the calculation 15 times to
cover the 3 integration points during the day and 5 integration points down the canopy. In the end
we add all the calculated light absorption and assimilation rates, applaying the pertinent weights
of Gaussian integration and end up with the total light absorption and assimilation of the day.
First we make a further subdivision of the incoming direct light, which we now call total
direct light. The part of direct light that is directly absorbed as such by the leaf we call directdirect light. The remainder is dispersed and results in secondary diffuse light. The extinction
coefficient of the leaves can be measured empirically under 100% diffuse light and is then called
kdf . The extinction coefficients for total direct light (kdr,t) and for direct-direct light (kdr,bl) both
depend on sun height and thus on latitude, day of the year and time of the day.
8
Extinction
coefficient
[-]

Type of light:

diffuse
4
direct-direct
2

direct total

0
0

12

18

24

Time of day [h]

In this example, it can be seen that direct light is extinguished effectively when the sun is low.

Chapter 6. The INTERCOM model

86

So, when the sun is low, whatever little direct light there is, dies out quickly in the canopy.
The light penetrating to a certain level in the canopy decreases exponentially with the
effective LAI above that level. The effective LAI is the LAI times the extinction coefficient
(page 36 in Kropff & Laar 1993). For reasons explained further down we will instead call this
the effective extinction. Anyway, we can calculate the rate of light penetration for all three kinds
of light, applying the appropriate extinctions coefficient. However, a fraction of the light is
immediately reflected by the canopy and is thereby not available for absorption. Leaf reflectance
differs for the three kinds of light but, surprisingly, can be assumed equal for all plant species.
It has a fixed value for diffuse and direct-direct light whereas it depends on sun height for the
direct-total light.
0.2
Leaf
reflectance
[-]

Type of light:

0.15

diffuse
0.1
direct-direct
0.05

direct total

0.0
0

12

18

24

Time of day [h]

The light available at any height in the canopy can now be calculated from the total LAI
above that height and the pertinent extinction coefficients and reflectances. Here it is shown at
2
15:43h, the second integration point of the day, keeping the parameter settings so far (20 MJ/m /d
of sun light impinging at 55 N on day 120).
100
Type of light:

80
Available

diffuse

60
light
2

[W per m ground]

direct-direct

40

direct total
20
0
0.0

0.2

0.4

0.6

0.8

1.0

Height above ground [m]

To obtain how much of the available light is actually absorbed at any height in the canopy,
we just need to multiply the available light with the pertinent extinction coefficients.

6.1. Light absorption explained

87

100
Type of light:

80
Light

diffuse

60
absorption rate
2

[W per m leaf]

direct-direct

40

direct total
20
0
0.0

0.2

0.4

0.6

0.8

1.0

Height above ground [m]

The diligent reader will have noticed that the units changed from available W per m2 ground
to absorbed W per m2 leaf (eq. 4.12 in Kropff & Laar (1993)). How could this be accomplished
by multiplication with the extinction coefficient, which is after all unitless? Well, consider the
negative exponential law of light extinction: exp ( k LAI ). If we consider LAI unitless, k
becomes unitless by implication. But if we consider LAI in m2 leaf per m2 ground then k must
have the inverse dimension, m2 ground per m2 leaf. And, if we apply this dimension as we
multiply with k to go from light availability per ground area to light absorption per leaf area, the
units work out nicely.
To calculate the light absorption rate of shaded leaves (Ia,sh), i.e. leaf area not struck by
light directly, we take from above the absorption of diffuse light (red curve) and add to that
absorption of secondary diffuse light, which is simply the difference between the absorbed total
direct light (yellow curve) and direct-direct light (blue curve). This yields the red curve below.
100

50

80

40

absorption rate

60

30

for shaded leaves

for shaded leaves

40

20

[kg CO2 per ha leaf

20

10

per hour]

Light

[W per m leaf]

0.0

0.2

0.4

0.6

0.8

Assimilation rate

1.0

Height above ground [m]

Photosynthesis turns assimilated CO2 into carbohydrates using the energy of the absorbed
light. In INTERCOM the assimilation rate is expressed in the (akward, you may think) units
of kg CO2 per ha leaf per hour. The light response curve, which converts absorbed light into
assimilated CO2, is defined by the conversion efficiency (kg CO2 per ha leaf per hour per (W
per m2 leaf)) and the maximum assimilation rate Amax (kg CO2 per ha leaf per hour); can also
2
6+3
4
be expressed in more intuitive units, such as g CO2 per MJ, by multiplication with 10 /10 /60
= 27.78.

Chapter 6. The INTERCOM model

88
50
40
Assimilation rate
30
[kg CO2 per ha leaf
per hour]

20
10
0
0

100

200

300

400

500

Light absorption rate [W per m2 leaf]

The curvature of light saturation causes assimilation (blue line above) to be less efficient towards
the top of the canopy where light is most intense. The parameters and Amax vary with plant
species, leaf quality and environmental conditions. Storkey (2005) determined the empirical
relationship between and Amax and temperature (T):
= 0.0095T + 0.635
Amax = 50(1 0.882T )
We used these relations here, applying the values at 20 C, = 0.445 kg CO2 per ha leaf per hour
per (W per m2 leaf) and Amax = 45.9 kg CO2 per ha leaf per hour. The upper limit on Amax was set
to 50 kg CO2 per ha leaf per hour, whereas in the original paper it was operating in other units.
The calculation of light absorption by sunlit leaves is more complicated because the absorption rate depends on the angle of the leaf surface with respect to the sun. The leaf distribution
is assumed to be spheric which means that all leaf angles are equally represented; one can think
of the green area in the canopy as a uniform, green sphere, the intensity of green corresponding
to the LAI. The light flux hitting this sphere perpendicularly, relatively to the light flux hitting
the ground (the measured direct PAR per ground m2), depends on the height of the sun. At the
equator at noon the two fluxes are equal but at lower heights of the sun, the relation shifts (in
proportion to the shadow that the sphere would cast) while at the same time the intensity of sunlight drops.
The net effect can be seen here at 55 N on Julian day 120. As both sun height and sun light
approaches zero, the perpendicular light intensity approaches zero divided by zero; hence, it is
shown only from early morning until late afternoon.

6.1. Light absorption explained

89

Incoming
perpendicular PAR

200

[W per m leaf]
100
Incoming
direct PAR
[W per m2 ground]

0
0

12

18

24

Time of day [h]

The calculated rate of light hitting perpendicularly can be used to calculate the absorption
rate of the whole canopy, which will be hit at all angles, according to the spheric leaf distribution
assumption. This integration over all leaf angles is carried out in INTERCOM using a 3-point
Gaussion integration. To get the total absorption rate of sunlit leaves, we must add to this, the
absorption rate of diffuse light, which will be the same as calculated above for shaded leaves.
Finally, this total light absorption rate of sunlit leaves is turned into an assimilation rate
by the same light saturation curve as for shaded leaves, exemplified here at 15:43h, the second
integration point of the day.
150
60

Light
absorption rate
for sunlit leaves
2

100
40

Assimilation rate
for sunlit leaves
[kg CO2 per ha leaf

50

20

[W per m leaf]
0

per hour]

0
0.0

0.2

0.4

0.6

0.8

1.0

Height above ground [m]

Knowing the absorption and assimilation rate for both shaded and sunlit leaves, we only
need to divide the leaf area into these two proportions. Assuming a random distribution of leaf
area, the proportion of sunlit leaves is simply the negative exponential of the leaf area index
weighted by the extinction coefficient for direct-direct light (kdr,bl; bl is for black which makes
sense in this context, since we are calculating the area not obstructed by leaves).
Continuing our example from 55 N, Julian day 120, we get this profile of direct sunlight
filering down through the canopy at 15:43h.

Chapter 6. The INTERCOM model

90
1.0
0.8
Fraction sunlit

0.6

leaves [-]

0.4
0.2
0.0
0.0

0.2

0.4

0.6

0.8

1.0

Height above ground [m]

Now, at any height we know both the fraction of shaded and sunlit leaves and their rates of
absorption and assimilation. We can obtain the net total light absorption and CO2 assimilation at
any height in the canopy, as the sum of the contributions from shaded and sunlit leaves, weighed
by their fraction of the the total. We get curves that go from the rates of sunlit leaves at the top
of the canopy to the most shaded leaves at the bottom.
150
60

Light
absorption rate
of leaves total
2

100
40

Assimilation rate
of leaves total
[kg CO2 per ha leaf

50

20

[W per m leaf]
0

per hour]

0
0.0

0.2

0.4

0.6

0.8

1.0

Height above ground [m]

But these rates are still per leaf area. To proceed we have got to convert them to a per ground
2
area base. For that purpose we multiply the rates down the canopy with the leaf density (m leaf
per m3 space) at that height. To convert from leaf density to leaf area index, we also multiply
with plant height (set to 1 m, in this example). Thus the units per leaf area in the figure above
are multiplied with m2 leaf per m2 ground or, equally, ha leaf per ha ground, which yields the
units per ground area in the figure below. Since we chose a parabolic model of leaf density,
the resulting rates turn out quite small at the top of the canopy, because leaf density here is
quite small.

6.1. Light absorption explained

91

500

250

400

200

absorption rate

300

150

of leaves total

of leaves total

200

100

[kg CO2 per ha ground

100

50

per hour]

Light

[W per m ground]

Assimilation rate

0
0.0

0.2

0.4

0.6

0.8

1.0

Height above ground [m]

At this point you may have forgotten what the points are used for: They are used as a
shortcut to integrate the curves via Gaussion integration. If you leaf back through the figures,
curves with 5 points on them, really exist in 3 versions, one for each integration point during the
day. And curves with 3 points on them, really exist in 5 versions, one for each integration point
through the canopy. To arrive at the total amount of light absorption and CO2 assimilation for
the whole canopy and the whole day, we need to integrate these 15 curves, first over the canopy
and then over the day.
In our example, integration over canopy height yields this course of the whole-canopy rate
during the day.
300

150

200

100

100

50

Light
absorption rate
for leaves total
[W per m2 ground]

Assimilation rate
for leaves total
[kg CO2 per ha ground
per hour]
0

0
0

12

18

24

Time of day [h]

Taking the integration one step further, using the 3 Gaussion points to integrate these curves
over the day, we arrive at a light absorption rate of 156.74 W per m2 ground and an assimilation
rate of 42.23 kg CO2 per ha ground per h. To factor out time and arrive at the finite rates per day,
we must multiply by daylength (14.84 h, in this case). Thus we arrive, finally, at the end of the
calculations with 8.37 MJ absorbed per m2 ground and 641.42 kg CO2 assimilated per ha ground.
This should be held up against the total daily irradiation, set at 10 MJ PAR per m2 ground in
our example.
Lets congratulate ourselves with this achievement! But we are not quite finished yet. In
our canopy model we limited ourselves to consider only one population, namely that of a population of leaves with a parabolic vertical distribution. But in reality a canopy may consist of
any number of plant organ populations, leaves, stems, flowers, fruits, belonging to one or more
species. We must take a deep breath, retrace our steps and go through the logic right from the

Chapter 6. The INTERCOM model

92

beginning and see, which calculations would need to be changed to accomodate a multi-population canopy.
Our first discovery is the leaf density to height relation. There will, in general, be one such
relation, particular to each population present and possible of different shape, total LAI, and
maximum height. Consequently we must imagine the canopy as a multitude of such curves. Lets
consider three populations.
5
4
Leaf density
2

[m leaf per m space]

3
2
1
0
0.0

0.2

0.4

0.6

0.8

1.0

Height above ground [m]

Each curve translates easily into the cumulative curve of that populations LAI above a certain
height .
3

LAI above height

[m leaf per m2 ground]

0
0.0

0.2

0.4

0.6

0.8

1.0

Height above ground [m]

The light available down through the canopy still decreases exponentially with the total
LAI above any particular. The only difference in the multi-population case is that the effective
extinction (k LAI) must be summed for all populations, applying their pertinent extinction coefficients.
The remaining calculations will remain, irrespective of the number of populations present.
The calculations just need to be repeated for each population to arrive at its daily finite rates of
light absorption and CO2 assimilation. It is a minor step then, in the end, to add up the finite daily
rates of light absorption and CO2 assimilation for each species, summing up the contributions
from the populations of plant organs belonging to that species.

6.1. Light absorption explained

93

To finish the story, we must subsequently turn the daily rate of CO2 assimilation into a
daily rate of biomass accumulation. This is achieved first by multipliction with 30/44 which is
the photosynthetic exchange rate from CO2 to CH 2O (carbohydrates, "sugars"). Part of these
carbohydrates is lost immediately to maintenance respiration while the rest is distributed among
the plant organs, according to the prevailing allocation scheme. But even the actual incorporation
of those carbohydrates comes at a cost, growth respiration, before the remainder is finally bound
as plant biomass. All this logic can be expressed straightforwardly in C++, as will be shown in
the following.
6.2. Light absorption refactored
We view a multispecies plant community as a composition of structural levels: community,
plant populations, plant organs and organ sub-components. This example shows the resulting
hierarchy in a community of just two populations, a crop and a weed:
community
wheat

height

leaves
area

mass

stem
area

mass

cheal

grains
area

root

mass

height

mass

stem

leaves
area

area

mass

root

mass

mass

Each of the boxes correspond to an object in the running model, and each arrow denote
a parent-child relationship. In this case the crop is composed of four organs and the weed of
three organs. The green organs each hold an object representing its area. All organs in addition
holds a mass. Both plants also hold an object to keep track of plant height. The areas have been
emphasized with a green background.
If we look at the classes these objects belong to, we can see that we need a total of six classes
to define this model (Community, Plant, Height, Organ, Area and Mass):
Community
Plant

Height

Organ
Area

Mass

Organ
Area

To be continued

Mass

Plant

Organ
Area

Mass

Organ
Mass

Height

Organ
Area

Mass

Organ
Area

Mass

Organ
Mass

Chapter 7. Student projects


The student projects are the results of the students efforts to build their own plugin models for
Universal Simulator under the supervision of Niels Holst, Aarhus University, Denmark. The
models are documented here in the studentsown words and are all easily accessible, as they form
part of the standard installation of Universal Simulator.
Note: My original thought was that all student models eventually would be added to this
chapter. I have since then realised that this leads to update problems that cannot be resolved. So,
here are two models presented by the brave students attending the first year (2011) the modelling
course was run.
7.1. Lake oxygen model
Anders Nielsen, Aarhus University, Denmark [an@dmu.dk]
7.1.1. Introduction
Net community production (NCP), defined as the difference between gross primary production
(GP) and total (algal (RA) plus heterotrophic (RH)) community respiration (RT), derives defines
the metabolism of a biological community (Wetzel 2001). Unfortunately, measurements of
GP and RT and the derived NCP is relatively time consuming. For that reason empirical or
statistical relationships between easily and low cost measurements and NCP is of particular
interest. Such empirical relations have been developed in oceanography (see Serret et al. 2009),
whereas compilation of similar relations for freshwater lakes according to our literature review
is very limited. We have conducted a statistical analysis of a comprehensive high frequency data
set from 24 mesocosms including easily obtainable measurements and NCP and compiled an
empirical relation to derive NCP for a given lake. The statistical analysis is still in progress and
calculations of NCP by the UniSim plug-in should only be trusted as a broad term estimate.
Data for the statistical analysis is based on work conducted by Liboriussen et al. 2010,
where GP and RT haves been calculated on a 30 minute time step for a 5 year period from 2003
to 2008. Data has been sampled from 24 mesocosms designed as cylindrical stainless steel tanks
1.9 m in diameter and a water depth of 1 m simulating 2 nutrient levels with 3 temperatures in 4
replicates. More details about design and set up of the mesocosms, see Liboriussen et al. 2005.
7.1.2. Calculations
In the following a brief description of the calculations and description of required variables
when using the UniSim plug-in is presented. For overview of the different required variables see
Table 7.1. The variables must be given on a daily time step.
Dissolved Oxygen Concentration Saturation Percentage
The saturation concentration of oxygen is a function of primarily temperature. Calculation of
94

7.1. Lake oxygen model

95

Table 7.1. Variables necessary as input to perform calculations. An example of the input text
file is given in the UniSim weather folder (LakedataOBS2004-2005.txt).
Name

Unit

Variable name

Date

[dd/mm/yyyy]

date

LakeID

[-]

LakeID (ignored)

Oxygen concentration

[mg l ]

obsDO

Water temperature

[C]

tempw

Daily Light Integral

[mol m-2 d ]

obsDLI

Wind speed

m-1

wind

-1

-1

saturation concentration is done according to American Society of Civil Engineering Committee


on Sanitary Engineering Research (1960):
DOsat = 14.652 0.41022Tw + 0.0079910Tw2 0.000077774Tw3
Where
DOsat:

Dissolved oxygen saturation concentration [g m-3]

T w:

Water temperature [C]

Percentage of Saturation
Afterwards the percentage of saturation for a given observed dissolved oxygen concentration is
calculated according to the following simple equation:
DOsat,obs = 100

DOobs
DOsat

PAR (Photosynthetically Active Radiation)


PAR (Photosynthetically Active Radiation), wavelength 400-700 nm [mol m-2 sec-1] is a key parameter in plant growth through the processes of chlorophyll synthesis and photosynthesis which
result in the conversion of radiant energy into chemical energy. Thus availability of PAR radiation is an important factor for primary production in aquatic systems like lakes (Wetzel 2001).
Unfortunately PAR is often not available as a widespread measurement at any spatial location.
However PAR can be calculated as a constant ratio or function of the broadband solar radiation
if no measurements are available (Jellison & Melack 1993, Alados & Alados-Arboledas 1999,
Udo & Aro 1999). The UniSim plug-in needs information about PAR given as Daily Light Inte-1
gral [mol m-2 d ]
Day Length
The day length is calculated in the UniSim package by the Calendar model (see page 145) as

Chapter 7. Student projects

96

a function of day number of the year (Julian day) and the latitude. The user of the lake oxygen
plug-in needs to specify the latitude of location in the xml file. For further information about
calculation of the day length, see Kropff & Laar 1993.
Net Community Production Equation
Based on a statistical analysis we have compiled a multiple linear regression with satisfactory
2
significant explained variation (R =0.253, N=24,738, F=4190, P<0.001). The equation is
presented below:
NCP = 0.014DOsat, obs + 0.0022DLI 0.081DayLength 0.787
Where
-1

NCP:

Net Community Production [gO2 m-2 d ]

DOsat,obs:

Dissolved Oxygen Concentration Saturation Percentage [%]

DLI:

Daily Light Integral [mol m-2 d ]

DayLength:

[hours]

-1

This prediction equation is implemented into the UniSim lake plug-in and calculates the NCP
based on lake specific inputs.
7.1.3. Predicting NCP in Real Lakes
When extrapolating the NCP model from mesocosms to real lake data, changes in system proportions and factors controlling governing processes must be considered. One process is the system
exchange of oxygen between water column and overlaying atmosphere (Odum 1956). Lake oxygen reaeration is primarily controlled by wind speed (Banks & Herrera 1977, Gelda et al. 1996),
while the mesocosms reaeration are generated from constantly mixing by artificial steering
(Liboriussen et al. 2005). The UniSim lake oxygen plug-in is developed to calculate the NCP for
real lake and not mesocosms, thus we have implemented the opportunity for the user to adjust
the reaeration coefficient to fit a given lake.
Several empirical relations has been publish where reaeration coefficient
is estimated from wind speed as only important parameter (Liss 1973, Emerson 1975,
Banks & Herrera 1977, Deacon 1977, Mattingly 1977, OConnor 1983, Wanninkhof et al. 1985,
Boyd & Teichert-Coddington 1992, Livingstone & Imboden 1993, Portielje & Lijklema 1995,
Gelda et al. 1996, Gelda & Effler 2002, Crusius & Wanninkhof 2003). Thus, we have used the
empirical relation published by (Banks & Herrera 1977). Based on this relation the UniSim plugin calculates a lake specific reaeration coefficient from wind speed (see Table 7.1).
The system reaeration coefficient for the mesocosms in Lemming (K L,mes) is estimated to
-1

0.22 m d by Liboriussen et al. 2010. The Plug-in then use linear scaling, computed from the
ratio K L,lake / K L,mes between mesocosms system reaeration coefficient and the individual lake
specific reaeration coefficient (K L,lake) estimated from wind speed, to correct our NCP model to

7.1. Lake oxygen model

97

individual lakes.
Furthermore the user can specify a range for the K L,lake parameter used as input to a
stochastic number generator generating the coefficient K L,lake,Random. This coefficient is also
used to calculate a NCP from linear scaling by the ratio K L,lake,Random /K L,mes. Thus the user can
view different estimations of the NCP where uncertainty on the reaeration coefficient implicit
is included.
If the user has limited knowledge about a lake specific system reaeration coefficient,
estimations from wind is the best approach. For that reason we derive the average reaeration
coefficient estimated from wind speed and present it in a plot (see section about plotting). Based
on this particular plot, the user can set the ranges for the stochastic number generator and thereby
quantify the NCP in a broader range and implicit account for uncertainty.
The reason why so much effort is put into this module is that the reaeration coefficient as
parameter is difficult to measure directly and thereby is uncertain to estimate as well.
7.1.4. Unit of output
Daily accumulated NCP is default calculated as mass oxygen production per square meter
-1
surface area per day [gO2 m-2 day ], however, the user can choose to change the unit to carbon
instead by taking into account the difference in atom mass between oxygen and carbon. This is
easily done by simply changing the parameter unit from 1 (oxygen) to 0 (carbon) in the model
XML file.
7.1.5. Setting the stochastic sampling number
In the model XML file the user can specify the number of iterations one batch model run
performs. Control of this parameter is of use if any post hoc statistical analysis is conducted.
By default the model performs 30 single runs in each batch where the reaeration coefficient is
changed each time within the user specified range (min and max for the stochastic sampling
range is also set in the XML file).
7.1.6. Plotting
WHen the simulation is run, output appears in several plots on the screen. Below their meaning
is explained.
Lake environment
Lake environment is an overview of the observed parameters: Daily Light Integral (DLI), wind
speed and Day length, variables classified as outer variables in respect to the lake as system. The
plot is simply graphs drawn from the input file where all variables are given on a daily time step,
but is presented to give the user overview.
Observations
-1

Observations is an overview of the in-lake observed parameters: oxygen [mg l ] and water
temperature [C] read from the input file and given on a daily time step.
Averaged estimated reaeration coefficient (from wind speed)

98

Chapter 7. Student projects

If the user has no knowledge about the reaeration coefficient for a specific lake, a value computed
from wind speed is the best estimate. Thus by looking at the average plot the user can then get
help to estimate the stochastic sampling range for the reaeration coefficient.
Net community production
Net community production presents two graphs (1) NCP (K L estimated from wind) and (2) NCP
(K L stochastic). (1) is the NCP where corrections in respect to reaeration coefficient is computed
from wind speed (see Table 7.1) whereas (2) is the NCP where corrections in respect to reaeration
coefficient is computed as and stochastic sampling process based on a user defined range.
Parameter
The stochastic sampling of parameter values for the reaeration coefficient based on a user
defined range is presented in the Parameter plot where each individually sampled value is plotted,
thus the user can view the actually sampled values.
Accumulated Net Community Production
The UniSim lake oxygen plug-in calculates NCP on a daily basis. However, for comparable
reasons the present calculations is summarize from daily values to an accumulated yearly net
community production. Following the curve, the accumulation is reset at the first of January each
year and thereby gives the yearly calendar net community production.
7.1.7. Output from the model
In the XML file output from the lake oxygen model is specified. The model automatically creates
an output file containing all parameters necessary for the calculations as well as calculated values
of dissolved oxygen concentration saturation percentage, net community production (both with
corrections where reaeration coefficients are estimated from stochastic sampling and from wind
speed, respectively). The UniSim model creates one file for each stochastic parameter estimate,
which can be used for post hoc statistical analysis.

7.2. Microbial community model

99

7.2. Microbial community model


Yun-Feng (Kevin) Duan, Aarhus University, Denmark [kevin.duan@agrsci.dk]
7.2.1. Introduction
Microbial community model simulates the composition and activity of microbial communities.
It is composed of a series of sub models, each simulating one aspect of the complex of microbial
community. For example, population model mimics the population of a microbial species and
its growth, competition model imitates the competition for common resources, reaction models
emulates microbial metabolic activities, and effect model reproduces the effect of environmental
factors. These models can be combined together to simulates the facets of interest of the
microbial community under study. Furthermore, microbial community model offers the ability
to construct communities stochastically. This feature is very useful in exploring how community
structure affects community function and response to stress.
7.2.2. Population model
Population is the basic structural unit of a community. Similarly, the Population model is the
basic building block of more complicated community models. Population model describes
some of the important parameters of a microbial population, e.g. species name, initial density,
growth rate, mortality rate, metabolic dynamics, etc., and these parameters are used by other
models to simulate microbial activities.
Prerequisite
A UniSim::Calendar model with the name calendar must be placed in the XML file. This
model is required by Population model.
7.2.3. Population Growth
The Population model is to be used in combination with other models, so it cannot do anything
on its own, except for growth. The growth of a population is characterized by parameters
GrowthRate (g) and MortalityRate (m), and the observed growth rate is:
n = n (g m)
t
where n is the current density of the population. As long as g > m, the growth will follow an
exponential curve (Fig. 7.1, Left).
In real world situations, the growth of a population is limited by available environmental
resources so the population cannot grow indefinitely and will eventually reach a plateau (Fig. 7.1,
Right). This kind of growth is called logistic growth, and can be easily simulated by introducing
a new parameter CarryingCapacity (C). In that case, the observed growth rate becomes:
n = n [g (1 n/C) m]
t

Chapter 7. Student projects

100

When CarryingCapacity is set to a positive value, the Population model would behave
according to logistic growth; when its set to 0 or a negative value, exponential growth will be
presented instead. Note that Population model assumes infinite supply of resource during
growth (which means you will never see a decrease of density as long as g>m); to simulate
growth under limited resource, a Competition model should be introduced.
Demonstration
Model definition file Demo_PopulationGrowth.xml demonstrates exponential and logistic
population growth.
Model

Parameter

Value

Remarks

Population

InitialDensity

1000

Growthrate

0.03

MortalityRate

0.01

CarryingCapacity

For exponential growth

CarryingCapacity

10000

For logistic growth

Figure 7.1. Simulated population growth. Left: exponential growth; Right: logistic growth.

7.2.4. Competition Model


Competition model simulates the growth of one or more populations under competition for a
common resource of limited supply. To enable the model, simply set parameter EnableCompetition to True, and define the amount of available resource at the beginning of competition in
parameter InitialResource. It is possible in future development to select what competition

model to be used, but for now only one model (the Gutierrez-Baumgrtner functional response
model) is available. Each population is considered a consumer for the common resource in the
competition. For each consumer to sustain itself, a certain amount of resource is required, and this

7.2. Microbial community model

101

is called "demand". Demand of the ith consumer (Di) in time t is dependent on the population
density (ni) and the demand rate (i), and is defined as:
Di = ni i t
However, in a limited environment, the demand of each consumer may not be realized due to the
consumers inability to acquire resource or the insufficiency of resource. So, in the case of no
interspecific competition, the actual resource consumed by the ith consumer (consumption,
noted as Ri), is dependent on the consumers ability to find the resource (determined by
search rate i), and the available resource in the environment (R). Ri can be modelled by the
Gutierrez-Baumgrtner functional response model (Gutierrez 1992):

Ri = Di

(1 e )
i R
Di

So, the actual growth of the ith consumer is now dependent on its demand and consumption,
which can be characterized by the supply/demand ratio:
R

i
Ri
i =
= 1 e Di
Di

And the observed growth rate for the ith consumer becomes:
ni
= ni gi i mi
t

Note that in the presence of a Competition model, the carrying capacity for a population is
implicitly determined by the available resource S which is determined by the Competition
model, so exponential instead of logistic growth would be used.
With the introduction of supply/demand ratio , the observed growth rate could now
become negative, indicating decrease of population density (Fig. 7.2). It should be noted that
when the calculated population density drops below 1, Population model will return 0 as the
output value. This ensures that population can "extinct" during competition since mathematically
the progressive decrease of density would only approximate zero indefinitly but never really
reach it. The total consumption of all consumers is:
Rtotal = Ri
i

Chapter 7. Student projects

102
And the remaining resource R is updated in each step as:
R R Rtotal

When R approaches zero, the calculated Rtotal could become greater than R. In that case we
assume that the consumers exhaust the resource completely, dividing the remaining resource
among them in proportion to Ri:

Ri

Ri
Rtotal R

Demand rate () and search rate (a) are defined in Population model as parameters DemandRate and SearchRate; Competition model will try to inquire their values as well as the
value of pull variable Density from Population model during simulation. Supply/demand
ratio () is calculated by Competition model and sent back to Population model, and can be
accessed through pull variable SupplyDemandRatio. Remaining resource (R) can be accessed
through pull variable AvailableResource from Competition model.
Demonstration
Model definition file Demo_PopulationGrowth.xml demonstrates exponential and logistic
population growth.
Model

Parameter

Value

Population

InitialResource

10000

Population_1

InitialDensity

500

Growthrate

0.04

MortalityRate

0.01

SearchRate

0.01

DemandRate

0.02

InitialDensity

1000

Growthrate

0.03

MortalityRate

0.01

SearchRate

0.015

DemandRate

0.03

Population_2

Remarks

7.2.5. Reaction Models


Examining the dynamics of microbial metabolic activities is an important part of microbial
ecology studies. Although the real situation could very well be much more complicated, in many

7.2. Microbial community model

103

Figure 7.2. Simulated competition of 2 populations. Left: the change of population (red and blue) and
community density (yellow); Right: the decrease of available resource

cases, these activities are reduced to simple enzymatic or chemical reactions, and they can be
simulated by reaction models.
There is a group of different reaction models to suit different senarios. All reaction models
take only one parameter InitialSubstrate. But during simulation, they will also try to
inquire parameter values describing metabolic dynamics from Population models. Each
reaction model would inquire parameter(s) from Population model during simulation, and this is
described in each section respectively.
Reaction models send current reaction rate and substrate concentration as output and they
can be accessed through pull variables Velocity and Substrate respectively.
NOTICE: A model of the type MicrobialCommunity::Reaction does exist, but it is
only meant as the base model for implementation. The model Reaction should never be used in
the simulation.
EnzymaticReaction Model
The metabolic activities of microorganisms are catalyzed by enzymes, so the EnzymaticReaction model is the fundament of all other Reaction models.
An enzyme catalyzed reaction could take several substrates, but in studies ususally only
one substrate is considered the limiting factor. For example, the monooxygenase in methane-oxidizing bacteria (MOB) oxidizes methane to formaldehyde through a reaction that also requires
oxygen. But in an aerobic environment where MOBs are most active, oxygen is ample and the
availability of methane limits the reaction. So, in situations like this, the dynamics of microbial
metabolic activity can be simplified to single-substrate enzymatic dynamics, and can be described
by Michaelis-Menten equation (Fig. 3, Up-left):
V S
V = S = max
Delatt K m + S

Chapter 7. Student projects

104

where V is the velocity of reaction, S is the substrate concentration, Vmax is the maximum velocity
and K m is the Michaelis-Menten constant.
The integrated form of Michaelis-Menten equation describes how substrate concentration
decreases over time (Fig. 3, Bottom-right, Red):

(S0 S) + K m ln

()

S0
= Vmax t
S

EnzymaticReaction model would inquire two parameters from Population model:


MaximumVelocity, which is corresponding to Vmax, and MichaelisMentenConstant,

corresponding to K m.
ZeroOrderReaction Model
In certain cases, Michaelis-Menten equation can be approximated to simpler forms. If substrate
concentration S >> sK m, then V Vmax, and Michaelis-Menten equation can be approximated to
the rate equation of zero-order reaction (Fig. 3, Up-right):
S = k where k = V
max
0
0
t
In a zero-order reaction, the substrate concentration decreases linearly over time (Fig. 3,
Bottom-right, Blue):
S = S0 k 0 t
ZeroOrderReaction model would inquire parameter ZeroOrderRateConstant (k0) from
Population model.

FirstOrderReaction Model

Vmax
S, and Michaelis-Menten equation can be approxKm
imated to the rate equation of first-order reaction (Fig. 3, Bottom-left):

On the other hand, if S << K m, then V

S = k S where k = Vmax
1
1
Km
t
In a first-order reaction, the substrate concentration decreases along an exponential decay curve
over time (Fig. 3, Bottom-right, Yellow):

7.2. Microbial community model

105

S = S0 ek1t
FirstOrderReaction model would inquire parameter FirstOrderRateConstant (k1)
from Population model.

Reaction by Several Populations


When there are several populations present in the environment that ultilize the same substrate, the
change of substrate concentration is simply calculated by adding together the substrate uptake
of each population:
S = Si
i

Reaction with Changing Population Density


During prolonged experiment, the density of microbial population will likely to change. For
example, in a incubation trial of MOB with methane for several weeks, MOB populations will
grow in numbers and this will lead to increased rate of methane oxidation. Reaction models can
take the change of population density into account and run simulations as accurate as possible.
Lets say the initial population density is n0, and after time t the density becomes nt,
and the change of density is n. Since population density is positively correlated to enzyme
concentration, we can simplify the situation by treating density as enzyme cancentration directly.
Then, by deducing Michaelis-Menten equation, we have:

V(n =

kn0 S
Km + S

V(n =

knt S
Km + S

0)

t)

(Note: kn = Vmax)
From which we can define a density-activity coefficient :

V(n

t)

V(n

0)

nt
= 1 + n
n0
n0

It is easy to see that in an enzyme catalyzed reaction, change of population density will affect
Vmax but not K m; and in zero- and first-order reactions, the effect is on k0 and k1.
It should be noted that the change of population is dependent on population growth.

Chapter 7. Student projects

106

Logistic growth or growth under competition should be used instead of exponential growth,
which might generate unrealistic results.
In the case of changing population density, current reaction rate and substrate concentration
should be accessed through pull variables VelocityPDD and SubstratePDD respectively.
PDD stands for Population Density Dependent.
Demonstration
Model definition file Demo_Reaction.xml demonstrates the activity of methane oxidation
by a MOB population. Population density dependent reaction is demonstrated in a separate file
Demo_Reaction_PDD.xml, the result of which is not shown below.
Model

Parameter

Value

Population

InitialDensity

1000

ZeroOrderRateConstant

25

FirstOrderRateConstant

0.004

MichaelisMentenConstant

800

MaximumVelocity

30

EnzymaticReaction

InitialSubstrate

10000

ZeroOrderReaction

InitialSubstrate

10000

FirstOrderReaction

InitialSubstrate

10000

Remarks

7.2.6. GeneralEffect Model


In microbial ecology studies, it is often to examine the effect of environmental factors on
microbial activities, which could be either stimulative or inhibitory. Simulation of these effect is
achieved by including an effect model.
To activate an effect model, the value of parameter EnableEffect should be set to True;
then, parameter TargetPopulations determines the populations affected under the effect.
TargetPopulations is flexible and can take several forms of input to suit different needs:

All (or simply *): all populations are affected.

AllBut:{List_of_Population_Models}: all populations are affected, except for

those given in the list.

Specified:{List_of_Population_Models}: only those populations given in the list


are affected. E.g. Specified:{Bacterium_1, Bacterium_2, Bacterium_3}.

Random:{List_of_Population_Models}: a random group from those populations

given in the list are affected.

Random:{Min, Max}: a random group from all populations with size ranging from Min
to Max are affected. Min must be equal to or greater than 1.

7.2. Microbial community model

107

Figure 7.3. Simulated microbial methane oxidation. Up-left, Up-rightBottom-left: dependence of


reaction rate on substrate concentration (enzymatic, zero order, and first order reaction); Bottom-right: the
decrease of methane concentration over time (Red: enzymatic reaction, Blue: zero order reaction, Yellow:
first order reaction).

Random:{All} or Random:{*}: a random group from all populations are affected. This
is equivalent to Random:{1, Number_of_Populations}.

In each implementation of individual effect model, additional parameters are required in order
to perform respective simulation, and this is described in each section of the model.
NOTICE: A model of the type MicrobialCommunity::Effect does exist, but it is
only meant as the base model for implementation. The model Effect should never be used in
the simulation.
GeneralEffect Model
GeneralEffect is a simple implementation of Effect model which simulates the effect of an
environmental factor on the properties of populations. A simple usage of the GeneralEffect

model is to simulate the effect of temperature on the growth of microorganisms.


GeneralEffect has two additional parameters: TargetParameter and EffectRatio.
TargetParameter determines which parameter of the Population models is affected, e.g.
GrowthRate, MortalityRate, or MichaelisMentenConstant. The strength of the effect

Chapter 7. Student projects

108

is determined by EffectRatio, which can take the following forms of input:

Uniform:{Value}: the strength is uniform among all populations and takes the value

specified in the curly brackets.

Range:{Min, Max}: the strength takes a random number between Min and Max.

specified:{List_of_Values}: this can only be used when TargetPopulations


is set to Specified, and the list of values must contain the same number of items as the
list in TargetPopulations. Each affected population will take one value in the order of

appearance. You can even define a range for the value, but slightly different from the above,
it should be written in the form of min-max. E.g. Specified:{0.2, 0.3-0.5, 0.6}.
Effect ratio is defined as the ratio of the parameter value under effect to the value without effect.
So, effect ratio less than 1means the factor is inhibitory, while ratio greater than 1means the factor
is stimulative, and equal to 1 means theres no effect at all.
CompetitiveInhibition Model
CompetitiveInhibition implements the effect of a competitive inhibitor on enzyme-cat-

alyzed reactions. Competitive inhibitor competes with the substrate for the active site of an enzyme. In the presence of a competitive inhibitor, the Michaelis-Menten equation becomes:

V=

Vmax S
[I]
where = 1 +
KI
K m + S

[I] is the concentration of the competitive inhibitor, and K I is the inhibition constant. As a result,
CompetitiveInhibition model has two corresponding parameters: InhibitorConcentration and InhibitionConstant. It can be used, for example, to simulate the competitive
effect of ammonium on methane oxidation by MOBs.
7.2.7. Community Model
The Community model provides a realistic way to simulate real world situations. In most
cases, it is recommended to use Community model as a container to hold other models such
as Population, Competition, Reaction, and Effect. This not only simplifies the model
definition in the XML file, but also presents a more flexible way to run the simulation.
As already discussed above, Competition, Reaction and Effect models can interact
with Population models during the simulation, by either inquiring parameter values, or affect
the behavior of Population models. It should be noted by now that Competition, Reaction
and Effect models only interact with Population models that are on the same level as
themselves. For example, consider the following structure of models:
<Community_1>
<Competition_1 />
<Population_1 />
<Population_2 />

7.2. Microbial community model

109

</Community_1>
<Community_2>
<Effect_1 />
<Population_3 />
<Population_4 />
</Community_2>
Competition_1 only affects Population_1 and Population_2, since they are all on
the same level (contained in Community_1); while Effect_1 only has an effect on Population_3 and Population_4. This behavior makes it possible to include several Community

models with different combination of submodels in one simulation and they can be insulated
from each other.
Stochastic Community
Another powerful feature of Community model is that it can stochastically select Population
models into the simulation. Coupled with UniSims RunIterator and random parameter
features, Community model provides an automated way to explore the effect of community
structure on community functions,
To generate stochastic communities, the parameter EnableStochasticCommunity
should be set to True. Then Community model takes three parameters to determine how the
stochastic communities are constructed:

MinPopulations: the minimum number of populations in the community;

MaxPopulations: the maximum number of populations in the community;

AlwaysIncludedPopulations: a list of Population models that should always be

included in the community.


When constructing a stochastic community, Community model flows the following steps:

1.

A random number between the values of MinPopulations and MaxPopulations was


generated, which determines how many populations will be selected into the community.

2.

Population models specified in AlwaysIncludedPopulations are entered with


priority. If there are more items in AlwaysIncludedPopulations than the number

generated in step 1, then those items will be selected randomly. To avoid this situation, set
MinPopulations to the number of items in AlwaysIncludedPopulations.

3.

If after step 2 therere still empty slots left, the rest of the Population models will be
selected randomly until all slots are filled.

Model Output
Community model can calculate a list of indices that describe the properties of the community,

110

Chapter 7. Student projects

including species richness (Richness), Simpsons index (SimpsonIndex), Shannon-Wiener


index (ShannonIndex), evenness (Evenness), and Gini coefficient (GiniCoefficient).
All indicies are calculated in real-time, that means, for example, if the density of one population
decreases to 0 during the simulation, the value of richness will decrease by 1. This allows a
glimpse into the detailed dynamics of community structural change instead of comparing status
at the beginning and the end of the simulation.

Appendix A. Plug-ins Reference


This appendix was generated directly from the source code of the UniSim plugins. Thus its
listings of model parameters, push and pull parameters are up-to-date with the code version
given below.
The Appendix is out-dated. In the current revision of the Universal Simulator software,
documentation will instead be generated as HTML documents that can be browsed (and
updated) moreeasily.
Version: 1.43.
A.1. awe plugin
The awe plugin contains an unpublished model of annual weed population dynamics in the
crop rotation. It was developed as a teaching tool for the ENDURE Summer School 2009 in
Volterra, Italy.
Author: Niels Holst, Aarhus University, Flakkebjerg, Denmark.
A.1.1. awe::Crop
The Crop model is quite simple as it does not contain a dynamic formulation of growht and
development. Rather, the crop is modelled only by its leaf area index (LAI) which follows a fixed
schedule according to the temperature sum (day-degrees above C) since sowing.
PARAMETERS
sowingDay

sowingMonth

harvestDay

harvestMonth

weedExchangeRate

0.6

maxYield

800

maxYieldLossPct

60

slopeYieldLossPct

0.5

Day in month of sowing.


Month of sowing.
Day in month of harvest.
Month of harvest.
Final biomass of weeds as a proportion of yield
loss (g/g).
2

Weed-free yield (g/m ).


Maximum yield loss (%) caused by weeds
(Cousenss a).
Initial yield loss per weed (% per weed density
equivalent) caused by weeds (Cousenss i).

111

Appendix A. Plug-ins Reference

112
((0
0)(110
0)(210
0.3)(310
0.8)(410
1.6)(510
2.9)(610
5)(1000
5)(1200
5)(1650 2))

Calendar for leaf area index (LAI) running on temperature sum since sowing (day-degrees above C).
Defined as a list of (temperature-sum LAI) pairs.

lai

double

Tsum

double

Leaf area index (m /m ).


Temperature sum since sowing (day-degrees above
C).

laiCalendar

VARIABLES
2

A.1.2. awe::InstantMortality
Once per year, at the given month and day, an InstantMortality object effectuates given
mortalities on one or more PlantGrowhtStage models. This can be used to simulate discrete
mortaly events caused by field operations, for example, spraying or soil cultivation.
It is natural to create InstantMortality objects as descendants (or, inside) of a Crop
model. The mortalities will then only be in effect when that crop is current in the Rotation.
PARAMETERS
day

month

mortalities

empty string

Day in month of imposed mortality.


Month of imposed mortality.
List of instant mortalities (0-100%) applied to the
different weed growth stages. Defined as a list
of (growth stage mortality) pairs. For example,
((seedling 100) (juvenile 80) (mature
10)), which will apply the respective
mortalities to all PlantGrowhtStage models
named seedling, juvenile and mature.

A.1.3. awe::PlantGrowthStage
A PlantGrowthStage holds two UniSim::Stage models inside, represing plant density
both as plants per m2 and density equivalents per m2. One density eqivalent corresponds to the
density of one plant that emerged simultaneouly with the crop. Later emerging plant counts as
less than one density equivalent per plant. Thus equivalence is meant as equivalent in terms of
competitiveness towards the crop
PARAMETERS

A.1. awe plugin

113

inflowAsDensity

inflowAsDensityEqs

instantMortality

Number of plants to enter this growth stage in the


next update (i.e. time step) (plants per m2 per day).
Number of density equivalents to enter this growth
stage in the next update (i.e. time step) (density
equivalents per m2 per day).
Instant mortality (0-100%) to apply to this growth
stage in the next update.

VARIABLES
outflowAsDensity

double

outflowAsDensityEqs

double

Number of plants that emerged from this growth


stage during the last update (i.e. time step) (plants
per m2 per day).
Number of density equivalents that emerged from
this growth stage during the last update (i.e. time
step) (density equivalents per m2 per day).

A.1.4. awe::Rotation
The Rotation model holds as children the Crop models that are part of the rotation. It keeps
check of the current crop according to cropping sequence and the harvest and sowing events
pertaining to Crop models.
PARAMETERS
crops

empty string

Sequence of crops in rotation. For example,


(maize wheat wheat), in which maize is followed by two crops of wheat. The crop names must
refer to names of Crop models that are children of
Rotation.

double

Leaf area index (m /m ) of the current crop.

VARIABLES
lai

A.1.5. awe::SeedBank
2

The SeedBank model holds the density of seeds in the soil (per ). Seeds are divide into two
groups: dormant and non-dormant. Newly produced seeds enter the seed bank as dormant. Dormancy is lost on 1 January every year, and all dormant seeds are then movedinto the non-dormant group.
PARAMETERS
initialDensity

1000

Initial density of the seeds in the seed bank (seeds


per m2.

Appendix A. Plug-ins Reference

114
emergenceCalendar

(0 0 5 10 20
40 10 5 0 0
0 0)

yearlyEmergenceRate

0.2

yearlyMortalityRate

0.1

The calendar shows the relative emergence of


seedlings per month in a scenario where no shade
is causing a reduction in emergence. The scale is
relative and needs not add up to a total of, e.g., 1 or
100. A daily calendar with values for
dailyEmergenceRatioPotential is constructed from this calendar and the yearlyEmergenceRate.
The proportion [0..1] of the seed bank that would
potentially emerge if no crop reduced emergence
by shading.
The mortality [0..1] of the seed bank per year.

cropLaiExp

0.04282

Exponent a in the equation to calculate cropEf5

fectOnEmergence, y = exp( ax2 ), where x is


the leaf area index of the current Crop.
dormantInflow

instantMortality

Use this to set the daily inflow of dormant seeds


into the seed bank (seeds per m2 per day). You cannot put non-dormant seeds into the seed bank.
The mortality (%) will be applied once in the next
time step, before new seeds of dormantInflow
are added. Dormant and non-dormant seeds will be
affected alike.

VARIABLES
number

double

dormant

double

nonDormant

double

dailyEmergenceRatio

double

totalEmergenceRatio

double

dailyEmergenceDensity

double

totalEmergenceDensity

double

cropEffectOnEmergence

double

Total number of seeds (dormant + non-dormant) in


the soil (seeds per m2).
Number of dormant seeds in the soil (seeds per
m2).
Number of non-dormant seeds in the soil (seeds per
m2).
Ratio [0..1] of seedlings emerging in this time step
(per day).
Accumulated ratio [0..1] of seedlings that have
emerged since 1 January.
Density of seedlings emerging in this time step
(seedlings per m2 per day).
Accumulated density of seedlings emerged since 1
January (seedlings per m2).
The effect [0..1] is a scaling factor applied to the
dailyEmergenceRatioPotential to achieve
the realised dailyEmergenceRatio.

A.1. awe plugin


dailyEmergenceRatioPotential

115
double

Potential ratio [0..1] of seedlings emerging in this


time step (per day). The realised ratio dailyEmergenceRatio depends on the shading effect of
the crop.

A.1.6. awe::Weather
The Weather model produces data for daily average temperature, assuming a sine curverelation
over the year, y = a + b( x + c )2, where x is the day of the year [0..365].
365
PARAMETERS
a

-0.75

17.2

Parameter a of yearly sine curve for temperature


(C).
Parameter b of yearly sine curve for temperature
(C).

VARIABLES
T

double

Tavg

double

Tsum

double

Daily average temperature ( C).


Same as T.
Temperature sum since 1 January Day-degrees
above 0 C.

A.1.7. awe::Weed
The Weed model holds the SeedBank model, PlantGrowthStage models for seedling,
juvenile and mature stages, and a UniSim::Stage model to represent seeds on the plant.
The Weed model orchestrates the progressive flow of weed individuals through these
models. For the PlantGrowthStage models there are parallel flows of density equivalents.
PARAMETERS
c1

6.904

Parameter in the equation that calculates density


equivalents from density, y = exp{c1[exp( x ) 1
c2
c
x
exp(
where
is
crop
leaf
area
index.
]}
1),

c2

0.7491

See c1.

seedProdSlope

seedProdExp

Slope a (seeds per gb) in the equation relating seed


production to final weed biomass, y = axbwhere x is
weed biomass (g).
Exponent b in the equation relating seed production to final weed biomass, y = axbwhere x is weed
biomass (g).

VARIABLES

Appendix A. Plug-ins Reference

116

The projected number of density equivalents (per


m2) is the final density equivalents expected, if there
will be no mortality applied to any growth stages.
The projected yield loss (%) is calculated from
projectedDeqs by way of the Cousens equation.

projectedDeqs

double

projectedYieldLossPct

double

projectedMass

double

The projected weed biomass (g/m ) is calculated


from projectedYieldLossPct applying the
weed/yield biomass exchange rate pertinent to the
Crop.

seedsDropping

double

double

The number of seeds (per m2 per day) dropping to


the ground during this time step. These originate
from the seedsOnPlant model.
Current seed multiplication rate for the seedsOnPlant model. Works by unpublished mechanism.

A.1. awe plugin

117

A.2. conductance plugin


The conductance plugin is an implementation of the Conductance model for plant growth
and competition, as described by Benjamin & Park (2007) and references cited therein. The
Conductance model always holds three child models, representing calendar, weather and plant
community, respectively. The community model again holds one or two plant models.
Authors: Niels Holst, Aarhus University, Flakkebjerg, Denmark.
Mette Snderskov, Aarhus University, Flakkebjerg, Denmark.
Gionata Bocci, Scuola Superiore di Studi Universitari e di Perfezionamento SantAnna,
Pisa, Italy.
A.2.1. conductance::Community
A Community object holds one or two Plant objects. It governs the passage of the plant(s)
through the three stages of competition: Unlimited, UnderCompression, and WeightProportional.
VARIABLES
sum_sz

double

Total crown zone area of the one or two plants


2
present (m ground area owned per m2 ground area
available).

A.2.2. conductance::Plant
A Plant object grows, in terms of biomass, leaf area and crown zone area, according to its
current competition phase
PARAMETERS
initWeight

initDay

initMonth

0.03

phi

0.67

0.01

Initial plant weight at time zero (g per plant).


Day of month when growth begins and weight
is set to initWeight. Use together with initMonth. If initDay or initMonth is zero,they
are not used and growth will start on day 1 in the
simulation.
See initDay.
Coefficient in allometric relation for crown zone
area: Aw.
Exponent in allometric relation for crown zone
area: Aw.
Coefficient in allometric relation for plant leaf
area: F w.

Appendix A. Plug-ins Reference

118
theta

0.9

0.6

eps

20

Plant density (plants per m2).

weight

double

Plant weight (g per plant).

totalWeight

double

Total population plant weight (g/m ground area


available).

sz

double

Crown zone area per plant (m ground area owned


per per plant).

total_sz

double

Total population crown zone area (m ground area


owned per m2 ground area available).

Lz

double

fz

double

Leaf area index within the crown zone area (m


leaf area per m2 ground area owned).
Fraction of light intercepted [0..1].

LA_per_plant

double

dweight

double

phase

int

LAI

double

Exponent in allometric relation for plant leaf area:


F w.
Light extinction coefficient of foliage [0..1].
Light use efficiency (g/MJ) of global irradiation.

VARIABLES
2

Leaf area per plant (m leaf area per plant).


Latest increment in plant weight over time step dt
(g per plant per day).
Competition phase: Unlimited, UnderCompression or WeightProportional.
2

Leaf area index of whole population (m leaf area


per m2 ground area available).

A.2.3. conductance::Weather
This Weather object holds fixed values for global irradiation and daily average temperature.
PARAMETERS
irradiation

10

Global irradiation (MJ/m /d).

A.2. conductance plugin

119

A.3. dynamic_photosynthesis plugin


The dynamic_photosynthesis plug-in contains just one model Leaf, which models
photosynthesis based on induction state.
Authors: Isik Ozturk, Aarhus University, rslev, Denmark.
Niels Holst, Aarhus University, Flakkebjerg, Denmark.
A.3.1. dynamic_photosynthesis::Leaf
To simulate leaf photosynthesis in C3 plants
PARAMETERS
Sini

alpha

0.007

S0

0.27

0.017

0.007

gSini

250

PARmin

tm

30

ts

45

useTemperature

no

A0

12

theta

0.0035

Max assimilation rate, Mmol m2 s-1.


Regression coefficient for photosynthesis, Mmol
m2 s-1.

double

Induction state, Mmol m2 s-1.

Seq

double

Equilibrium state of induction, Mmol m2 s-1.

S60

double

Induction state after 60 seconds, Mmol m2 s-1.

Ar

double

Photosynthesis rate, Mmol m2 s-1.

Initial induction state, Mmol m2 s-1.


Response of Seq to PAR, no dimension.
Asymptotic Seq with respect to PAR, Mmol m2 s-1.
Asymptotic regression coefficient for S60, Mmol
m2 s-1.
Regression coefficient for S60, no dimension.
Regression coefficient for S60, no dimension.
Initial stomatal conductance, mmol m2 s-1.
Value of PAR when measured PAR is zero, Mmol
m2 s-1.
location of the peak response on the x axis, C.
controls the width of the bell, no dimension.
controls the effect of temperature.

VARIABLES

Appendix A. Plug-ins Reference

120

A.4. ecotox plugin


A collection of models to simulate deposition of a substance around a source, for instance, GM
pollen or a pesticide. The current naming of models implies GM pollen.
Author: Niels Holst, Aarhus University, Flakkebjerg, Denmark.
A.4.1. ecotox::DepositionFlush
With this model deposition comes in a flush. The daily deposition rate follows a parabolic curve
during the deposition period. The flush starts on a date sampled randomly from a seasonal deposition curve, which must be defined in a sibling model called depositionRate. This can, for
example, be one of the models DepositionMonotonicSampled or DepositionMonotonicWeibull.
PARAMETERS
duration

14

onsetFileName

empty string

Duration (days) of pollen release from crop.


Optional file with dates of pollen onset. Date will
be picked at random within calendar year.

VARIABLES
value

double

total

double

Deposition rate (0..1).


Accumulated deposition total (0..1).

A.4.2. ecotox::DepositionMonotonicSampled
Seasonal deposition curve sampled from an empirical distribution, beginning at value zero and
ending at value one at the end of the season. The distribution data must be supplied as a column
in the records of the weather model.
VARIABLES
value

double

total

double

Deposition rate (0..1).


Accumulated deposition total (0..1).

A.4.3. ecotox::DepositionMonotonicWeibull
Seasonal deposition curve described by a Weibull curve
PARAMETERS
alpha

21.54

beta

1.868

Pollen phenology shape parameter.


Pollen phenology shape parameter.

A.4. ecotox plugin

121

dateMax

31/7/2011

dateShift

Pollen phenology compression. c < 1 prolongs the


period of pollen deposition. c > 1 shortens the period.
Date when pollen deposition peaks.
Shift dateMax by this number of days. Usefull for
stochastic modelling.

VARIABLES
value

double

total

double

Deposition rate (0..1).


Accumulated deposition total (0..1).

A.4.4. ecotox::LogLogistic
The log-logistic dose-response curve described by
y = ymin

(ymax ymin)
x slope
1 + ED50

The value of the dose x is given by the parameter dose below. As for any other parameter,
you can either set this to a fixed or a variable value. For dose you most often want a variable value supplied from another model. If you set dose to pollen[pollenDensity]
then the response will reflect current pollen density. Other possible measures include
pollen[stdPollenDensity] and pollen[toxinDensity], see Pollen on page 121.
PARAMETERS
dose

lower

upper

ED50

10

slope

Dose for which response will be calculated. You


can use this also as a push variable.
Asymptotic response at low dose.
Asymptotic response at high dose.
Dose giving average response (lower + upper)/2.
Slope of sigmoid curve. The curve is rising from
lower to upper, if slope is positive.And, the
curve is falling from upper to lower, if slope
is negative.

VARIABLES
value

double

Response at current dose.

A.4.5. ecotox::Pollen
This model must be composed of two models, depositionRate and lossRate, and possibly
a third model, depositionFlush. Its parameters determine the total deposition and the

Appendix A. Plug-ins Reference

122
distance from the source.

The LogLogistic dose-response model can pull the current dose from Pollen as pollenDensity, toxinDensity or stdPollenDensity.The exchange rate between these different
units of density is determined by the parameters pollenMass and toxinConc, which set the
mass and toxin concentration for the crop at hand, and stdPollenMass and stdToxinConc,
which set the corresponding values for a standard reference crop. The transformations are
toxinDensity = pollenDensity*pollenMass*toxinConc

and
stdPollenDensity =
pollenDensity*pollenMass/stdPollenMass*toxinConc/stdToxinConc

PARAMETERS
distance

distanceExp

-0.548

distanceMin

0.3

Npeak

1750

Distance to maize field (m).


Pollen deposition declines with the distance from
the maize field. This is described as a power function with the exponent distanceExp.
Minimum distance of pollen dispersion model (m).
Peak average density of pollen deposited on food
plant (pollen per cm2) at field edge, i.e. at distance <= distanceMin.

VARIABLES
pollenDepositionRate
pollenDepositionTotal
pollenDensity

double

Current pollen deposition rate (per day per cm2).

double

Total pollen deposition (per cm2).

double

Current pollen density (per cm2).

A.4.6. ecotox::PollenLossConstant
With a constant rate of pollen loss, pollen disappears following a negetive exponential curve.
PARAMETERS
rate

0.01

Fraction of pollen lost per day. Set this to zero if


pollen is not lost.

double

Fraction of pollen lost per day.

VARIABLES
value

A.4. ecotox plugin

123

A.4.7. ecotox::PollenLossSampled
With sampled loss rate, the daily loss rate is determind by picking a value at random from the
supplied list of loss rates.
PARAMETERS
rates

(0 0.5 0.9)

List of daily loss rates from which one is drawn at


random every day. A value of (0 0.5 0.9), for
example, results in a daily loss rate of either 0, 50%
or 90% with equal probability.

double

Pollen survival rate (per day).

VARIABLES
value

Appendix A. Plug-ins Reference

124

A.5. intercom plugin


The intercom plugin is an implementation of the INTERCOM model for plant growth and
competition, as described by Kropff & Laar (1993).
Authors: Niels Holst, Aarhus University, Flakkebjerg, Denmark.
Marleen Riemens, Plant Research International, Wageningen, Netherlands.
Jonathan Storkey, Rothamsted Research, UK.
A.5.1. intercom::Area
2

An Area object keeps track of the area (cm per plant) which carries out photosynthesis
according to its parameters and sub-models. It must hold three sub-models as children, named
density, amax and lightUseEfficiency. The latter two specify the shape of the light
response curve and the first the shape of the canopy.
PARAMETERS
scatteringCoeff

0.2

kDiffuse

0.7

writeTestOutput

no

allocation

Light scattering coefficient. Usually the default


value is used.
Light extinction coefficient of diffuse light.
Write detailed output? The resulting file has a name
that begins witharea_test followed by the full name
of the Area object.
Allocated dry matter (g per plant per day) to be
converted into area.

VARIABLES
value

double

LAI

double

lightAbsorption

double

CO2Assimilation

double

grossProduction

double

The area of this organ per plant (cm per plant).


Leaf area index of this organ.
Light absorbed by this area (W per m2 ground
per day).
CO2 assimilated by this area (kg CO2 per ha ground
per day).
Carbohydrates produced by this area (kg CH2O per
ha ground per day).

A.5.2. intercom::AreaDensityEven
This model can serve as a density sub-model for an Area object. The density is the same at all
heights from zero to canopy height.

A.5. intercom plugin

125

A.5.3. intercom::AreaDensitySymmetric
This model can serve as a density sub-model for an Area object. The density is parabolic from
zero to canopy height.

A.5.4. intercom::AreaDensityTapering
This model can serve as a density sub-model for an Area object. The density increases linearly
from zero at canopy height to its maximum at zero height.

A.5.5. intercom::AreaDensityTopheavy
This model can serve as a density sub-model for an Area object. The density increases
non-linearly from zero to canopy height, resulting in a topheavy shape typical of flowers

A.5.6. intercom::AssimilationMaxGivenTemp
This model can serve as the amax sub-model of an Area object. Based on the Tday variable of
Tday)
weather model, it calculates the maximum assimilation rate as maxAmax(1 radix
PARAMETERS
radix

0.882

maxAmax

50

Radix in the empirical equation.


Asymptotic max CO2 assimilation rate at high
temperature [kg CO2 per ha leaf per hour].

VARIABLES
value

double

Max CO2 assimilation rate [kg CO2 per ha leaf


per hour].

A.5.7. intercom::Community
A Community model holds one or more Plant child models. It resolves the competition for
light in daily time steps, calculating total light absorption and CO2 assimilation of the whole
canopy (i.e. of all its Plant objects) and dividing the resulting total among its Plant objects.
If more than one Community object is present they will work in parallel without any interference (e.g. competition for light). Thus different scenarios can be compared in one simulation run.
PARAMETERS
earlyGrowthThreshold

Threshold (LAI) for applying the early exponential


growth model.

Appendix A. Plug-ins Reference

126
testMode

no

In test mode, the plants stop growing after earlyGrowthThreshold has been reached. Daily photosynthesis is calculated but not allocated.

VARIABLES
isInEarlyGrowth

bool

Is the community it its early growth phase?.

LAI

double

Leaf area index of whole community (m plant


area per m2 ground).

lightAbsorption

double

CO2Assimilation

double

Absorbed light (W per m2 ground per day).


Assimilated kg CO2 per ha ground per day.

grossProduction

double

Produced kg CH2O per ha ground per day.

A.5.8. intercom::EarlyGrowth
The EarlyGrowth model is a simple expontial curve based on photothermal time. A photothermal time model must be available as a sibling.
PARAMETERS
initialArea

0.05

Area at time zero (cm per plant).

growthRate

Exponential growth rate (m per m2 per photothermal time unit.

double

Current area (cm per plant).

VARIABLES
area

A.5.9. intercom::Height
A Plant model must have one child model named height with a height pull variable
returning the height. The Height class provides the standard height model of INTERCOM
which is a logistic growth curve working on photothermal time.
hmax h0
height(t) = h0 +
1 + exp( slope(t tm))
The height model looks for the nearest model named time to provide the daily time increment.
A UniSim::PhotoThermalTime model can be used for this purpose (see page 152).
PARAMETERS
h0

0.05

hmax

slope

0.0085

tm

624

Height at time zero (m).


Maximum height (m).
Growth rate (per photothermal time unit).
Time when height = h0 + (hmax h0)/2.

A.5. intercom plugin

127

VARIABLES
height

double

Current height (m).

A.5.10. intercom::InstantMortality
List of instant mortalities [0;1] applied on a certain day and month to the listed plant organs, for
example, ((leaves 0)(stem 0.05)(flowers 0)). Plant organs not mentioned will not be
afflicted. Those mentioned must exist inside Plant.
PARAMETERS
day

month

survival

empty string

Day of month when survival will be applied.


Month when survival will be applied.
List of survival rates, max. one for each Stage
defined for the Plant.

A.5.11. intercom::LightUseEfficiencyGivenTemp
This model can serve as the lightUseEfficiency child model of an Area object. It calculates
light use (or light conversion) effiency as a linear relation on Tday of the weather model
PARAMETERS
slope

-0.0095

intercept

0.635

Slope of the line (kg CO2 per ha leaf per hour per
(W per m2 leaf) per C).
Intercept of the line (kg CO2 per ha leaf per hour
per (W per m2 leaf)).

VARIABLES
value

double

Light use efficiency, (kg CO2 per ha leaf per hour


per (W per m2 leaf)).

A.5.12. intercom::Mass
This model can serve as a mass child model of an Organ model. It holds iself a mass child
model to hold the actual mass (g/plant) which is usually of the UniSim::Stage class to simulate
an ageing mass
PARAMETERS
allocation

Allocated dry matter (g per plant per day) to be


added to mass.

double

The mass of this organ per plant (g per plant).

VARIABLES
value

Appendix A. Plug-ins Reference

128
allocationRate

double

currentPartition

double

The mass just allocated to this organ per plant (g


per plant per day).
The proportion [0;1] that this mass consistutes out
of the plant total.

A.5.13. intercom::Organ
An Organ model is a child of a Plant model. It contains one child model called mass and
optionally an additional model of the Area class
PARAMETERS
maintenanceCoeff

0.03

CH2ORequirement

1.5

Maintenance coefficient (g/g/day) at 20 C.


Carbohydrate requirement g CH2 O per g biomass.

VARIABLES
Absorbed light (W per m2 ground per day).
Assimilated kg CO2 per ha ground per day.

lightAbsorption

double

CO2Assimilation

double

grossProduction

double

Produced kg CH2O per ha ground per day.

maintenanceResp

double

growthResp

double

netAllocation

double

Maintenance respiration (kg CH2 O per ha ground


per day).
Growth respiration (kg CH2 O per ha ground per
day).
Net allocation rate, the daily increment to organbiomass (kg CH2 O per ha ground per day).

allocatedPerPlant

double

propAllocatedPerPlant

double

Net biomass allocated to this organ per plant (g per


plant per day).
Proportion biomass allocated to this organ among
all the plants organs [0;1].

A.5.14. intercom::PartitioningFixed
This model supplies a partitioning coefficient with a fixed value
PARAMETERS
value

Fixed partitioning coefficient. They must sum up to


one for a Plant object.

A.5. intercom plugin

129

A.5.15. intercom::PartitioningFixedByStage
Pending
PARAMETERS
value

values

empty string

Fixed partitioning coefficient. They must sum up to


one for a Plant object.
Fixed partitioning coefficient for each plant growth
stage, for example, (vegetative 0.5)(flowering 0.2).

A.5.16. intercom::Phenology
The model of plant phenology must be a child of a Plant model. It may consist of any number
of UniSim::Stage models
VARIABLES
alive

double

Proportion of plant population still alive [0;1], i.e.


the proportion that has not yet developed past the
last stage defined as child of Phenology.

A.5.17. intercom::Plant
A Plant model is a child of the Community model. It holds one or more Organ child models
and additional child models called time, height and earlyGrowth.
PARAMETERS
100

Plants per m2.

mass

double

Mass of one plant (g per plant).

LAI

double

Leaf area index of whole plant (m plant area per


m2 ground).

lightAbsorption

double

allocatedPerPlant

double

CO2Assimilation

double

Absorbed light (W per m2 ground per day).


Net allocation rate, the daily increment to plant
mass (g per plant per day).
Assimilated CO2 (kg CO2 per ha ground per day.

grossProduction

double

Produced kg CH2O per ha ground per day.

maintenanceResp

double

Maintenance respiration (kg CH2O per ha ground


per day).

density

VARIABLES
2

Appendix A. Plug-ins Reference

130
growthResp

double

availableProduction

double

netAllocation

double

Growth respiration (kg CH2 O per ha ground per


day).
The available production is gross production minus
maintenance respiration (kg CH2O per ha ground
per day).
Net allocation rate, the daily increment to plant
population mass (kg CH2O per ha ground per
day).

A.5.18. intercom::SpecificLeafArea
This can serve as the specificLeafArea model of an Area model. It models specific leaf area
2
(m /g) as a linear relation on photothermal time, supplied by the nearest model called time, for
example a UniSim::PhotoThermalTime model.
PARAMETERS
initial

240

Initial specific leaf area at time zero (cm /g).

slope

-0.075

Slope on photothermal time ((cm /g/D)).

double

Specific leaf area (cm /g).

VARIABLES
value

A.5.19. intercom::Weather
The model named weather of this class must be present, as several other models rely on daily
weather recordings. The weather model holds a UniSim::Records inside which manages
the daily readings from a weather file. This weather file must hold at least four columns labelled:
Date, Tmin, Tmax and irradiationMJ. In addition to these four, Weather itself adds additional
pull variables.
Values of irradiation rates pertain to the current time of the day, as set by the clock
object
VARIABLES
Tavg

double

Tday

double

irradiation

double

Daily average temperature calculated as the average of Tmin and Tmax (C).
Daily day temperature calculated as Tmax minus
one quarter of the span between Tmax and Tmin
(C).
Daily total irradiation. Same as irradiationMJ
read from weather records but with adjusted units
2
(W/m ).

A.5. intercom plugin

131

parTotal

double

parDiffuse

double

parDirect

double

Total PAR irradiation rate at current time of day


2
(W/m ).
Diffuse component of total PAR irradiation at
2
current time of day (W/m ).
Direct componente of total PAR irradiation at cur2
rent time of day (W/m ).

Appendix A. Plug-ins Reference

132

A.6. MicrobialCommunity plugin


Description of MicrobialCommunity.
Authors: Kevin, Yun-Feng Duan, Aarhus University, Foulum, Denmark.
Niels Holst, Aarhus University, Flakkebjerg, Denmark.
A.6.1. MicrobialCommunity::Community
Description pending
PARAMETERS
EnableStochasticCommunity

no

MinPopulations

MaxPopulations

AlwaysIncludedPopulations

empty string

A switch indicating whether stochastic community


is enabled.
Minimum number of populations entered in the
stochastic community.
Maximum number of populations entered in the
stochastic community.
A list of populations that will always be entered in
the stochastic community.

VARIABLES
Density

double

Richness

int

SimpsonIndex

double

ShannonIndex
Evenness

double
double

GiniCoefficient

double

Total density of the community.


Community richness.
Simpsons Index.
Shannon-Wiener Index.
Community evenness.
Gini coefficient.

A.6.2. MicrobialCommunity::Competition
Description pending
PARAMETERS
EnableCompetition

yes

InitialResource

CompetitionModel

default

VARIABLES

A switch indicating whether competition model


is enabled.
Initial resource.
Define the competition model used in the simulation.

A.6. MicrobialCommunity plugin


AvailableResource

double

133
Description.

A.6.3. MicrobialCommunity::CompetitiveInhibition
Description pending
PARAMETERS
EnableEffect

yes

TargetPopulations

empty string

InhibitionConstant
InhibitorConcentration

Enable the effect.


The Population models that are affected under
this effect.
Inhibition constant.

Concentration of inhibitor.

A.6.4. MicrobialCommunity::Effect
Description pending
PARAMETERS
EnableEffect

yes

TargetPopulations

empty string

Enable the effect.


The Population models that are affected under
this effect.

A.6.5. MicrobialCommunity::EnzymaticReaction
Description pending
PARAMETERS
100

Initial concentration of substrate.

Substrate

double

SubstratePDD

double

Velocity

double

VelocityPDD

double

Concentration of substrate.
Concentration of substrate, population density dependent.
Reaction velocity.
Reaction velocity, population density dependent.

InitialSubstrate

VARIABLES

Appendix A. Plug-ins Reference

134

A.6.6. MicrobialCommunity::FirstOrderReaction
Description pending
PARAMETERS
100

Initial concentration of substrate.

Substrate

double

SubstratePDD

double

Velocity

double

VelocityPDD

double

Concentration of substrate.
Concentration of substrate, population density dependent.
Reaction velocity.
Reaction velocity, population density dependent.

InitialSubstrate

VARIABLES

A.6.7. MicrobialCommunity::GeneralEffect
Description pending
PARAMETERS
EnableEffect

yes

TargetPopulations
TargetParameter

empty string

EffectRatio

empty string

empty string

Enable the effect.


The Population models that are affected under
this effect.
The parameter of Population model that is affected
by this factor.
The effect ratio of this factor.

A.6.8. MicrobialCommunity::Population
Description pending
PARAMETERS
SpeciesName

Bacterium

IsActive

yes

InitialDensity

CarryingCapacity

LagPhase

GrowthRate

MortalityRate

SearchRate

Name of the microbial species.


A switch indicating whether this population is
active in a stochastic community.
Initial density.
Carrying capacity.
Lag phase.
Growth rate.
Mortality rate.
Search rate.

A.6. MicrobialCommunity plugin

135

DemandRate

ZeroOrderRateConstant
FirstOrderRateConstant
MichaelisMentenConstant
MaximumVelocity

Demand rate.
Zero-order rate constant.

First-order rate constant.

Michaelis-Menten constant (Km) for the enzyme.

SupplyDemandRatio

Maximum velocity of the enzyme-catalyzed reaction.


Supply-demand ratio.

VARIABLES
Density

double

DensityActivityCoefficient

double

Population density.
Bacterial density-activity coefficient.

A.6.9. MicrobialCommunity::Reaction
Description pending
PARAMETERS
100

Initial concentration of substrate.

Substrate

double

SubstratePDD

double

Velocity

double

VelocityPDD

double

Concentration of substrate.
Concentration of substrate, population density dependent.
Reaction velocity.
Reaction velocity, population density dependent.

InitialSubstrate

VARIABLES

A.6.10. MicrobialCommunity::ZeroOrderReaction
Description pending
PARAMETERS
100

Initial concentration of substrate.

Substrate

double

SubstratePDD

double

Velocity

double

Concentration of substrate.
Concentration of substrate, population density dependent.
Reaction velocity.

InitialSubstrate

VARIABLES

Appendix A. Plug-ins Reference

136
VelocityPDD

double

Reaction velocity, population density dependent.

A.6. MicrobialCommunity plugin

137

A.7. mussel_bed plugin


The mussel_bed plugin includes models for creatures on a mussel bed.
Authors: Antonio Agera, Wageningen University, Netherlands.
Niels Holst, Aarhus University, Flakkebjerg, Denmark.
A.7.1. mussel_bed::HydrodynamicSRScale
Scaling searching rate of starfish by hydrodynamic regime in the area. Yields a number [0;1]
PARAMETERS
maxflow

desc.

double

desc.

VARIABLES
value

A.7.2. mussel_bed::Mussel
Mussel population model
PARAMETERS
initialDensity

initialN

1000

LossB

LossN

growthRate

0.3

Observed density at t0 as kg/m2.


Observed density at t0 as numbers/m2.
losses in mussel biomass as kg/m2.
losses in mussel numbers as kg/m2.
mussel growth rate (only in biomass).

VARIABLES
N

double

density

double

current density at step, numbers/m2.


current density at step, kg/m2.

A.7.3. mussel_bed::MusselGrowthRate
Mussel population growth rate model
PARAMETERS
intrinsicRate

0.019

carryingCapacity

15

Intrinsic rate of increase (% per day), maximum


growth observed in the Wadden Sea for young
mussels.
Carrying capacity (kg/m2), obtained from field observations.

Appendix A. Plug-ins Reference

138
density

current mussel density at step(kg/m2).

double

total growth rate for the current density, temperature and salinity (kg/m2).

VARIABLES
value

A.7.4. mussel_bed::SalinityScale
Scaling of growth rate by Salinity. Yields a number [0;1]
PARAMETERS
Smax

30

Smin

24

salinity at high tide.


salinity at low tide.

double

mussel growth scaling factor.

VARIABLES
value

A.7.5. mussel_bed::SalinitySRScale
Scaling searching rate of starfish by average salinity. Yields a number [0;1]
PARAMETERS
Smax

31

Smin

10

desc.
desc.

double

desc.

VARIABLES
value

A.7.6. mussel_bed::searchrate
estimating appearance for fResp
PARAMETERS
maxSR

maximum search rate m2/day, from Wong et al,


2006.

double

search rate or appearance.

VARIABLES
value

A.7.7. mussel_bed::Starfish
starfish population model
PARAMETERS

A.7. mussel_bed plugin

139

inDensity

0.3

mortality

stgrowthRate

0.12

Starfish density at t0 (kg/m2.


Starfish mortality at step (kg).
Starfish population increase in biomass (kg) at
current step.

VARIABLES
stdensity

double

current step starfish density (kg/m2).

A.7.8. mussel_bed::StarfishFeedingRate
Scaled Feeding rate of starfish
PARAMETERS
stdensity

0.3

current starfish density Kg/m2.

double

total demand for the current density kg/m2 of mussel flesh.

VARIABLES
value

A.7.9. mussel_bed::StarfishGrowthRate
transform feeding rate into new starfish biomass
PARAMETERS
supply

0.007

stDensity

0.3

temperature

13

total amount of mussel flesh consumed kg/m2.


current starfish density kg/m2.
current temperature degrees celsius.

double

total increase in starfish biomass at step kg/m2.

VARIABLES
value

A.7.10. mussel_bed::StarfishSalMortality
Starfish mortality produced by salinity changes
PARAMETERS
Smax

28

Smin

12

maximum salinity at day.


minimum salinity at day.

double

desc.

VARIABLES
value

Appendix A. Plug-ins Reference

140
A.7.11. mussel_bed::TemperatureScale
Scaling of growth rate by temperature. Yields a number [0;1]
PARAMETERS
temperature

12

avgs

0.005

current step temperature in degree Celsius.


average individual weight at current step.

double

scaling parameter at current temperature.

VARIABLES
value

A.7.12. mussel_bed::TemperatureStScale
Scaling of feeding rate of starfish by Temperature. Yields a number [0;1]
PARAMETERS
temperature

15

current temperature degree celsius.

double

scaling factor for feeding rate.

VARIABLES
value

A.7.13. mussel_bed::thinning
stimate loss rate considering also self thinning rule
PARAMETERS
Density

supply

current mussel density biomass kg/m2.


current mussel density numbers n/m2.
biomass of mussesl consumed by starfish kg/m2.

VARIABLES
thin

double

LossN

double

LossB

double

avgs

double

maxN

double

loss casused by thinning as kg/m2.


mussel loss as numbers n/m2.
mussel loss as biomass kg/m2.
current mussel mean individual weight.
maximum density in numbers/m2 for the current
avgs.

A.7. mussel_bed plugin

141

A.8. rvf plugin


The rvf plugin includes models for the epidemics of Rift Valley Virus (RVF).
Author: Clement Mweya, National Institute for Medical Research, Tanzania.
A.8.1. rvf::Adult
Adult mosquitoes laying eggs.
PARAMETERS
sexRatio

0.5

density

fecundity

20

proportionEggsInWater

20

Proportion of females.
Density of adults.
Eggs laid per female per day.
desc.

VARIABLES
eggsLaidInWater

double

eggsLaidOnGround

double

Number of eggs laid in water.


Number of eggs laid on dry ground.

A.8.2. rvf::Egg
Mosquitoes eggs in water
VARIABLES
totalEggsInflow

double

desc.

A.8.3. rvf::InactiveEgg
Inactive eggs laid on the ground.
PARAMETERS
initialDensity

lossRate

20

activationRate

20

inflow

desc.
desc.
desc.
desc.

VARIABLES
density
eggsLost

double

eggsActivated

double

double

desc.
desc.
desc.

Appendix A. Plug-ins Reference

142
A.8.4. rvf::MosquitoFecundity

Daily egg-laying rate of adult mosquitoes. Depends on water level


PARAMETERS
waterLevel
waterLevelThreshold
dailyFecundity

0
20

desc.
desc.

20

desc.

double

desc.

VARIABLES
value

A.8.5. rvf::WaterLevel
Water level in the environment.
PARAMETERS
initialValue

100

dailyRainfall

dailyLoss

10

desc.
desc.
desc.

double

desc.

VARIABLES
value

A.8. rvf plugin

143

A.9. seed_emergence plugin


The seed_emergence plugin provides a CumulativeEmergence model which models emergence as a Gompertz curve running on hydrothermal time. The Unisim::HydrothermalTime
model calculates time from weather input provided on a file with hourly readings of soil temperature and soil water potential.
Authors: Niels Holst, Aarhus University, Flakkebjerg, Denmark.
Roberta Masin, Consiglio Nazionale delle Ricerche, Padova, Italy.
A.9.1. seed_emergence::CumulativeEmergence
Cumulative emergence (%) modelled as a Gompertz curve.
PARAMETERS
a

10

0.008

Gompertz curve a parameter.


Gompertz curve b parameter.

double

Current accumulated emergence (%).

VARIABLES
accumulated

A.9.2. seed_emergence::Weather
Converts units of soil water potential from kPa to MPa.
VARIABLES
Tavg

double

SWP

double

Soil temperature (C).


Soil water potential in MPa.

Appendix A. Plug-ins Reference

144

A.10. strawberry plugin


The strawberry plugin models powdery mildew in strawberries.
Author: Niels Holst, Aarhus University, Flakkebjerg, Denmark.
A.10.1. strawberry::Infection
Computes daily infection rate of leaves
PARAMETERS
inoculumDensity

infectionRate

sourceModel

empty string
empty string

desc.
desc.
desc.
desc.

double

Number of new leaves infected (latent) per day.

targetModel

VARIABLES
leavesInfected

A.10.2. strawberry::LeafProduction
Computes daily production of new leaves
PARAMETERS
productionRate

0.1

Number of leaves produced per day.

double

desc.

VARIABLES
value

A.10. strawberry plugin

145

A.11. UniSim plugin


The UniSim plugin contains a collection of models of general utility.
Author: Niels Holst, Aarhus University, Flakkebjerg, Denmark.
A.11.1. UniSim::Anonymous
An Anonymous model simply acts as a container of other models

A.11.2. UniSim::AsymptoticDecreasing
Asymptotic curve which begins at a value of max at x=0and decreases to min as a lower
asymtote ar large x. The slope parameter determines the curvature
PARAMETERS
x

x for which to calculate the value.

min

max

slope

0.5

Asymptotic minimum value attained at large $F x.


Maximum value attained at x=0.
Slope of curve in the invert units of x.

double

Value calculated from x.

VARIABLES
value

A.11.3. UniSim::AsymptoticIncreasing
Asymptotic curve which begins at a value of min at x=0and increases to max as an upper
asymtote ar large x. The slope parameter determines the curvature
PARAMETERS
x

min
max

slope

0.5

Asymptotic maximum value attained at large $F x.


Slope of curve in the invert units of x.

double

Value calculated from x.

x for which to calculate the value.


Minimum value attained at x=0.

VARIABLES
value

A.11.4. UniSim::Calendar
The Calendar model keeps track of the date. Since latitude is one of its parameters, it also
knows of the current day length. Solar elevation is calculated every time the hour of the day is
set by a tick of the global clock object. For example,

Appendix A. Plug-ins Reference

146
#include <usbase/clock.h>
double hour = 12.5; // Half-past noon
clock()->doTick(hour);

PARAMETERS
latitude

52

initialDate

1/1/2000

initialTimeOfDay

0:0:0

timeStep

timeUnit

timeStepOffset

-1

Latitude of simulated system.


Initial date of simulation. You should perform a
deepReset on your Calendar object after pushing a new value to initialDate.
Initial time of day of simulation. Default is midnight. You should perform a deepReset on your
Calendar object after pushing a new value to
initialDate.
Duration of one integration time step in units determined by timeUnit.
Time unit of timeStep: s)econds, m)inutes,
h)ours, d)ays or y)ears.
The first values are reported to plot and table outputs after one time step. With the default value of -1
for timeStepOffset, the first output will occur
at time zero, defined by initialDay and initialTimeOfDay.
Often
this
is
what
is intuitively expected. With a timeStepOffset
value of zero the first output will occur one time
step after time zero.

VARIABLES
date

date

timeOfDay

time

dateTime

datetime

timeStepSecs

double

totalTimeSteps

int

totalTime

int

totalDays

double

dayOfYear

int

day

int

month

int

year

int

hour

int

Current date.
Current time of day.
Current date and time.
Duration of timeStep in seconds.
Total number of time steps performed since beginning of simulation.
Total time, in units determined by timeUnit.
passed since beginning of simulation.
Total days passed since beginning of simulation.
Day number in year, also known as Julian day.
Current day in month (1..31).
Current month (1..12).
Current year.
Current hour of the day (0..23).

A.11. UniSim plugin

147

minute

int

second

int

dateAsReal

double

dayLength

double

sinb

double

sinLD

double

cosLD

double

Current minute of the hour (0..59).


Current second of the minute (0..59).
Date as a real number measured in years.
Current day length (hours).
Sine of sun elevation, updated by the tick event
of the clock object.
Intermediate variable in astronomic calculations,
updated by the tick event of the clock object.
Intermediate variable in astronomic calculations,
updated by the tick event of the clock object.

A.11.5. UniSim::CrossTab
Output class. Description pending
PARAMETERS
fileName

output.txt

Name of output file.

A.11.6. UniSim::DayDegrees
This is a standard day-degree model. It obtains the daily average temperature from the weather
object, which must exist as Model named weather having a pull variable named Tavg. The
daily increment in day-degrees increases linerly above T0 until Topt. Above Tops it decreases
linearly until Tmax.
The DayDegree model is derived from the PhysiologicalTime base class, like the
alternatives: Days, HydroThermalTime, LactinTime and PhotoThermalTime. They
all start updating right from the beginning, or when triggered by a child model, for example a
TriggerByDate model.
PARAMETERS
T0

Topt

100

Tmax

100

Lower temperature threshold for development


(C).
Optimum temperature for development (C).
Upper temperature threshold for development
(C).
weather[Tavg].

VARIABLES
step

double

Duration of latest time step (physiological time


units).

Appendix A. Plug-ins Reference

148
total

double

Total duration since beginning of simulation (in


physiological time units) or since most recent trigger event (see e.g. TriggerByDate).

A.11.7. UniSim::Days
This model has the same pull variables as the DayDegrees model but it works in simple
chronological time counting every day as just that, one day.
VARIABLES
step

double

total

double

Duration of latest time step (physiological time


units).
Total duration since beginning of simulation (in
physiological time units) or since most recent trigger event (see e.g. TriggerByDate).

A.11.8. UniSim::Exponential
Simple exponential growth model, y = exp(rt ), where t is taken from the nearest model called
time.
PARAMETERS
initialValue

0.05

growthRate

Value at time zero (size or density units).


Exponential growth rate (size or density units per
time unit.

VARIABLES
value

double

increment

double

Current value (size or density units).


Increment in value during the latest time step (size
or density units).

A.11.9. UniSim::Fixed
Often used for test purposes, or an initial version of a model, a Fixed model sets up fixed
values for chosen parameters, and push and pull variables. The only type of values currently
supported is double. Note that these artifical parameters and variables are not created until
initialize() of Fixed is called. This is unlike their real counterparts which are always
created in the models constructor
PARAMETERS
parameters

()

Parameters as name value pairs. E.g., ((Tavg


22.5)(I 40)).

A.11. UniSim plugin

149

A.11.10. UniSim::FunctionalResponseGB
The Gutierrez-Baumgaertner functional response model, including the energy budget for
egestion and respiration
PARAMETERS
apparancy

resourceDensity

100

demand

egestionRatio

respiration

The apparancy of the resource, also known as attack rate or search rate.
The density of the resource (prey, host).
The finite demand rate of the consumer (predator,
parasitoid) population.
Egestion fraction of consumption.
Demand to cover respiration costs.

VARIABLES
supply

double

sdRatio

double

totalDemand

double

totalSupply

double

egestion

double

attacksPerHost

double

numHostsAttacked

double

propHostsAttacked

double

The net supply obtained (net resource consumption, parasitoids infected [0; demand].
The supply/demand ratio [0;1].
Total demand obtained to cover net supply, egestion
and respiration.
Total supply obtained to cover net supply, egestion
and respiration.
Amount of totalSupply lost to egestion.
Amount of totalSupply lost to egestion.
Amount of totalSupply lost to egestion.
Amount of totalSupply lost to egestion.

A.11.11. UniSim::HydroThermalTime
Hydrothermal time accounts for temperature and soil water potential at the same time. In this
implementation the daily increment, as calculated by the DayDegrees model, is set to zero if
soil water potential is less than the threshold, otherwise the daily increment is unaltered. A Model
named weather with a pull variable named SWP must exist to supply HydroThermalTime
with soil water potential.
PARAMETERS
T0

Topt

100

Tmax

100

Lower temperature threshold for development


(C).
Optimum temperature for development (C).
Upper temperature threshold for development
(C).

Appendix A. Plug-ins Reference

150
T

SWP0

SWPTopt

100

Kt

weather[Tavg].
Soil water potential threshold (MPa).
Temperature optimum (C). Above this value, the
soil water potential threshold increases linearly by
Kt.
Rate of increase (MPa/C) in soil water potential
threshold above SWPTOpt.

VARIABLES
step

double

total

double

swpThreshold

double

Duration of latest time step (physiological time


units).
Total duration since beginning of simulation (in
physiological time units) or since most recent trigger event (see e.g. TriggerByDate).
Actual soil water potential threshold for germination (MPa).

A.11.12. UniSim::Inachis
A stage-structured model of the Nymphalid butterfly Inachis io.
PARAMETERS
sexRatio

0.5

eggProduction

100

Proportion females.
Lifetime egg production of one female.

A.11.13. UniSim::Infection
Multi-way infection based upon Predation model.
PARAMETERS
apparencyMatrix

empty string

File with references to predator demands and apparency value for each predator x prey combination.

A.11.14. UniSim::InsectLifeCycle
A stage-structured insect model. Under development
VARIABLES
eclosedReproductiveAdults

double

Number of individuals just eclosed and entering


the reproductive adult stage.

A.11. UniSim plugin

151

adultsToHibernation

double

deadAdults

double

Number of individuals entering the hibernating


adult stage.
Number of individuals dead from senescence.

A.11.15. UniSim::LactinTime
This is the physiological time scale of Lactin et al. (reference to be added). It pulls the daily
average temperature from the weather object just like the DayDegrees model. The equation
used to calculate the daily increment in physiological time is exp(ax) exp(ab (b x) c) + d,
where x is daily average temperature.
PARAMETERS
a

0.13

42

-0.1

Equation parameter.
Equation parameter.
Equation parameter.
Equation parameter.

VARIABLES
step

double

total

double

Duration of latest time step (physiological time


units).
Total duration since beginning of simulation (in
physiological time units) or since most recent trigger event (see e.g. TriggerByDate).

A.11.16. UniSim::Map
Creates output as an animated map. The output element must hold exactly one Trace element.
PARAMETERS
fileName

output.txt

range

(0 100)

steps

log10

no

Name of output file.


Range of trace values on colour ramp. Use logtransformed range values if log10 is set to true.
Number of steps on colour ramp.
Log-transform trace values?.

Appendix A. Plug-ins Reference

152

A.11.17. UniSim::PhotoThermalTime
Photothermal time accounts for temperature and day length at the same time. In this implementation the daily increment, as calculated by the DayDegrees model, is multiplied by day length
in hours (acquired from the calendar object) divided by 24 hours.
PARAMETERS
T0

Topt

100

Tmax

100

Lower temperature threshold for development


(C).
Optimum temperature for development (C).
Upper temperature threshold for development
(C).
weather[Tavg].

VARIABLES
step

double

total

double

Duration of latest time step (physiological time


units).
Total duration since beginning of simulation (in
physiological time units) or since most recent trigger event (see e.g. TriggerByDate).

A.11.18. UniSim::Plot
Output class. Description pending
PARAMETERS
title

empty string

logy

no

ymin

NA

ymax

NA

penWidth

symbolSize

Title of plot shown in window top bar.


Log-transform y-axis? Log base 10 is used.
Minimum value displayed on y-axis. Write as logtransformed value if logy.
Maximum value displayed on y-axis. Write as
log-transformed value if logy.
Pen width for curves and symbols.
Size of symbols.

A.11.19. UniSim::Predation
Multi-way predation based upon FunctionalResponseGB model.
PARAMETERS

A.11. UniSim plugin


apparencyMatrix

153
empty string

File with references to predator demands and apparency value for each predator x prey combination.

A.11.20. UniSim::RandomLognormal
The model maintains a random variable with a log-normal distribution.
PARAMETERS
minValue

NA

maxValue

NA

maxTries

100

mean

10

sd

Minimum random value.


Maximum random value.
Maximum number of tries to find a number inside
the interval minValue to maxValue. An exception is cast if exceeded.
Mean of log-normal distribution.
Standard deviation of log-normal distribution.

double

Random value.

VARIABLES
value

A.11.21. UniSim::RandomNormal
The model maintains a random variable with a normal distribution.
PARAMETERS
minValue

NA

maxValue

NA

maxTries

100

mean

10

sd

Minimum random value.


Maximum random value.
Maximum number of tries to find a number inside
the interval minValue to maxValue. An exception is cast if exceeded.
Mean of normal distribution.
Standard deviation of normal distribution.

double

Random value.

VARIABLES
value

A.11.22. UniSim::RandomPoisson
The model maintains a random variable with a Poisson distribution.
PARAMETERS
minValue

NA

maxValue

NA

Minimum random value.


Maximum random value.

Appendix A. Plug-ins Reference

154
maxTries

100

mean

10

Maximum number of tries to find a number inside


the interval minValue to maxValue. An exception is cast if exceeded.
Mean of Poisson distribution.

double

Random value.

VARIABLES
value

A.11.23. UniSim::RandomUniform
The model maintains a random variable with uniform (i.e. flat) distribution.
PARAMETERS
minValue

NA

maxValue

NA

maxTries

100

Minimum random value.


Maximum random value.
Maximum number of tries to find a number inside
the interval minValue to maxValue. An exception is cast if exceeded.

double

Random value.

VARIABLES
value

A.11.24. UniSim::Range
The model produces equally spaced numbers inside a [min,max] range.
PARAMETERS
progress

min

max

100

scale

linear

steps[progress].
Minimum value in range.
Maximum value in range.
Scale is either linear or log10. With a log10
scale, min=-2 and max=3, values in the range
[0.01,1000] will result.

VARIABLES
value

double

Current value in range.

A.11.25. UniSim::Records
A Records model reads input from a text file formatted in columns with labels in the first line.
Columns can be separated by spaces or tab characters. Labels may not contain spaces. A pull
variable will be created for every column in the input file, named after the column label. There
can be more than one Records model present in a simulation.
Columns named date and time have special meanings, as they are used to synchronize

A.11. UniSim plugin

155

the readings from the input file with the calendar model. If you have either a date or a time
column, or both, then the calendar model will be reset to the time indicated in the first line of
records, before the simulation begins. While this is the behaviour usually wanted, you can also
change this by setting imposeInitialDateTime to no.
The pull variables for date and time are mostly used for test purposes. If you need to know
about the current date and time of day, you should pull this information from the calender
model. See page 145.
PARAMETERS
fileName

records.txt

fileLocation

input

imposeInitialDateTime

yes

randomizeInitialYear

no

Name of input file. If date and time are included,


their column titles must be date and time.
Valid locations are the standard folders: input and
plugins. The standard folders can be set from the
File|Locations menu.
Impose the first date and time on calendar. Either
or both, date and time, are imposed; it depends on
which are included in the file. If neither is included, there is no effect of setting imposeInitialDateTime to yes.
Pick a random initial year from the years available
in the records file.

VARIABLES
currentDateTime

datetime

nextDateTime

datetime

firstDateTime

datetime

lastDateTime

datetime

currentDate

date

nextDate

date

currentTime

time

nextTime

time

The date and time of the current line in the input


file. The calendar date and time will be at or
past this.
The date and time of the next line in the input file.
The calendar date and time will be at or before this.
The date and time of the first line in the input file.
The date and time of the last line in the input file.
The date part of currentDateTime.
The date part of nextDateTime.
The time part of currentDateTime.
The time part of nextDateTime.

A.11.26. UniSim::RunIteratorFixed
The model increments its iteration counter for every update. Its value remains true as long
as iteration numIterations.
PARAMETERS
numIterations

10

Number of iterations to count.

Appendix A. Plug-ins Reference

156
VARIABLES
value

bool

iteration

int

Is current iteration within the set number of iterations?.


Number of current iteration.

A.11.27. UniSim::Scenarios
The Scenarios model is used to iterate through several parameter settings. Description pending
PARAMETERS
scenarios.txt

Column-oriented text file with scenarios, line by


line.

iteration

int

numIterations

int

value

bool

Number of current iteration.


Number of current iteration.
Is current iteration within the set number of iterations?.

fileName

VARIABLES

A.11.28. UniSim::Scheduled
A Scheduled model produces canned data which are derived from a list of time value pairs,
e.g., ((10.2 14.6) (45.1 32.3) (57.1 24.43)). Values are interpolated from the
current time which is taken from the nearest model called time. At times outside the range
covered by the list (outside [10.2;57.1], in this case) values are extrapolated (to 14.6 or 24.43, in
this case).
PARAMETERS
empty string

Schedule as (time value) pairs. For example, ((0


10)(20.5 30)(65 48.6)).

value

double

increment

double

Current value.
Increment in value during the latest time step.

schedule

VARIABLES

A.11.29. UniSim::SensitivityAnalysis
Integrator class. Description pending
PARAMETERS
maxSteps

100

factor

-1

description.
description.

A.11. UniSim plugin

157

relative

-1

absolute

-1

days

10

seconds

60

description.
description.
description.
description.

VARIABLES
stepNumber

int

progress

double

runNumber

int

Number of current time step in this iteration.


Progress of current iteration [0,1].
Number of current iteration.

A.11.30. UniSim::Stage
The Stage model implements a distributed delay (Manetsch 1976, Vansickle 1977). The implementation follows the original FORTRAN code of Abkin & Wolf (1976). The two parameters
duration and k determine the average and variance of stage duration with variance equal to
duration2 / k2. The time scale used by the Stage model is determined by the nearest model
called time.
PARAMETERS
k

30

duration

100

growthRate

sdRatio

instantMortality

instantLossRate

phaseInflow

inflow

initialInflow

The number of age classes in the stage. The fewer


age classes, the larger the variance on duration.
The average duration of the stage: an inflow will
emerge as an outflow dispersed over time, with a
delay of duration on average and a variance of
duration2 /k2 (Manetsch 1976).
For every quantity x that enters as inflow, growthRate*x will emerge as outflow.
growthRate can be changed during the simulation but must be larger than zero. Use small values
(e.g., 106) instead of zero. growthRate is also a
pull/push variable.
Supply/Demand ratio.
Mortality [0..100] will be applied in the next time
step, before inflow is added.
Works just like mortality except the scale is a
ratio [0..1].
Inflow of dimension k.
Number of units to be put into the stage in the next
time step.
The initialInflow is entered as inflow at time
0.

Appendix A. Plug-ins Reference

158
0

Proportion that will change phase in next time


step.

value

double

number

double

inflowTotal

double

outflowTotal

double

phaseInflowTotal

double

phaseOutflowTotal

double

growthIncrement

double

phaseOutflow
latestInflow

QVector<double>
double

Number of units (e.g. individuals) in stage.


Synonymous with value.
Total inflow into the stage since beginning of the
simulation.
Total outflow from the stage since beginning of
the simulation.
Total phase change inflow into the stage since beginning of the simulation.
Total phase change outflow from the stage since
beginning of the simulation.
Increment realised in this integration step.
Outflow of dimension k.

outflow

double

timeStep

double

phaseOutflowProportion

VARIABLES

Inflow into the stage in latest time step.


Outflow from the stage in latest time step.
The latest time step applied to the stage.

A.11.31. UniSim::StageAndPhase
The StageAndPhase model simulates a population undergoing two processes at the same, for
instancephysiological development (ageing) and incubation (after being infected). The discern
the two, the first is called a stage and the second, a phase. Phase change is characterisedby the
parameters phaseL and phaseK with the same meaning as L and k in the Stage class.
PARAMETERS
k

30

duration

100

growthRate

sdRatio

The number of age classes in the stage. The fewer


age classes, the larger the variance on duration.
The average duration of the stage: an inflow will
emerge as an outflow dispersed over time, with a
delay of duration on average and a variance of
duration2 /k2 (Manetsch 1976).
For every quantity x that enters as inflow, growthRate*x will emerge as outflow.
growthRate can be changed during the simulation but must be larger than zero. Use small values
(e.g., 106) instead of zero. growthRate is also a
pull/push variable.
Supply/Demand ratio.

A.11. UniSim plugin

159

instantMortality

instantLossRate

phaseInflow

phaseK

30

phaseDuration

100

inflow

timeStep

phaseTimeStep

Mortality [0..100] will be applied in the next time


step, before inflow is added.
Works just like mortality except the scale is a
ratio [0..1].
Inflow of dimension k.
Works like k but in the change phase process.
Works like duration but in the change phase
process.
Number of units to be put into the stage in the next
time step.
Time step for stage development, for example, in
days or day-degrees.
Time step for phase development, for example, in
days or day-degrees.

VARIABLES
value

double

number

double

inflowTotal

double

outflowTotal

double

phaseInflowTotal

double

phaseOutflowTotal

double

growthIncrement

double

phaseOutflow

QVector<double>
QVector<double>
QVector<double>

latestInflow
outflow

Number of units (e.g. individuals) in stage.


Synonymous with value.
Total inflow into the stage since beginning of the
simulation.
Total outflow from the stage since beginning of
the simulation.
Total phase change inflow into the stage since beginning of the simulation.
Total phase change outflow from the stage since
beginning of the simulation.
Increment realised in this integration step.
Outflow of dimension k.
Inflow into the stage in latest time step.
Outflow from the stage in latest time step.

A.11.32. UniSim::StageDemand
This model calculates the growth demand of the stage, identified by stage, which must be of
type UniSim::Stage.The stages growthDemand method is used for the calculation.
PARAMETERS
stage

empty string

Name of stage from which the current demand is


requested by the growthDemand method.

Appendix A. Plug-ins Reference

160
VARIABLES
value

double

Current demand of stage.

A.11.33. UniSim::Steps
Integrator class. Description pending
PARAMETERS
maxSteps

100

description.

stepNumber

int

progress

double

runNumber

int

Number of current time step in this iteration.


Progress of current iteration [0,1].
Number of current iteration.

VARIABLES

A.11.34. UniSim::Sum
Calculates sum of variables supplied as a list of references. The variables must all be of
type double.
PARAMETERS
toAdd

empty string

List of references to add, e.g. (lion[density]


leopard[density]).

double

Sum of values in list.

VARIABLES
value

A.11.35. UniSim::Table
Output class. Description pending
PARAMETERS
fileName

output.txt

Name of output file.

A.11.36. UniSim::TimeLimited
Integrator class. Description pending
PARAMETERS
maxTime

30

description.

int

Number of current time step in this iteration.

VARIABLES
stepNumber

A.11. UniSim plugin

161

progress

double

runNumber

int

Progress of current iteration [0,1].


Number of current iteration.

A.11.37. UniSim::TriggerByDate
The TriggerByDate model can be used by other models to trigger changes in their
behaviour.
PARAMETERS
fromDate

1/1/1900

dateShift

toDate

1/1/1900

frequency

Yearly

triggerAtReset

yes

The trigger will be true between fromDate and


toDate at the specified frequency.
The value of dateShift is added to fromDate,
This is useful for adding stochasticity.
The trigger will be true between fromDate and
toDate at the specified frequency.
Frequency of trigger (Daily or Yearly: Daily or
yearly in date interval.
Always trigger when model is reset?.

VARIABLES
value

bool

Triggered? Updated for every time step according


to the rules set by the parameters.

A.11.38. UniSim::Weather
This Weather model simply supplies a daily reading from a Records child model. If the
records file contains a column named Tavg then that colum is used. Otherwise, if columns named
Tmin and Tmax are present then Tavg is calculated as the average of those
VARIABLES
Tavg

double

Daily average temperature, either read from


records file, or calculated as the daily average of
minimum and maximum temperature. Must have a
child model called records.

Appendix A. Plug-ins Reference

162

A.12. vg plugin
Virtual greenhouse.
Authors: Oliver Krner, AgroTech, Denmark.
Niels Holst, Aarhus University, Flakkebjerg, Denmark.
A.12.1. vg::AirInfiltration
Desc
PARAMETERS
timeStepSecs

height

roofRatio

sideRatio

windspeed

screensAirTransmission
leakage

calendar[timeStepSecs].
construction[height].
construction[roofRatio].
construction[sideRatio].
environment[windspeed].
screens[airTransmission].

0.5

Air exchange through leakage (m3 air/m3 greenhouse/h.

double

Greenhouse air infiltration (m3 air/m2 greenhouse/s).

VARIABLES
value

A.12.2. vg::BlackoutScreenController
Desc
PARAMETERS
fromTime

0:0:0

toTime

0:0:0

maxSignalHighHumidity

0.95

radiationThreshold

followEnergyScreen

yes

time

NA

radiation

Screen is fully drawn after this time.


Screen is fully drawn until this time.
Maximum signal to screen at high humidity [0;1].
Radiation threshold for using blackout screen
(W/m2).
If the energy screen signal is larger than this, will
the blackout screen use that signal instead?.
calendar[timeOfDay].
environment[radiation].

A.12. vg plugin
isHumidityHigh

163
no

climate/humidity[isHigh].

double

Signal to shade screen [0;1].

VARIABLES
signal

A.12.3. vg::BoundaryLayerResistance
Desc
PARAMETERS
windSpeed

ventilation

environment[windspeed].
greenhouse/ventilation[value].

VARIABLES
value

double

Boundary layer resistance against water vapour


(s/m).

A.12.4. vg::ControlElement
Desc
PARAMETERS
signal

timeStepSecs

initState
rate

0
0.1

..[signal].
calendar[timeStepSecs].
Initial value of state.
Rate at which state approaches signal (per
minute).

VARIABLES
state
course

double
int

Current state of control element.


Current course of change: Decreasing, Stable
or Increasing.

A.12.5. vg::ControlElementAsym
Desc
PARAMETERS
signal

timeStepSecs

initState

..[signal].
calendar[timeStepSecs].
Initial value of state.

Appendix A. Plug-ins Reference

164
rateUp

0.1

rateDown

0.01

Rate at which state approaches signal (per minute),


when state is going up towards signal.
Rate at which state approaches signal (per minute),
when state is going down towards signal.

VARIABLES
state
course

double
int

Current state of control element.


Current course of change: Decreasing, Stable
or Increasing.

A.12.6. vg::CoverDew
Desc
PARAMETERS
timeStepSecs

numTimeSteps

coverArea

groundArea

Tcover

mcIndoors

dewScreen

calendar[timeStepSecs].
calendar[totalTimeSteps].
greenhouse/construction[coverArea].
greenhouse/construction[groundArea].
../temperature[value].
climate/humidity[mc].
regulation/screens[dew].

double

Dew formation on greenhouse cover (g/m2/s).

VARIABLES
value

A.12.7. vg::CoverTemperature
Desc
PARAMETERS
Tindoors

Toutdoors

Tsky

windspeed

latcov

climate/temperature[value].
environment[temperature].
environment[skyTemperature].
environment[windspeed].
greenhouse/construction[latcov].

double

Cover temperature (oC).

VARIABLES
value

A.12. vg plugin

165

A.12.8. vg::CoverVapourFlux
Desc
PARAMETERS
Tindoors

mcIndoors

diffuseRadiation

rbH2O

climate/temperature[value].
climate/humidity[mc].
climate/radiation[diffuse].
crop/rbH2O[value].

VARIABLES
double

Vapour flux from cover (i.e. glass and screens)


(kg/m2/s).

kdiff

0.8

coverage

0.1

Extinction coefficient for diffuse light (-).


Proportion of floor covered by crop [0;1].

absorbedRadiation
temperature

double

Total radiation absorbed by crop (W/m2).

double

surfaceMoistureContent

double

transpirationConductance
latentHeatFlux

double

Average temperature of crop (oC).


Average air moisture content at leaf surface
(g/m3).
Total transpiration conductance of leaves (m/s).

dew

double

value

A.12.9. vg::Crop
Desc
PARAMETERS

VARIABLES

double

Average latent heat flux of crop (W/m2).


Total dew formation rate on crop (kg/m2/s).

A.12.10. vg::CropLayer
Desc
PARAMETERS
Tindoors

mcIndoors

vpIndoors

vpdIndoors

climate/temperature[value].
climate/humidity[mc].
climate/humidity[vp].
climate/humidity[vpd].

Appendix A. Plug-ins Reference

166
diffuseRadiation

cropLai

lowerPipeHeatFlux
kDiff

riH2O

rbH2O

longWaveAbsorption

crop[kDiff].
crop/riH2O[value].
crop/rbH2O[value].
crop/radiationAbsorption[longWave].

absorbedRadiation
temperature

double

Radiation absorbed by crop layer (W/m2).

double

surfaceMoistureContent
transpirationConductance
latentHeatFlux

double

Temperature of crop layer (oC).


Air moisture content at leaf surface (g/m3).

double

Transpiration conductance of leaves (m/s).

double

dew

double

Latent heat flux of crop layer (W/m2).


Dew formation rate on crop (g/m2/s).

climate/radiation[diffuse].
crop/growth[lai].
pipes/lower[heatFlux].

VARIABLES

A.12.11. vg::CropRadiationAbsorption
Desc
PARAMETERS
Tindoors

diffuseRadiation

screenTransmission
lampLongWaveEmission
lampShortWaveEmission

climate/temperature[value].
climate/radiation[diffuse].
regulation/screens[lightTransmission].

regulation/light/attributes[longWaveEmission].

regulation/light/attributes[shortWaveEmission].

longWave

double

shortWave

double

Long wave absorption (thermal radiation, Bn)


(W/m2).
Short wave absorption (visible light, Rn) (W/m2).

VARIABLES

A.12. vg plugin

167

A.12.12. vg::EnergyScreenBalance
Desc
PARAMETERS
indoorsDirectRadiation
indoorsTemperature
outdoorsTemperature
KCover

climate/radiation[direct].

climate/temperature[value].

environment[temperature].

construction[KCover].

double

Value of energy balance (W/m2).

VARIABLES
value

A.12.13. vg::EnergyScreenController
Desc
PARAMETERS
maxSignalHighHumidity

0.95

Maximum signal to screen at high humidity [0;1].

radiationThreshold

10

radiation

isHumidityHigh

no

Radiation threshold for using energy screen


(W/m2).
environment[radiation].
climate/humidity[isHigh].

double

Signal to shade screen [0;1].

VARIABLES
signal

A.12.14. vg::Environment
Desc
PARAMETERS
co2

350

windDirection

temperature

rh

radiation

diffuseRadiation

windSpeed

CO2 concentration(ppm).
Wind direction [0;360].
./records[Tair].
./records[RHair].
./records[GlobRad].
./records[DifRad].
./records[WindSpeed].

Appendix A. Plug-ins Reference

168
0

./records[Tsky].

directRadiation

double

vp

double

mc

double

Direct global radiation (W/m2).


Water vapour pressure (Pa).
Moisture content (g/m3).

skyTemperature

VARIABLES

A.12.15. vg::GreenhouseConstruction
Desc
PARAMETERS
width

50

length

50

height

roofRatio

sideRatio

windowLength

windowHeight

0.825

fractionWindows

0.078

alphaVentilationMax
latcov

44

Kcover

7.9

floorHec

glassType

single

lampType

HPSL

35

Width (m).
Length (m).
Height (m).
Roof/Side wall ratio (-).
Side ratio ? (-).
Window length (m).
Window height (m).
Fraction windows [0;1].
Max. ventilation opening (degrees).
Lat cover (degrees).
K value of greenhouse cover (W/m2/K).
Heat capacity of the floor (?).
Possible values: double, hortiplus, single.
Possible values: hpsl, led.

VARIABLES
iGlassType

int

iLampType

int

volume

double

groundArea

double

coverArea

double

averageHeight

double

Glass type as integer.


Lamp type as integer.
Volume (m3).
Area of ground covered (m2).
Area of greenhouse cover (m2).
Average height of greenhouse (m).

A.12. vg plugin

169

A.12.16. vg::GreenhouseEnergetics
Desc
PARAMETERS
coverDew

screenDew

cropDew

ventilation

energyScreenState
longWaveLight

shortWaveLight

lampHeat

Toutdoors

Tfloor

cropLatentHeatFlux
KScreenEnergy

KCover

7.9

floorHec

5.2

greenhouse/cover/dew[value].
regulation/screens[dew].
crop[dew].
greenhouse/ventilation[value].
screens/energy/control[state].
light/attributes[longWaveEmission].
light/attributes[shortWaveEmission].
light/attributes[heatEmission].
environment[temperature].
floor/temperature[state].
crop[latentHeatFlux].
K-value for energy screen (W/m2/K).
K-value for greenhouse cover (W/m2/K).
Heat capacity of the floor (W/m2/K).

VARIABLES
energyBalance

double

heatCapacity

double

Tunheated

double

dewHeat

double

outdoorsHeat

double

floorHeat

double

Energy balance of greenhouse (W/m2).


Heat capacity of greenhouse (W/m2/K).
Greenhouse temperature if not heated (oC).
Heat generated from dew condensation (W/m2).
Heat from outside (W/m2).
Heat from floor (W/m2).

A.12.17. vg::GreenhouseVentilation
Desc
VARIABLES
value

double

Total ventilation rate (m3/m2/s.

Appendix A. Plug-ins Reference

170
A.12.18. vg::HeatingDemand
Desc
PARAMETERS
Tminimum

energyBalance

heatCapacity

setpoints/temperature[minimum].
greenhouse/energetics[energyBalance].
greenhouse/energetics[heatCapacity].

VARIABLES
total

double

perPipe

double

Total heat needed to reach desired minimum temperature (W/m2).


total divided by number of pipes (W/m2).

A.12.19. vg::HumiditySetpoints
Desc
PARAMETERS
radiation

daylightThreshold
maxRHDay

10

maxRHNight

90

minDeltaXBasis

80

environment[radiation].
Global radiation threshold for daylight (W/m2).
Setpoint for relative humidity during the day (%).
Setpoint for relative humidity during the night
(%).
Setpoint for delta x (g/m3).

VARIABLES
maxRH

double

minDeltaX

double

Setpoint for maximum relative humidity (%).


Setpoint for minimum delta x (g/m3).

A.12.20. vg::IndoorsRadiation
Desc
PARAMETERS
glassType

sinb

outdoorsDirectRadiation
outdoorsDiffuseRadiation

construction[iGlassType].
calendar[sinb].
environment[directRadiation].

environment[diffuseRadiation].

A.12. vg plugin

171
0.79

Transmission of diffuse light through greenhouse


construction [0;1].

direct

double

diffuse

double

Direct light transmitted through greenhouse construction (W/m2).


Diffuse light transmitted through greenhouse construction (W/m2).

diffuseTransmission

VARIABLES

A.12.21. vg::LampAttributes
Desc
PARAMETERS
lampType

capacity

40

construction[iLampType].
Capacity of installed lamps (W/m2).

ballastCorrection

Set to >1 (e.g, 1.15) if capacity includes ballast.

heatEmission

double

longWaveEmission

double

shortWaveEmission
parEmission

double

Convective heat emission (W/m2).


Long wave emission (thermal radiation, Bn)
(W/m2).
Short wave emission (visible light, Rn) (W/m2).

energyUse

double

VARIABLES

double

PAR radiation (W/m2).


Energy used (W/m2).

A.12.22. vg::LightController
Desc
PARAMETERS
onDay

300

Julian day when to switch on (1..365).

offDay

60

onTime
offTime

0:0:0
NA

onRadiation

offRadiation

20

day

time

NA

Julian day when to switch off (1..365).


Time when to switch on.
Time when to switch off.
Outdoors radiation when to switch on (W/m2).
Outdoors radiation when to switch on (W/m2).
calendar[dayOfyear].
calendar[timeOfDay].

Appendix A. Plug-ins Reference

172
0

environment[radiation].

signal

double

signalDay

bool

signalTime

bool

signalRadiation

bool

Signal to lamp (0 or 1).


Switch on according to day?.
Switch on according to time of day?.
Switch on according to outdoors radiation?.

radiation

VARIABLES

A.12.23. vg::MicroclimateHumidity
Desc
PARAMETERS
timeStepSecs

mcOutdoors

height

ventilation

temperature

mcCropSurface

cropTranspirationConductance
screenState

Tscreen

Tcover

maxRH

minDeltaX

calendar[timeStepSecs].
environment[mc].
greenhouse/construction[averageHeight].
greenhouse/ventilation[value].
../temperature[value].
crop[surfaceMoistureContent].
crop[transpirationConductance].
screens/energy/control[state].
screens/energy/temperature[value].
greenhouse/cover/temperature[value].
setpoints/humidity[maxRH].
setpoints/humidity[minDeltaX].

VARIABLES
rh

double

prevRh

double

vp

double

vpd

double

mc

double

moistureDeficit

double

isHigh

bool

A.12.24. vg::MicroclimateTemperature
Desc

Relative humidity (%).


Relative humidity (%).
Water vapour pressure (Pa).
Water vapour pressure deficit (Pa).
Moisture content (g/m3).
Absolute humidity deficit (g/kg).
Is humidity above setpoints?.

A.12. vg plugin

173

PARAMETERS
energyBalance

heatCapacity

pipesHeatFlux

VARIABLES
value

double

A.12.25. vg::PidControl
Desc
PARAMETERS
direction

ceiling

timeStepSecs

actualValue

20

targetValue

20

initSignal

Kp

Ti

1000000

Td

Is target value a lower (floor) or upper (ceiling)


limit? Possible values: ceiling, floor.
calendar[timeStepSecs].
Current value being regulated.
Value to regulate towards.
Initial value of signal.
Proportional gain.
Integral time.
Derivative time.

double

Response of PID control.

pipeType

s51

heatingDemand

Tunheated

energyScreenCourse
Tminimum

Possible values: p25, s26, s33, s51.


heating/demand/pipe[signal].
greenhouse/energetics[Tunheated].
screens/energy/control[course].

Tindoors

actualTpipe

pipeLength

1.822

VARIABLES
signal

A.12.26. vg::Pipe
Desc
PARAMETERS

setpoints/temperature[minimum].
climate/temperature[value].
./control[state].
Pipe length (m/m2).

Appendix A. Plug-ins Reference

174
70

Max pipe temperature (oC).

signal

double

heatFlux

double

Desired pipe temperature (oC).


Heat flux from pipe (W/m2).

calendar[timeStepSecs].

heatFlux

double

energyUsed

double

Total heat transfered from all pipes (W/m2).


Accumulated energy used for heating (MJ/m2).

TmaxPipe

VARIABLES

A.12.27. vg::Pipes
Desc
PARAMETERS
timeStepsSecs

VARIABLES

A.12.28. vg::ProportionalControl
Desc
PARAMETERS
direction

ceiling

actualValue

20

targetValue

20

gapMultiplier

pBand

maxSignal

100
yes

signalNotNegative

Is target value a lower (floor) or upper (ceiling)


limit? Possible values: ceiling, floor.
Current value being regulated.
Value to regulate towards.
Multiplier on gap between actualValue and
targetValue.
Proportional band of response.
Maximum absolute value of signal.
Should a negative signal be set to zero?.

VARIABLES
signal

double

Response between zero and maxSignal, increasing with increasing difference between actualValue and targetValue, positive or negative according to direction of change and setting of signalNotNegative flag.

A.12. vg plugin

175

A.12.29. vg::ScreenDew
Desc
PARAMETERS
timeStepSecs

numTimeSteps

state

Tscreen

mcIndoors

calendar[timeStepSecs].
calendar[totalTimeSteps].
../control[state].
../temperature[value].
climate/humidity[mc].

double

Dew formation at all screens (g/m2/s).

temperature

double

airTransmission

double

lightTransmission
dew

double

Average temperature of screens [oC].


Transmission of air through all screens [0;1].
Transmission of light through all screens [0;1].

double

Dew formation at all screens (kg/m2/s).

VARIABLES
value

A.12.30. vg::Screens
Desc
VARIABLES

A.12.31. vg::ScreenTemperature
Desc
PARAMETERS
Tindoors

Tcover

climate/temperature[value].
greenhouse/cover/temperature[value].

double

Screen temperature (oC).

VARIABLES
value

A.12.32. vg::ScreenTransmission
Desc
PARAMETERS
screenState

../control[state].

Appendix A. Plug-ins Reference

176
ratio

0.3

Ratio of transmission [0;1].

double

Screen transmission [0;1].

VARIABLES
value

A.12.33. vg::ShadeScreenController
Desc
PARAMETERS
maxSignalHighHumidity

0.95

Maximum signal to screen at high humidity [0;1].

radiationThreshold

10

temperatureThreshold

28

tolerance

2000

followEnergyScreen

yes

radiation

temperature

isHumidityHigh

no

Radiation threshold for using shade screen


(W/m2).
Temperature threshold for using shade screen
(oC).
Low tolerance gives steep reaction and high tolerance gives gentle reaction, when threshold is
crossed (>=0.
If the energy screen signal is larger than this, will
the blackout screen use that signal instead?.
environment[radiation].
climate/temperature[value].
climate/humidity[isHigh].

double

Signal to shade screen [0;1].

VARIABLES
signal

A.12.34. vg::StomatalResistance
Desc
PARAMETERS
rh

co2

PgcMol

rbH2O

climate/humidity[rh].
climate/co2/[value].
crop/photosynthesis[PgcMol].
crop/rbH2O[value].

double

Stomatal resistance against water vapour (s/m).

VARIABLES
value

A.12. vg plugin

177

A.12.35. vg::TemperatureSetpoints
Desc
PARAMETERS
humidityIncrement
humidityDecrement
setMinimum

./humidityIncrement[signal].

./humidityDecrement[signal].

20

setMaximum

27

Desired minimum temperature, which may be


increased by humidity (oC).
Desired maximum temperature, which may be
lowered by humidity (oC).

VARIABLES
minimum

double

maximum

double

Desired minimum temperature, corrected for humidity (oC).


Desired maximum temperature, corrected for humidity (oC).

A.12.36. vg::VentilationByTemperatureDiff
Desc
PARAMETERS
indoorsTemperature
outdoorsTemperature
ventilationMax

climate/temperature[value].

environment[temperature].

../maximum[signal].

double

The desired ventilation opening [0;100].

VARIABLES
signal

A.12.37. vg::VentilationController
Desc
PARAMETERS
windSideProportion

0.75

indoorsTemperature

The wind side signal as a proportion of the lee side


signal [0;1].
climate/temperature[value].

Appendix A. Plug-ins Reference

178
outdoorsTemperature
maxTemperature

environment[temperature].

windSpeed

byTemperature

byTemperatureDiff
byHumidity

setpoints/temperature[maximum].
environment[windspeed].
./byTemperature[signal].
./byTemperatureDiff[signal].

maxSignal

./byHumidity[signal].
./maximum[signal].

VARIABLES
signal

double

leeSideSignal

double

windSideSignal

double

Synonym for leeSideSignal.


Ventilation opening on the lee side [0;100].
Ventilation opening on the wind side [0;100].

A.12.38. vg::VentilationLatentEnergyBalance
Desc
PARAMETERS
timeStepSecs

groundArea

height

ventilation

mcIndoors

mcOutdoors

calendar[timeStepSecs].
greenhouse/construction[groundArea].
greenhouse/construction[averageHeight].
greenhouse/ventilation[value].
climate/humidity[mc].
environment[mc].

VARIABLES
value

double

totalLoss

double

Balance of latent heat by ventilation (W/m2).


Total latent heat lost through ventilation (MJ/m2).

A.12.39. vg::VentilationMax
Desc
PARAMETERS
radiation

thresholdRadiation
dayMax

10

environment[radiation].
Threshold radiation day vs. night (W/m2).

100

Max. ventilation opening in the day [0;100].

A.12. vg plugin
nightMax

179
5

Max. ventilation opening in the night [0;100].

double

Max. ventilation opening [0;100].

VARIABLES
signal

A.12.40. vg::WindowsVentilation
Desc
PARAMETERS
Tindoors

Toutdoors

windspeed

windowLength

alphaVentilationMax
fractionWindows

ventilationLeeSide
ventilationWindSide

construction[fractionWindows].
regulation/ventilation/leeSideControl[state].

regulation/ventilation/windSideControl[state].

double

Greenhouse ventilation rate through windows (m3


air/m2 greenhouse/s.

climate/temperature[value].
environment[temperature].
environment[windspeed].
construction[windowLength].
construction[alphaVentilationMax].

VARIABLES
value

180

Appendix A. Plug-ins Reference

References
Abkin MH & Wolf C. Computer library for agricultural systems simulation. Distributed delay
routines: DEL, DELS, DELF, DELLF, DELVF, DELLVF, pages 1-88. Tech. Rep. CLASS-8
(1976), Department of Agricultural Economics, Michigan State University.
Alados I & Alados-Arboledas L. Validation of an empirical model for photosynthetically active
radiation. International Journal of Climatology 19, 1145-1152 (1999).
Banks RB & Herrera FF. Effect of wind and rain on surface reaeration. Journal of the
Hydraulics Division 103, 489-504 (1977).
Benjamin LR & Park SE. The Conductance model of plant growth and competition in
monoculture and species mixtures: a review. Weed Research 47, 284-298 (2007).
Boyd CE & Teichert-Coddington D. Relationship between wind speed and reaeration in small
aquaculture ponds. Aquacultural Engineering 11, 121-131 (1992).
Crusius J & Wanninkhof R. Gas transfer velocities measured at low wind speed over a lake.
Limnology and Oceanography 48, 1010-1017 (2003).
Deacon 1977. Gas transfer to and across an air-water interface. Tellus 29, 363-374 (1977).
Emerson S. Gas exchange rates in small Canadian shield lakes. Limnology and Oceanography
20, 754-761 (1975).
Gelda RK, Auer MT, Effler SW, Chapra SC & Storey ML. Determination of reaeration coefficients: whole-lake approach. Journal of Environmental Engineering 122, 269-275 (1996).
Gelda RK & Effler SW. Estimating oxygen exchange across the airwater interface of a
hypereutrophic lake. Hydrobiologia 487, 243-254 (2002).
Holst N, Lang A, Gabor LOtto M. Increased mortality is predicted of Inachis io larvae caused
by Bt-maize pollen in European farmland. Ecological Modelling, 250, 126-133 (2013).
Jellison R & Melack JM. Meromixis in hypersaline Mono Lake, California. 1. Stratification
and vertical mixing during the onset, persistence, and breakdown of meromixis. Limnology and
Oceanography 38, 1008-1019 (1993).
Kropff MJ & van Laar HH. Modelling Crop-Weed Interactions, pages 1-274. CAB International, Wallingford, UK and International Rice Research Institute, Manila, The Philippinnes, 1993.
Liboriussen L, Landkildehus F et al.. Global warming: Design of a flow-through shallow lake
mesocosm climate experiment. Limnol. Oceanogr.: Methods 3, 1-9 (2005).
Liboriussen L, Lauridsen TL F et al.. Effects of warming and nutrients on sediment community
respiration in shallow lakes: an outdoor mesocosm experiment. Freshwater Biology ?, ?-?
181

182

References

(2010).
Liss PS. Processes of gas exchange across an air-water interface. Deep Sea Research and
Oceanographic Abstracts 20, 221-238. (1973).
Livingstone DM & Imboden DM. The non-linear influence of wind-speed variability on gas
transfer in lakes. Tellus B 45, 275-295 (1993).
Manetsch TJ. Time-varying distributed delays and their use in aggregate models of large
systems. IEEE Transactions on Systems, Man and Cybernetics 6, 547-553 (1976).
Mattingly GE. Experimental study of wind effects on reaeration. Journal of the Hydraulics
Division 103, 311-323 (1977).
OConnor DJ. Wind effects on gas-liquid transfer coefficients. Journal of Environmental
Engineering 109, 731-752 (1983).
Odum HT. Primary production in flowing waters. Limnology and Oceanography 1, 102-117
(1956).
Park SE, Benjamin LR, Aikman DP & Watkinson AR. Predicting the growth interactions
between plants in mixed species stands using a simple mechanistic model. Annals of Botany 87,
523-536 (2001).
Portielje R & Lijklema L. The effect of reaeration and benthic algae on the oxygen balance of
an artificial ditch. Ecological Modelling 79, 35-48 (1995).
Serret P, Robinson C, Fernndez E, Teira E, Tilstone G & Prez V. Predicting plankton net
community production in the Atlantic Ocean. Deep Sea Research Part II: Topical Studies in
Oceanography 56, 941-953. (2009).
Storkey J. Modelling assimilation rates of 14 temperate arable weed species as a function of the
environment and leaf traits. Weed Research 45, 361-370 (2005).
Udo SO & Aro TO. Global PAR related to global solar radiation for central Nigeria. Agricultural and Forest Meteorology 97, 21-31 (1999).
Vansickle J. Attrition in distributed delay models. IEEE Transactions on Systems, Man and
Cybernetics 7, 635-638 (1977).
Wanninkhof RIK, Ledwell JR & Broecker WS. Gas exchange-wind speed relation measured
with sulfur hexafluoride on a lake. Science 227, 1224-1226 (1985).
Wetzel RG. Limnology. Lake and River Ecosystems. Academic Press, San Diego, 2001.

Index
BoundaryLayerResistance, 163
byHumidity, 178
byTemperature, 178
byTemperatureDiff, 178
c, 119, 121, 151
c1, 115
c2, 115
Calendar, 145
capacity, 171
CarryingCapacity carryingCapacity, 134,
137
CH2ORequirement, 128
co2, 167, 176
CO2Assimilation, 124, 126, 128, 129
Community, 117, 125, 132
Competition, 132
CompetitionModel, 132
CompetitiveInhibition, 133
conductance, 117
ControlElement, 163
ControlElementAsym, 163
cosLD, 147
course, 163, 164
coverage, 165
coverArea, 164, 168
CoverDew coverDew, 164, 169
CoverTemperature, 164
CoverVapourFlux, 165
Crop, 111, 165
cropDew, 169
cropEffectOnEmergence, 114
cropLai, 166
cropLaiExp, 114
cropLatentHeatFlux, 169
CropLayer, 165
CropRadiationAbsorption, 166
crops, 113
cropTranspirationConductance, 172
CrossTab, 147
CumulativeEmergence, 143
currentDate, 155

a A, 115, 117, 119, 143, 151


A0, 119
absolute, 157
absorbedRadiation, 165, 166
accumulated, 143
activationRate, 141
actualTpipe, 173
actualValue, 173, 174
Adult, 141
adultsToHibernation, 151
AirInfiltration, 162
airTransmission, 175
alive, 129
allocatedPerPlant, 128, 129
allocation, 124, 127
allocationRate, 128
alpha, 119, 120
alphaVentilationMax, 168, 179
AlwaysIncludedPopulations, 132
Anonymous, 145
apparancy, 149
apparencyMatrix, 150, 153
Ar, 119
Area area, 124, 126
AreaDensityEven, 124
AreaDensitySymmetric, 125
AreaDensityTapering, 125
AreaDensityTopheavy, 125
AssimilationMaxGivenTemp, 125
AsymptoticDecreasing, 145
AsymptoticIncreasing, 145
attacksPerHost, 149
availableProduction, 130
AvailableResource, 133
averageHeight, 168
avgs, 140
awe, 111
b, 115, 119, 143, 151
ballastCorrection, 171
beta, 120
BlackoutScreenController, 162

183

Index

184
currentDateTime, 155
currentPartition, 128
currentTime, 155
d, 151
dailyEmergenceDensity, 114
dailyEmergenceRatio, 114
dailyEmergenceRatioPotential, 115
dailyFecundity, 142
dailyLoss, 142
dailyRainfall, 142
date, 146
dateAsReal, 147
dateMax, 121
dateShift, 121, 161
dateTime, 146
day, 112, 127, 146, 171
DayDegrees, 147
dayLength, 147
daylightThreshold, 170
dayMax, 178
dayOfYear, 146
Days days, 148, 157
deadAdults, 151
demand, 149
DemandRate, 135
density Density density, 129, 132, 135, 137,
138, 140, 141
DensityActivityCoefficient, 135
DepositionFlush, 120
DepositionMonotonicSampled, 120
DepositionMonotonicWeibull, 120
dew, 165, 166, 175
dewHeat, 169
dewScreen, 164
diffuse, 171
diffuseRadiation, 165, 166, 167
diffuseTransmission, 171
direct, 171
direction, 173, 174
directRadiation, 168
distance, 122
distanceExp, 122
distanceMin, 122
dormant, 114
dormantInflow, 114
dose, 121

duration, 120, 157, 158


dweight, 118
dynamic_photosynthesis, 119
EarlyGrowth, 126
earlyGrowthThreshold, 125
eclosedReproductiveAdults, 150
ecotox, 120
ED50, 121
Effect, 133
EffectRatio, 134
egestion, 149
egestionRatio, 149
Egg, 141
eggProduction, 150
eggsActivated, 141
eggsLaidInWater, 141
eggsLaidOnGround, 141
eggsLost, 141
emergenceCalendar, 114
EnableCompetition, 132
EnableEffect, 133, 134
EnableStochasticCommunity, 132
energyBalance, 169, 170, 173
EnergyScreenBalance, 167
EnergyScreenController, 167
energyScreenCourse, 173
energyScreenState, 169
energyUse, 171
energyUsed, 174
Environment, 167
EnzymaticReaction, 133
eps, 118
Evenness, 132
Exponential, 148
F, 117
factor, 156
fecundity, 141
fileLocation, 155
fileName, 147, 151, 155, 156, 160
firstDateTime, 155
FirstOrderRateConstant, 135
FirstOrderReaction, 134
Fixed, 148
floorHeat, 169
floorHec, 168, 169
followEnergyScreen, 162, 176

Index
fractionWindows, 168, 179
frequency, 161
fromDate, 161
fromTime, 162
FunctionalResponseGB, 149
fz, 118
g, 116
gapMultiplier, 174
GeneralEffect, 134
GiniCoefficient, 132
glassType, 168, 170
GreenhouseConstruction, 168
GreenhouseEnergetics, 169
GreenhouseVentilation, 169
grossProduction, 124, 126, 128, 129
groundArea, 164, 168, 178
growthIncrement, 158, 159
GrowthRate growthRate, 126, 134, 137, 148,
157, 158
growthResp, 128, 130
gSini, 119
0, 126
harvestDay, 111
harvestMonth, 111
heatCapacity, 169, 170, 173
heatEmission, 171
heatFlux, 174
HeatingDemand heatingDemand, 170, 173
Height height, 126, 127, 162, 168, 172, 178
hmax, 126
hour, 146
humidityDecrement, 177
humidityIncrement, 177
HumiditySetpoints, 170
HydrodynamicSRScale, 137
HydroThermalTime, 149
iGlassType, 168
iLampType, 168
imposeInitialDateTime, 155
Inachis, 150
InactiveEgg, 141
increment, 148, 156
inDensity, 139
indoorsDirectRadiation, 167
IndoorsRadiation, 170
indoorsTemperature, 167, 177

185
Infection, 144, 150
infectionRate, 144
inflow, 141, 157, 159
inflowAsDensity, 113
inflowAsDensityEqs, 113
inflowTotal, 158, 159
InhibitionConstant, 133
InhibitorConcentration, 133
initDay, 117
initial, 130
initialArea, 126
initialDate, 146
initialDensity InitialDensity, 113, 134, 137,
141
initialInflow, 157
initialN, 137
InitialResource, 132
InitialSubstrate, 133, 134, 135
initialTimeOfDay, 146
initialValue, 142, 148
initMonth, 117
initSignal, 173
initState, 163
initWeight, 117
inoculumDensity, 144
InsectLifeCycle, 150
instantLossRate, 157, 159
InstantMortality instantMortality, 112, 113,
114, 127, 157, 159
intercept, 127
intercom, 124
intrinsicRate, 137
irradiation, 118, 130
IsActive, 134
isHigh, 172
isHumidityHigh, 163, 167, 176
isInEarlyGrowth, 126
iteration, 156
k, 118, 157, 158
Kcover KCover, 167, 168, 169
kdiff kDiff, 165, 166
kDiffuse, 124
Kp, 173
KScreenEnergy, 169
Kt, 150
LA_per_plant, 118

186
LactinTime, 151
LagPhase, 134
lai LAI, 112, 113, 118, 124, 126, 129
laiCalendar, 112
LampAttributes, 171
lampHeat, 169
lampLongWaveEmission, 166
lampShortWaveEmission, 166
lampType, 168, 171
lastDateTime, 155
latcov, 164, 168
latentHeatFlux, 165, 166
latestInflow, 158, 159
latitude, 146
Leaf, 119
LeafProduction, 144
leakage, 162
leavesInfected, 144
leeSideSignal, 178
length, 168
lightAbsorption, 124, 126, 128, 129
LightController, 171
lightTransmission, 175
LightUseEfficiencyGivenTemp, 127
log10, 151
LogLogistic, 121
logy, 152
longWave, 166
longWaveAbsorption, 166
longWaveEmission, 171
longWaveLight, 169
LossB, 137, 140
LossN, 137, 140
lossRate, 141
lower, 121
lowerPipeHeatFlux, 166
Lz, 118
maintenanceCoeff, 128
maintenanceResp, 128, 129
Map, 151
Mass mass, 127, 129
max, 145, 154
maxAmax, 125
maxflow, 137
maximum, 177
MaximumVelocity, 135

Index
maxN, 140
MaxPopulations, 132
maxRH, 170, 172
maxRHDay, 170
maxRHNight, 170
maxSignal, 174, 178
maxSignalHighHumidity, 162, 167, 176
maxSR, 138
maxSteps, 156, 160
maxTemperature, 178
maxTime, 160
maxTries, 153, 154
maxValue, 153, 154
maxYield, 111
maxYieldLossPct, 111
mc, 168, 172
mcCropSurface, 172
mcIndoors, 164, 165, 175, 178
mcOutdoors, 172, 178
mean, 153, 154
MichaelisMentenConstant, 135
MicrobialCommunity, 132
MicroclimateHumidity, 172
MicroclimateTemperature, 172
min, 145, 154
minDeltaX, 170, 172
minDeltaXBasis, 170
minimum, 177
MinPopulations, 132
minute, 147
minValue, 153, 154
moistureDeficit, 172
month, 112, 127, 146
mortalities, 112
mortality, 139
MortalityRate, 134
MosquitoFecundity, 142
Mussel, 137
mussel_bed, 137
MusselGrowthRate, 137
n N, 118, 137, 140
netAllocation, 128, 130
nextDate, 155
nextDateTime, 155
nextTime, 155
nightMax, 179

Index
nonDormant, 114
Npeak, 122
number, 114, 158, 159
numHostsAttacked, 149
numIterations, 155, 156
numTimeSteps, 164, 175
offDay, 171
offRadiation, 171
offTime, 171
onDay, 171
onRadiation, 171
onsetFileName, 120
onTime, 171
Organ, 128
outdoorsDiffuseRadiation, 170
outdoorsDirectRadiation, 170
outdoorsHeat, 169
outdoorsTemperature, 167, 177, 178
outflow, 158, 159
outflowAsDensity, 113
outflowAsDensityEqs, 113
outflowTotal, 158, 159
parameters, 148
parDiffuse, 131
parDirect, 131
parEmission, 171
PARmin, 119
PartitioningFixed, 128
PartitioningFixedByStage, 129
parTotal, 131
pBand, 174
penWidth, 152
perPipe, 170
PgcMol, 176
phase, 118
phaseDuration, 159
phaseInflow, 157, 159
phaseInflowTotal, 158, 159
phaseK, 159
phaseOutflow, 158, 159
phaseOutflowProportion, 158
phaseOutflowTotal, 158, 159
phaseTimeStep, 159
Phenology, 129
phi, 117
PhotoThermalTime, 152

187
PidControl, 173
Pipe, 173
pipeLength, 173
Pipes, 174
pipesHeatFlux, 173
pipeType, 173
Plant, 117, 129
PlantGrowthStage, 112
Plot, 152
Pollen, 121
pollenDensity, 122
pollenDepositionRate, 122
pollenDepositionTotal, 122
PollenLossConstant, 122
PollenLossSampled, 123
Population, 134
Predation, 152
prevRh, 172
productionRate, 144
progress, 154, 157, 160, 161
projectedDeqs, 116
projectedMass, 116
projectedYieldLossPct, 116
propAllocatedPerPlant, 128
propHostsAttacked, 149
ProportionalControl, 174
proportionEggsInWater, 141
radiation, 162, 167, 170, 172, 176, 178
radiationThreshold, 162, 167, 176
radix, 125
randomizeInitialYear, 155
RandomLognormal, 153
RandomNormal, 153
RandomPoisson, 153
RandomUniform, 154
range Range, 151, 154
rate, 122, 163
rateDown, 164
rates, 123
rateUp, 164
ratio, 176
rbH2O, 165, 166, 176
Reaction, 135
Records, 154
relative, 157
resourceDensity, 149

188
respiration, 149
rh, 167, 172, 176
Richness, 132
riH2O, 166
roofRatio, 162, 168
Rotation, 113
RunIteratorFixed, 155
runNumber, 157, 160, 161
rvf, 141
S, 119
S0, 119
S60, 119
SalinityScale, 138
SalinitySRScale, 138
scale, 154
scatteringCoeff, 124
Scenarios, 156
schedule, 156
Scheduled, 156
screenDew ScreenDew, 169, 175
Screens, 175
screensAirTransmission, 162
screenState, 172, 175
ScreenTemperature, 175
screenTransmission ScreenTransmission,
166, 175
sd, 153
sdRatio, 149, 157, 158
SearchRate searchrate, 134, 138
second, 147
seconds, 157
seed_emergence, 143
SeedBank, 113
seedProdExp, 115
seedProdSlope, 115
seedsDropping, 116
SensitivityAnalysis, 156
Seq, 119
setMaximum, 177
setMinimum, 177
sexRatio, 141, 150
ShadeScreenController, 176
ShannonIndex, 132
shortWave, 166
shortWaveEmission, 171
shortWaveLight, 169

Index
sideRatio, 162, 168
signal, 163, 167, 172, 173, 174, 176, 177, 178,
179
signalDay, 172
signalNotNegative, 174
signalRadiation, 172
signalTime, 172
SimpsonIndex, 132
sinb, 147, 170
Sini, 119
sinLD, 147
skyTemperature, 168
slope, 121, 126, 127, 130, 145
slopeYieldLossPct, 111
Smax, 138, 139
Smin, 138, 139
sourceModel, 144
sowingDay, 111
sowingMonth, 111
SpeciesName, 134
SpecificLeafArea, 130
Stage stage, 157, 159
StageAndPhase, 158
StageDemand, 159
Starfish, 138
StarfishFeedingRate, 139
StarfishGrowthRate, 139
StarfishSalMortality, 139
state, 163, 164, 175
stdensity stDensity, 139, 139
step, 147, 148, 150, 151, 152
stepNumber, 157, 160
steps Steps, 151, 160
stgrowthRate, 139
StomatalResistance, 176
strawberry, 144
Substrate, 133, 134, 135
SubstratePDD, 133, 134, 135
Sum, 160
sum_sz, 117
supply, 139, 140, 149
SupplyDemandRatio, 135
surfaceMoistureContent, 165, 166
survival, 127
SWP, 143
SWP0, 150

Index
swpThreshold, 150
SWPTopt, 150
symbolSize, 152
sz, 118
T, 115, 147, 150, 152
T0, 147, 149, 152
Table, 160
targetModel, 144
TargetParameter, 134
TargetPopulations, 133, 134
targetValue, 173, 174
Tavg, 115, 130, 143, 161
Tcover, 164, 172, 175
Td, 173
Tday, 130
temperature, 139, 140, 165, 166, 167, 172,
175, 176
TemperatureScale, 140
TemperatureSetpoints, 177
TemperatureStScale, 140
temperatureThreshold, 176
testMode, 126
Tfloor, 169
theta, 118, 119
thin, 140
thinning, 140
thresholdRadiation, 178
Ti, 173
time, 162, 171
TimeLimited, 160
timeOfDay, 146
timeStep, 146, 158, 159
timeStepOffset, 146
timeStepSecs, 146, 162, 163, 164, 172, 173,
175, 178
timeStepsSecs, 174
timeUnit, 146
Tindoors, 164, 165, 166, 173, 175, 179
title, 152
tm, 119, 126
Tmax, 147, 149, 152
TmaxPipe, 174
Tminimum, 170, 173
toAdd, 160
toDate, 161
tolerance, 176

189
Topt, 147, 149, 152
total, 120, 121, 148, 150, 151, 152, 170
total_sz, 118
totalDays, 146
totalDemand, 149
totalEggsInflow, 141
totalEmergenceDensity, 114
totalEmergenceRatio, 114
totalLoss, 178
totalSupply, 149
totalTime, 146
totalTimeSteps, 146
totalWeight, 118
toTime, 162
Toutdoors, 164, 169, 179
transpirationConductance, 165, 166
triggerAtReset, 161
TriggerByDate, 161
ts, 119
Tscreen, 172, 175
Tsky, 164
Tsum, 112, 115
Tunheated, 169, 173
UniSim, 145
upper, 121
useTemperature, 119
value, 120, 121, 122, 123, 124, 125, 127, 128,
129, 130, 137, 138, 139, 140, 142, 144,
145, 148, 153, 154, 156, 158, 159, 160,
161, 162, 163, 164, 165, 167, 169, 173,
175, 176, 178, 179
values, 129
Velocity, 133, 134, 135
VelocityPDD, 133, 134, 135, 136
ventilation, 163, 169, 172, 178
VentilationByTemperatureDiff, 177
VentilationController, 177
VentilationLatentEnergyBalance, 178
ventilationLeeSide, 179
ventilationMax VentilationMax, 177, 178
ventilationWindSide, 179
vg, 162
volume, 168
vp, 168, 172
vpd, 172
vpdIndoors, 165

190
vpIndoors, 165
waterLevel WaterLevel, 142, 142
waterLevelThreshold, 142
Weather, 115, 118, 130, 143, 161
Weed, 115
weedExchangeRate, 111
weight, 118
width, 168
windDirection, 167
windowHeight, 168
windowLength, 168, 179
WindowsVentilation, 179
windSideProportion, 177
windSideSignal, 178
windSpeed windspeed, 162, 163, 164, 167,
178, 179
writeTestOutput, 124
x, 145
year, 146
yearlyEmergenceRate, 114
yearlyMortalityRate, 114
ymax, 152
ymin, 152
ZeroOrderRateConstant, 135
ZeroOrderReaction, 135

Index

S-ar putea să vă placă și