Educational Examples
'Hello World'
Purpose
- It does not get simpler than printing out 'Hello World'. One component that is called from the hello.sim file.
Implementation
- The component hellowworld.Component takes one input and prints out the message on execute.
package helloworld;
import oms3.annotations.*;
@Description("A simple component").
public class Component {
@In public String message;
@Execute
public void run() {
System.out.println(message);
}
}
- The simulation file hello.sim passes the message to the component as input (parameter).
/*
* Hello 'world' example.
* A component printing a greeting.
*/
sim {
model(classname:"helloworld.Component") {
parameter {
message "Hello World ..."
}
}
}
OMS3/NetLogo Integration Prototype.
Purpose
- Prototype the integration of a NetLogo model as an OMS3 component. The NetLogo Fire model is used as an example to demonstrate the integration.
Method
- The original NetLogo source that should become a OMS3 component gets annotated with
OMS3 style meta data annotations. Such annotations are consistent across
all supported languages such as C,FORTRAN, and NetLogo.
- OMS picks up the annotation as a part of component build process,
automatically generates an OMS3 component that connects to the NL model using
the NetLogo API via the annotated elements.
What has to be done from a NetLogo developer's perspective?
- Identify the NetLogo variables (usually globals) to be used to exchange
data with other components.
- Annotate the global data with @In and @Out.
- Annotate the NetLogo entry point to call the model with @Execute.
OMS3 annotated NetLogo Example (Fire.nlogo fragment):
1 ; @Description("Simulates the spread of a fire through a forest.")
2 ; @Author(name="NetLogo user")
3 globals [
4
5 ; @In
6 ; @Description("Forest density")
7 ; density
8
9 ; @Out(name="burned_trees")
10 ; @Description("Number of burned trees.")
11 burned-trees
12
13 initial-trees ;; how many trees (green patches) we started with
14 ]
15
16 ; @Execute
17 to execute ;; the execution function
18 random-seed 0
19 setup
20 repeat 50 [ go ]
21 end
22 ...
23 ; more code to follow
Lines 1,2,5,6,9,10,16 contain OMS3 Annotations within comments.
Implementation Notes
- Annotations have to be 'one-liner', hidden as a NetLogo comment. Only one annotation
per line. Only one kind of annotation per variable.
; @Description("State Variable")
; @In
state_var
- If a NetLogo variable name conflicts with the conventions for Java identifier, the
the annotation can have an optional name attribute providing a valid Java variable
identifier as an alias. In the example below, the name burned-tree cannot be mapped to
Java, since '-' is not a legal character for an identifier. The solution:
; @Out(name="burned_trees")
burned-trees
- NetLogo variables are duck typed, therefore it needs no type declaration. When mapped to
Java Object via OMS3, the default type assumption is a Number since OMS3 needs a
type declaration for a given object. However the default type 'java.lang.Number' can
be changed to any type by just adding the full qualified java type (except 'java.lang'
package) to the 'type' attribute of an @In or @Out annotation.
; @Out(type="String")
message
OMS3/Fortran9x Integration Example.
Purpose
- Prototype the integration of a FORTRAN model as an OMS3 component. Demonstrate the use of OMS3 annotations for FORTRAN source code.
Method
- Annotating plain FORTRAN 9x code maks it a OMS3 component by using
OMS3 style meta data annotations. Such annotations are consistent across
all supported languages such as Java, C,FORTRAN, and NetLogo.
- There is one component that makes the model. The component has different parameter types.
MainOMS.f90
! @Description ("WEPP hillslope erosion component")
! @Author (name="j.c. ascough ii and d.c. flanagan")
! @Keywords ("Erosion")
! @VersionInfo ("$Id: MainOMS.f90 367 2009-08-28 22:21:52Z odavid $")
! @License ("http://www.gnu.org/licenses/gpl-2.0.html")
! @Documentation ("BasinSm.xml")
! @Execute
SUBROUTINE wecall(eroout, eroout_len, eroplot, eroplot_len, runoff, peakro, effdrn, npart, spg, outd)
USE, INTRINSIC :: ISO_C_BINDING
IMPLICIT NONE
! @Description("Erosion output name")
! @In
CHARACTER(kind = C_CHAR, len = eroout_len) :: eroout
INTEGER(C_INT), VALUE :: eroout_len
! @Description("Erosion plot name")
! @In
CHARACTER(kind = C_CHAR, len = eroplot_len) :: eroplot
INTEGER(C_INT), VALUE :: eroplot_len
! @In
REAL(C_FLOAT) :: runoff, peakro, effdrn
! @In
INTEGER(C_INT) :: npart
! @In
REAL(C_FLOAT), DIMENSION(npart) :: spg
! @Out
REAL(C_FLOAT) :: outd
print *, runoff, peakro, effdrn
print *, npart
print *, spg
print *, eroout
print *, eroplot
print *, 'done...... '
outd = outd + 4.36
END SUBROUTINE
Installation Requirements
To compile and run this example you need to have ANT 1.8+, and some GCC 4.x version installed that contains gfortran. the commands for ant and gfortran have to be in the PATH variable. The example project was tested under Linux, Windows, and OSX.
helloworld.zip
-'Hello World' example Project