Build Simple Models

We represent community models as objects of type Model. The Model contains all the parameters needed to simulate the dynamics of a community of species. These parameters correspond mostly to species traits and interaction strengths. They can be set up manually or generated automatically from a Foodweb.

Create a Default Model

The Model contains many parameters, and it can be cumbersome to set them all up manually. Therefore, we provide a function default_model that generates a model with default parameters to ease the process. The function default_model generates a model from a Foodweb.

By default, the predator functional response is classic and the producer growth is logistic. Moreover, species traits are taken from Miele et al. (2019). For details on the default parameters, see the Parameter Table.

If you want to change the default parameters, you can do so by passing the corresponding component as an argument to the default_model function. For instance, by default species body masses are set so that the predator body mass is 10 times the prey body mass.

m1 = default_model(Foodweb([3 => 2, 2 => 1]))
m1.body_masses
3-element EcologicalNetworksDynamics.BodyMasses:
   1.0
  10.0
 100.0

But let's say you want to set the body mass of all species to 1.5, then you can do:

m2 = default_model(Foodweb([3 => 2, 2 => 1]), BodyMass(1.5))
m2.body_masses
3-element EcologicalNetworksDynamics.BodyMasses:
 1.5
 1.5
 1.5

You can also change the default predator-prey body mass ratio to set up species body masses:

m3 = default_model(Foodweb([3 => 2, 2 => 1]), BodyMass(; Z = 5))
m3.body_masses
3-element EcologicalNetworksDynamics.BodyMasses:
  1.0
  5.0
 25.0

In the example above the body mass of the predator is 5 times the body mass of the prey, starting with a body mass of 1 for the primary producer.

Access the Model Data

The parameters held by the model can be accessed via the various model properties, with functions named get_<X>:

get_hill_exponent(m)
2.0
get_body_masses(m)
3-element EcologicalNetworksDynamics.BodyMasses:
   1.0
  10.0
 100.0
get_efficiency(m)
3×3 EcologicalNetworksDynamics.EfficiencyRates:
 0.0   0.0   0.0
 0.45  0.0   0.0
 0.0   0.85  0.0

Alternatively, you can access the same data with the following syntax:

m.hill_exponent # Same as get_hill_exponent(m).
m.body_masses # Same as get_body_masses(m).
m.efficiency # Same as get_efficiency(m).

The properties of the model can be viewed with:

properties(m)
63-element Vector{Any}:
 :A
 :K
 :M
 :S
 :body_masses
 :carnivorous_links
 :carrying_capacity
 :consumers_dense_index
 :consumers_indices
 :consumers_mask
 ⋮
 :tops_dense_index
 :tops_indices
 :tops_mask
 :tops_sparse_index
 :trophic_levels
 :trophic_links
 :w
 :x
 :y

Change the Model Data

Some parameters can be modified after the model was created, either with set_<x>!(m, value) or m.<x> = value. However, not all parameters can be modified in this way for consistency issues. For instance, many parameters are derived from body masses, therefore changing the body masses would make the model inconsistent.

# OK: terminal data can be changed.
set_hill_exponent!(m, 2.1)
m.hill_exponent = 2.1 # (same)

# Not OK: this would make the rest of the model data inconsistent.
m.body_masses = [1, 2, 3]
ERROR: In property 'body_masses' of '<inner parms>': This property is read-only.

If you need a model with different values for non-modifiable properties, you need to build a new model with the values you desire.

Create Your Own Model Manually

It is also possible to create a model manually by adding the components one by one. First, create an empty model:

m = Model()
Model (alias for EcologicalNetworksDynamics.Framework.System{<inner parms>}) with 0 component.

Then add your components one by one. Note that you have to add the components in the right order, as some components depend on others. Moreover, some components are mandatory. Specifically, you need to provide a food web, species metabolic classes, body masses, a functional response, metabolic rates and a producer growth function.

m = Model()
m += Foodweb([3 => 2, 2 => 1])
m += BodyMass(; Z = 3)
m += MetabolicClass(:all_invertebrates)
m += ClassicResponse(; h = 2)
m += LogisticGrowth(; r = 1, K = 10)
m += Metabolism(:Miele2019)
m += Mortality(0)
Model (alias for EcologicalNetworksDynamics.Framework.System{<inner parms>}) with 17 components:
  - Species: 3 (:s1, :s2, :s3)
  - Foodweb: 2 links
  - Body masses: [1.0, 3.0, 9.0]
  - Metabolic classes: [:producer, :invertebrate, :invertebrate]
  - Efficiency: 0.45 to 0.85.
  - Hill exponent: 2.0
  - Consumers preferences: 1.0
  - Intra-specific interference: [·, ·, ·]
  - Handling time: 0.05060399708831881 to 0.17705290320783398.
  - Attack rates: 81.97370583794364 to 158.4700962824307.
  - ClassicResponse
  - GrowthRate: [1.0, ·, ·]
  - Carrying capacity: [10.0, ·, ·]
  - ProducersCompetition: 1.0
  - LogisticGrowth
  - Metabolism: [0.0, 0.23858840529460007, 0.18128798452554248]
  - Mortality: [0.0, 0.0, 0.0]

Now we have a model ready to be simulated. We explain how to do so in the section Simulate the Model. But, first we explain how to create more sophisticated models in the following section Build Advanced Models.