Operation models are the implementations of the various forestry operations in SIMO. The operation models can be divided into two classes: cost only operations, and operations that modify the simulation data. Cost only operations have only an associated cost, but do not modify the data; e.g. soil preparation model. Models that modify data have also an associated cash flow (cost or income), but besides that they also modify the data, for example by removing trees (e.g. thinning model) or adding trees (planting model)

Operation models can currently be implemented only in Python in SIMO due to the complex data structures that are passed between simulator and the model implementation. For details on these data structures, see *simo.simulation.caller.operationcaller.py* and *simo.simulation.model.operationarg.py*.

All SIMO operation models share the same set of input parameters. When implementing new operation model, remember to assign the following list of parameters as the function parameters:

*data*– data by level in a dictionary where*key*= level and*value*= 2d numpy array*variables*– operation variable values in a 1d numpy array*parameters*– operation parameter values in a 1d numpy array*parameter_table_values*– values from parameter tables (simulator handles the table processing)*cash_flow_table*– cash_flow structure*cash_flow*– size 1 numpy array*results*– container (a numpy array for scalars or a list of date value tuples for date-arrays) for returning operation results*warnings*– container for returning warnings*errors*– container for returning errors

Below is an example of operation model function definition:

```
def clearcut(data, variables, parameters, parameter_table_values,
cash_flow_table, cash_flow, results, warnings, errors):
"""Remove all trees except a number of reserve trees from a stand.
"""
```

The bucking algorithm used in SIMO operation models is based on Näsberg’s (1985) dynamic optimization algorithm for optimal stem cutting. The stem cutting is optimized for maximum value with given price matrix for the various timber assortments. The bucking algorithm is implemented as a dynamically loaded C function.

The price matrix is a 2-dimensional array, where each row represents a single timber assortment class. The columns are: timber assortment indice, minimum diameter, minimum length and value (ie. price in euros). Below is a simple example of price matrix with four timber assortment classes. The assortment indices in the first column are 1=log and 2=pulp:

```
...
1. 160. 370. 55.
1. 160. 400. 57.
1. 160. 430. 59.
2. 70. 300. 17.
...
```

Tree stem profile is a 2-dimensional array where each row represents a single tree stem segment, cut with given divisor. The columns are segment top diameter, segment top height and cumulative volume, starting from the bottom segment. The tree stem and the stem segments are computed using taper curve functions by Laasasenaho (1982), separately for each tree species. Below is a simple example of a tree stem array:

```
...
235. 120. 0.002345
229. 150. 0.002891
222. 180. 0.003210
...
```

Below is a pseudo code description of the bucking algorithm (indexing arrays etc starts from 1):

```
INPUTS:
div -- tree stem divisor (segment length), double
n -- number of tree segments, integer
m -- number of timber assortment price classes, integer
P -- price matrix as a 2-dimensional array of size m x 4
T -- tree stem profile as a 2-dimensional array of size n x 3
// Initialize arrays V for storing volumes and C for storing values
// (...and fill the arrays with zero values)
SET V to 1-dimensional double array of size n
SET C to 1-dimensional double array of size n
// Initialize arrays A for storing timber assortment indices and L for
// storing log bottom positions (...and fill the arrays with zero values)
SET A to 1-dimensional integer array of size n
SET L to 1-dimensional integer array of size n
// Initialize some auxiliary variables
SET t to 1
SET d_top to 0.0
SET d_min to 0.0
SET v to 0.0
SET c to 0.0
SET v_tot to 0.0
SET c_tot to 0.0
FOR i = 1 to n
FOR j = 1 to m
// Get a location indice t for the top segment of the current stem
// piece when the location indice for the bottom segment is i
// (divide the height with the stem divisor)
t = i + P[j][3] / div
IF t is less than n THEN
// Get the top diameter of the current tree segment and check
// if the diameter is greater than the minimum assortment
// diameter defined in the price matrix P
d_top = T[top][1]
d_min = P[j][1]
IF d_top is greater than or equal to d_min THEN
// Calculate current tree stem's (bottom at i, top at t)
// volume v and the cumulative value c
v = T[t][3] - T[i][3]
c = v * P[j][4]
// Calculate the total volume and value at location i
v_tot = v + V[i]
c_tot = c + C[i]
// If total value, calculated as the value of the current
// log plus all the logs below i, is higher than the
// existing value in t, overwrite the existing value
// with c_tot
IF c_tot > C[t] THEN
V[t] = v_tot
C[t] = c_tot
A[t] = P[j][0]
L[t] = i
ENDFOR
ENDFOR
// Get the location indice for the maximum value in C[t] array by calling
// appropriate function
CALL get_max_indice with C RETURNING maxi
// Define arrays for storing timber assortment volumes and values
SET VOLUMES to 1-dimensional double array with size equal to number of assortments
SET VALUES to 1-dimensional double array with size equal to number of assortments
// define some auxiliary variables
SET a to 1
SET l to 1
// Cut the tree to optimal length logs and divide the values and
// volumes to corresponding assortments, start from the top
WHILE maxi is greater than 0
a = A[maxi]
l = L[maxi]
VOLUMES[a] = VOLUMES[a] + V[maxi] - V[l]
VALUES[a] = VALUES[a] + C[maxi] - C[l]
// Move to the next stem piece (under the current piece)
maxi = l
ENDWHILE
OUTPUTS:
VOLUMES -- volumes of each timber assortment
VALUES -- values of each timber assortment
```

References:

Laasasenaho, J. 1982. Taper curve and volume functions for pine, spruce and birch. Seloste: Männyn, kuusen ja koivun runkokäyrä- ja tilavuusyhtälöt. Comm. Inst. Forestalis Fenniae 108. 72 s.

Näsberg, M. 1985. Mathematical programming models for optimal log bucking. Department of Mathematics. Linköping Studies in Science and Technology. Dissertation No. 132. Linköping University, Sweden. 199 p.