Creating a New Model

The code that explicitly defines the Eco Lab model is contained in ecolab.cc. Several examples of a completely different models is provided with the Eco Lab distribution. Most of these are described in different papers:

shadow
Ecolab model with a neutral shadow model, as described in [8] and [9].
newman
A variation of Mark Newman's evolutionary model, described in [6]
webworld
An implementation of Drossel et al.'s Webworld model, described in [2] and [10].
jellyfish
A model of Jellyfish migration in Palauan lakes, in collaboration with Mike Dawson. This model will be described in more detail in §12.
netcomplexity
A class providing TCL methods for computing network complexities. Used in the study reported in [11]

A model typically consists of an interface file (.h), which is processed by Classdesc, an implementation file (.cc) and one or more experiment scripts (.tcl).

The model should, as far as possible, be implemented as a single object (which may be a container). Let's call the model JoesFolly. The model class (eg JoesFolly_t) is defined in the interface file in a regular C++ fashion. It is simplest if all members of the model class are public, however read the Classdesc chapter for how to handle private members.

Consider whether your model maps naturally to the notion of objects related by a network. In that case, you may find that Graphcode will effectively distribute your model across multiple processors of an MPI parallel job. Both the spatial EcoLab model, and the Jellyfish model are examples of Graphcode deployment.

Your model class needs to be derived from TCL_obj_t. This adds a few extra methods to your class, such as checkpoint/restart, and client/server functionality.

class JoesFolly_t: public TCL_obj_t
{
  public:
   int an_instance_var;
   double a_method(TCL_args);
};

You then define your model object in the implementation file, and pass this object to the macro make_model.

#include <ecolab.h>
#include "JoesFolly.h"
#include "JoesFolly.cd"
#include <ecolab_epilogue.h>

JoesFolly_t JoesFolly;
make_model(JoesFolly);

double JoesFolly(TCL_args args)
{
  double x=args, y=args;
  ...
}

The supplied Makefile in the models directory can be used as a template for your own project. It contains rules that generate Makefile dependencies for all include files included with "". It will launch classdesc to generate descriptors for all class definitions in JoesFolly.h. All public instance variables are visible to TCL, as are methods that take no arguments, or a single TCL_args argument.

Of course these instance variables or members are only actual accessible from TCL if their type T has a operator<<(ostream&,T) defined. Accessing other types of object will result in a runtime error.

Note that Standard C++ requires functions used by templates be declared prior to templates being defined. Since the .cd files are declaring functions like pack, TCL_obj etc., templates that call these functions must be declared after all .cd files are included, otherwise the templates will not pick up the definitions in the .cd files. This is achieved by including ecolab_epilogue.h after the all the .cd files have been included in the .cc file. In fact, now Eco Lab insists on the presence of this file if classdesc is used, and will generate a link time failure if not provided:

undefined reference to `(anonymous namespace)::classdesc_epilogue_not_included()'
undefined reference to `(anonymous namespace)::TCL_obj_template_not_included()'