Engee documentation
Notebook

Population dynamics with catch

In this example, we show how easy it is to create and solve a differential equation that allows you to model the dynamics of a catch-weighted fish population.

Model description

We will be modelling a fish population in a water body subject to the following processes:

  • the effects of fertility and mortality are described by a quadratic function $ax + bx^2$
  • the catch target reduces the population by $h$ tonnes annually
  • the initial population size is $x_0$.

Thus we create a model of the following problem:

$$\frac{dx}{dt} = (a + bx) x - h$$

$$x(0) = x_0$$

The general form of the flowchart by which this problem can be modelled is as follows:

image.png

All parameters are easily accessible and can be set either from the script (via variables) or on the canvas itself. Numerical integration will help us to solve this system, but it is worth remembering:

  • there are combinations of input conditions that make the solution unstable (population goes to $\pm \infty$);

  • when unstable, the constant step solver may not report an error, this is why a variable step solver is selected in the model settings;

  • the maximum simulation step size is set to 0.01, so that we still get a smooth graph on the interval 0...1, even if the problem conditions allow us to make bigger steps.

Running and analysing the results

Let's run the model using the software control tools:

In [ ]:
# Загрузим модель, если она еще не открыта на холсте
if "fish_population_diff_eq_model"  getfield.(engee.get_all_models(), :name)
    engee.load( "$(@__DIR__)/fish_population_diff_eq_model.engee");
end
Out[0]:
Model(
	name: fish_population_diff_eq_model
	id: bed18597-4e29-47c9-8729-257f0e2e80b6
)

Let's display a graph of the dependence of population dynamics on the change of its initial size:

In [ ]:
# Запустим модель
model_data = engee.run( "fish_population_diff_eq_model" );

# Прочитаем нужные параметры для вывода графика
param_vector = engee.get_param("fish_population_diff_eq_model/Начальное количество рыбы (т)", "Value");

plot( model_data["x"].time, hcat( model_data["x"].value... )',
      label=reshape(param_vector, 1, :), lw=2,
      title="Зависимости изменения популяции от начального количества (т)", titlefont=font(10),
      xlabel="Время, г", ylabel="Популяция, т" )
Out[0]:

Now let's set one value x0 and plot the dependence on changes in the annual catch plan:

In [ ]:
param_1 = engee.get_param("fish_population_diff_eq_model/Годовой план вылова (т)", "Value" );

# Поменяем параметры модели
engee.set_param!( "fish_population_diff_eq_model/Начальное количество рыбы (т)", "Value"=>"5.0" );
engee.set_param!( "fish_population_diff_eq_model/Годовой план вылова (т)", "Value"=>"0.5:0.2:2" );
# # Запустим модель
model_data = engee.run( "fish_population_diff_eq_model" );
# # Получим параметры модели для графика
param_2 = engee.get_param("fish_population_diff_eq_model/Годовой план вылова (т)", "Value" );

plot( model_data["x"].time, hcat( model_data["x"].value... )',
      label=reshape(param_2, 1, :), lw=2,
      title="Зависимости изменения популяции от задания на вылов (т)", titlefont=font(10),
      xlabel="Время, г", ylabel="Популяция, т" )
Out[0]:

And return the model to the initial state.

In [ ]:
engee.set_param!("fish_population_diff_eq_model/Годовой план вылова (т)", "Value"=>param_1 );
engee.set_param!("fish_population_diff_eq_model/Начальное количество рыбы (т)", "Value"=>string(param_vector) );

Conclusion

Solving differential equations using a flowchart and integrator simplifies the transfer of knowledge between representatives of different specialities, as we have seen in the example of solving the differential equation of population growth.

Blocks used in example