Rceattle C++ template
The CEATTLE likelihood: src/TMB/ceattle.cpp and its headers
Loading...
Searching...
No Matches
bioenergetics.hpp
Go to the documentation of this file.
1#ifndef BIOENERGETICS_HPP
2#define BIOENERGETICS_HPP
3
4/**
5 * @brief Temperature-dependent function of consumption (fT) for bioenergetics.
6 *
7 * Updates the fT matrix in place. Supports multiple bioenergetics models:
8 * 1 = Exponential function (Stewart et al. 1983)
9 * 2 = Warm-water species temperature dependence (Kitchell et al. 1977)
10 * 3 = Cool/cold-water species temperature dependence (Thornton and Lessem 1979)
11 * 4 = Constant (fT = 1.0)
12 *
13 * @param fT Temperature functions [nspp, nyrs], updated.
14 * @param nspp Number of species.
15 * @param nyrs Years, hindcast plus projection.
16 * @param Ceq Consumption equation per species.
17 * @param Cindex Environmental index driving each species.
18 * @param Qc Q coefficient in equations 1-2, a temperature in equation 3.
19 * @param Tcm Thermal max.
20 * @param Tco Thermal optimum.
21 * @param Tcl Thermal limit for Thornton/Lessem.
22 * @param CK1 Ascending limit for Thornton/Lessem.
23 * @param CK4 Descending limit for Thornton/Lessem.
24 * @param env_index Environmental predictors, e.g. bottom temperature [nyrs, n_indices].
25 */
26template <class Type>
27void calculate_temperature_function(matrix<Type> &fT,
28 int nspp,
29 int nyrs,
30 const vector<int> &Ceq,
31 const vector<int> &Cindex,
32 const vector<Type> &Qc,
33 const vector<Type> &Tcm,
34 const vector<Type> &Tco,
35 const vector<Type> &Tcl,
36 const vector<Type> &CK1,
37 const vector<Type> &CK4,
38 const matrix<Type> &env_index) {
39
40 // Kitchell and Thornton/Lessem intermediates, hoisted out to keep the AD tape small.
41 Type Yc = 0.0;
42 Type Zc = 0.0;
43 Type Vc = 0.0;
44 Type Xc = 0.0;
45 Type G2 = 0.0;
46 Type L2 = 0.0;
47 Type G1 = 0.0;
48 Type L1 = 0.0;
49 Type Ka = 0.0;
50 Type Kb = 0.0;
51
52 for(int sp = 0; sp < nspp; sp++) {
53
54 // Equations 1-3 read one column of env_index; equation 4 reads none. Cindex is
55 // 0-based (ceattle.cpp decrements the 1-based input), and an out-of-range column
56 // would read adjacent memory (the model is built without bounds checking), so with
57 // no column to read consumption takes equation 4's fT = 1.
58 bool has_env = (Cindex(sp) >= 0) && (Cindex(sp) < env_index.cols());
59 int eq = has_env ? Ceq(sp) : 4;
60
61 for(int yr = 0; yr < nyrs; yr++) {
62
63 switch(eq) {
64 case 1: // Exponential function from Stewart et al. 1983
65 fT(sp, yr) = exp(Qc(sp) * env_index(yr, Cindex(sp)));
66 break;
67
68 case 2: // Warm-water species temperature dependence, Kitchell et al. 1977
69 Yc = log(Qc(sp)) * (Tcm(sp) - Tco(sp) + 2.0);
70 Zc = log(Qc(sp)) * (Tcm(sp) - Tco(sp));
71 Vc = (Tcm(sp) - env_index(yr, Cindex(sp))) / (Tcm(sp) - Tco(sp));
72 Xc = pow(Zc, 2) * pow((1.0 + pow((1.0 + 40.0 / Yc), 0.5)), 2) / 400.0;
73 fT(sp, yr) = pow(Vc, Xc) * exp(Xc * (1.0 - Vc));
74 break;
75
76 case 3: // Cool/cold-water species temperature dependence, Thornton and Lessem 1979
77 G2 = (1.0 / (Tcl(sp) - Tcm(sp))) * log((0.98 * (1.0 - CK4(sp))) / (CK4(sp) * 0.02));
78 L2 = exp(G2 * (Tcl(sp) - env_index(yr, Cindex(sp))));
79 Kb = (CK4(sp) * L2) / (1.0 + CK4(sp) * (L2 - 1.0));
80
81 G1 = (1.0 / (Tco(sp) - Qc(sp))) * log((0.98 * (1.0 - CK1(sp))) / (CK1(sp) * 0.02));
82 L1 = exp(G1 * (env_index(yr, Cindex(sp)) - Qc(sp)));
83 Ka = (CK1(sp) * L1) / (1.0 + CK1(sp) * (L1 - 1.0));
84
85 fT(sp, yr) = Ka * Kb;
86 break;
87
88 case 4: // Constant
89 fT(sp, yr) = 1.0;
90 break;
91
92 default:
93 // Ceq outside 1-4, which data_check() refuses. fT = 1 rather than the zero from
94 // initialization, which would silently zero consumption and M2 with it.
95 fT(sp, yr) = 1.0;
96 break;
97 }
98 }
99 }
100}
101
102
103/**
104 * @brief Annual ration of a predator at age, in kg per predator per year.
105 *
106 * Updates `consumption_at_age` in place, from the bioenergetics equations (Ceq 1-3) or
107 * from input consumption (Ceq 4).
108 *
109 * @param consumption_at_age Individual consumption, kg/yr [nspp, max_sex, max_age, nyrs].
110 * @param nspp Number of species.
111 * @param nyrs Years, hindcast plus projection.
112 * @param nyrs_hind Years in the hindcast.
113 * @param nsex Sexes modelled per species: 1 = combined, 2 = both.
114 * @param nages Age bins per species.
115 * @param Ceq Consumption equation per species.
116 * @param CA Allometric mass function intercept (Cmax = CA * W^(1+CB)).
117 * @param CB Allometric mass function slope.
118 * @param fday Foraging days per year, per species.
119 * @param Pvalue Proportion of maximum consumption (scales Cmax).
120 * @param fT Temperature-dependence function [nspp, nyrs].
121 * @param ration_data Relative foraging rates (Ceq 1-3), input consumption (Ceq 4).
122 * @param weight_hat Weight-at-age [n_wt_indices, max_sex, max_age, nyrs].
123 */
124template <class Type>
125void calculate_ration(array<Type> &consumption_at_age,
126 int nspp,
127 int nyrs,
128 int nyrs_hind,
129 const vector<int> &nsex,
130 const vector<int> &nages,
131 const vector<int> &Ceq,
132 const vector<Type> &CA,
133 const vector<Type> &CB,
134 const vector<Type> &fday,
135 const vector<Type> &Pvalue,
136 matrix<Type> &fT, // "const" doesnt work for TMB matrices/arrays
137 array<Type> &ration_data,
138 array<Type> &weight_hat) {
139
140 for(int sp = 0; sp < nspp; sp++) {
141 for(int sex = 0; sex < nsex(sp); sex++) {
142 for(int age = 0; age < nages(sp); age++) {
143 for(int yr = 0; yr < nyrs; yr++) {
144
145 // Projection years reuse the last hindcast year's ration data.
146 int yr_ind = (yr < nyrs_hind) ? yr : (nyrs_hind - 1);
147
148 if(Ceq(sp) < 4){
149 int wt_idx_pop = 2 * sp;
150
151 // Cmax * fT * fday, grams/predator/yr; weight_hat is kg so x1000 gives grams.
152 consumption_at_age(sp, sex, age, yr) = CA(sp) * pow(weight_hat(wt_idx_pop, sex, age, yr) * Type(1000.0), 1.0 + CB(sp)) * fT(sp, yr) * fday(sp);
153
154 // Scale by Pvalue and the relative foraging rate, then grams to kg.
155 consumption_at_age(sp, sex, age, yr) = consumption_at_age(sp, sex, age, yr) * Pvalue(sp) * ration_data(sp, sex, age, yr_ind) / 1000.0;
156 }
157
158 // Ceq 4 bypasses bioenergetics: input consumption, scaled by Pvalue.
159 if(Ceq(sp) == 4){
160 consumption_at_age(sp, sex, age, yr) = Pvalue(sp) * ration_data(sp, sex, age, yr_ind);
161 }
162 }
163 }
164 }
165 }
166}
167
168
169#endif
void calculate_temperature_function(matrix< Type > &fT, int nspp, int nyrs, const vector< int > &Ceq, const vector< int > &Cindex, const vector< Type > &Qc, const vector< Type > &Tcm, const vector< Type > &Tco, const vector< Type > &Tcl, const vector< Type > &CK1, const vector< Type > &CK4, const matrix< Type > &env_index)
Temperature-dependent function of consumption (fT) for bioenergetics.
void calculate_ration(array< Type > &consumption_at_age, int nspp, int nyrs, int nyrs_hind, const vector< int > &nsex, const vector< int > &nages, const vector< int > &Ceq, const vector< Type > &CA, const vector< Type > &CB, const vector< Type > &fday, const vector< Type > &Pvalue, matrix< Type > &fT, array< Type > &ration_data, array< Type > &weight_hat)
Annual ration of a predator at age, in kg per predator per year.