3 #include "dimensions.hpp" 4 #include "distributions.hpp" 74 bool recruits_relation_on =
true;
84 bool recruits_variation_on =
true;
104 double recruits_deviation = 0;
109 double recruits_multiplier = 1;
130 double growth_rate_2;
131 double growth_assymptote;
132 double growth_stanza_inflection;
133 double growth_stanza_steepness;
136 double growth_cv_old;
166 double weight_length_b;
172 Array<double,Age> weight_age;
187 double maturity_length_steepness;
193 Array<double,Age> maturity_age;
215 Array<double,Age> mortality_shape = {
216 1.25, 1.25, 1.25, 1.25,
217 1.25, 1.25, 1.25, 1.25,
218 0.80, 0.80, 0.80, 0.80,
219 0.45, 0.45, 0.45, 0.45,
220 1.50, 1.50, 1.50, 1.50,
221 1.50, 1.50, 1.50, 1.50
253 double movement_length_steepness;
254 Array<double,Size> movement_size;
255 Array<double,Age> movement_age;
269 Array<double,SelectivityKnot> selectivity_lengths = {20,30,40,50,60,70,80};
280 Array<double,Method,Age> selectivity_age;
307 Array<double,Region,Method>
cpue;
308 Array<GeometricMean,Region,Method> cpue_base;
327 Array<GeometricMean,Region,Method> catchability_estim;
361 double biomass_spawners_msy;
369 double biomass_spawners_40;
383 Array<double,Quarter> m_pl_quarter = {0.97,0.87,0.97,1.19};
400 return sum(biomass_spawners)/sum(biomass_spawners_unfished);
418 movement_region = 1.0/regions.size();
419 movement_length_inflection = 0;
420 movement_length_steepness = 100;
453 exploit = exploit_rate;
458 exploitation_rate_specified = 0;
459 exploitation_rate_specified(WE,PS) = value;
460 exploitation_rate_specified(MA,PL) = value;
461 exploitation_rate_specified(EA,GN) = value;
468 double survival = geomean(escapement);
477 exploitation_rate_set(1-std::exp(-value));
485 return -std::log(1-exploitation_rate_get());
495 exploit = exploit_catch;
505 catches(WE,PS) = 0.354 * catches_ * dist.random();
506 catches(WE,PL) = 0.018 * catches_ * dist.random();
507 catches(WE,GN) = 0.117 * catches_ * dist.random();
508 catches(WE,OT) = 0.024 * catches_ * dist.random();
510 catches(MA,PS) = 0.000 * catches_ * dist.random();
511 catches(MA,PL) = 0.198 * catches_ * dist.random();
512 catches(MA,GN) = 0.000 * catches_ * dist.random();
513 catches(MA,OT) = 0.005 * catches_ * dist.random();
515 catches(EA,PS) = 0.058 * catches_ * dist.random();
516 catches(EA,PL) = 0.006 * catches_ * dist.random();
517 catches(EA,GN) = 0.141 * catches_ * dist.random();
518 catches(EA,OT) = 0.078 * catches_ * dist.random();
526 exploit = exploit_effort;
541 double growth_cv_slope = (growth_cv_old - growth_cv_0)/ages.size();
542 for(
auto age : ages){
544 double a = double(age.index()+0.5)/4.0;
546 double part1 = (1+std::exp(-growth_stanza_steepness*(a-growth_age_0-growth_stanza_inflection)))/
547 (1+std::exp(growth_stanza_inflection*growth_stanza_steepness));
548 double part2 = std::pow(part1,-(growth_rate_2-growth_rate_1)/growth_stanza_steepness);
549 double mean = growth_assymptote * (1-std::exp(-growth_rate_2*(a-growth_age_0))*part2);
551 double cv = growth_cv_0 + growth_cv_slope*a;
552 double sd = mean * cv;
554 length_age(age) = dist;
557 for(
auto size : sizes){
558 double lower = 2*size.index();
559 double upper = lower+2;
560 double prop = dist.cdf(upper)-dist.cdf(lower);
561 age_size(age,size) = prop;
565 for(
auto size : sizes) age_size(age,size) /= sum;
569 for(
auto size : sizes){
570 double length = 2*size.index()+1;
571 length_size(size) = length;
572 weight_size(size) = weight_length_a*std::pow(length,weight_length_b);
573 maturity_size(size) = 1.0/(1.0+std::pow(19,(maturity_length_inflection-length)/maturity_length_steepness));
574 movement_size(size) = 1.0/(1.0+std::pow(19,(movement_length_inflection-length)/movement_length_steepness));
578 for(
auto method : methods){
583 for(
auto size : sizes){
584 double length = length_size(size);
585 double selectivity = 0;
586 if(length<selectivity_lengths(0)) selectivity = 0;
588 for(uint knot=0;knot<selectivity_knots.size()-1;knot++){
589 if(selectivity_lengths(knot)<=length and length<selectivity_lengths(knot+1)){
590 selectivity = selectivity_values(method,knot) + (length-selectivity_lengths(knot)) * (
591 selectivity_values(method,knot+1)-selectivity_values(method,knot))/(
592 selectivity_lengths(knot+1)-selectivity_lengths(knot)
597 if(selectivity<0) selectivity = 0;
598 else if(selectivity>max) max = selectivity;
599 selectivity_size(method,size) = selectivity;
601 for(
auto size : sizes) selectivity_size(method,size) /= max;
609 for(
auto age : ages){
610 for(
auto size : sizes){
611 weight_age(age) += weight_size(size) * age_size(age,size);
612 maturity_age(age) += maturity_size(size) * age_size(age,size);
613 movement_age(age) += movement_size(size) * age_size(age,size);
614 for(
auto method : methods) selectivity_age(method,age) += selectivity_size(method,size) * age_size(age,size);
619 double movement_max = -1;
620 Array<double,Method> selectivity_max = -1;
621 for(
auto age : ages){
622 if(movement_age(age)>movement_max) movement_max = movement_age(age);
623 for(
auto method : methods){
624 if(selectivity_age(method,age)>selectivity_max(method)) selectivity_max(method) = selectivity_age(method,age);
627 for(
auto age : ages){
628 movement_age(age) /= movement_max;
629 for(
auto method : methods) selectivity_age(method,age) /= selectivity_max(method);
633 for(
auto age : ages){
634 mortality(age) = mortality_mean * mortality_shape(age);
635 survival(age) = std::exp(-0.25 * mortality(age));
639 for(
auto region_from : region_froms){
641 double off_diagonals = 0;
642 for(
auto region : regions){
643 if(region_from.index()!=region.index()) off_diagonals += movement_region(region_from,region);
647 throw std::runtime_error(
"Woahhh! There is a negative regional movement parameter");
649 else if(off_diagonals>1){
650 for(
auto region : regions){
651 if(region_from.index()!=region.index()) movement_region(region_from,region) = movement_region(region_from,region)/off_diagonals;
656 movement_region(region_from,Level<Region>(region_from)) = 1 - off_diagonals;
660 recruits_distrib =
Normal(0,recruits_sd);
682 uint year = IOSKJ::year(time);
683 uint quarter = IOSKJ::quarter(time);
686 for(
auto region : regions){
688 double biomass_spawners_ = 0;
689 double biomass_spawning_ = 0;
690 for(
auto age : ages){
691 double biomass = numbers(region,age) * weight_age(age)/1000;
693 double spawners = biomass * maturity_age(age);
694 biomass_spawners_ += spawners;
695 biomass_spawning_ += spawners * spawning(quarter);
697 biomass(region) = biomass_;
698 biomass_spawners(region) = biomass_spawners_;
699 biomass_spawning(region,quarter) = biomass_spawning_;
703 for(
auto region : regions){
707 if(recruits_relation_on){
710 double h = recruits_steepness;
711 double r0 = recruits_unfished(region);
712 double s0 = biomass_spawning_unfished(region,quarter);
713 double s = biomass_spawning(region,quarter);
714 recruits_determ(region) = 4*h*r0*s/((5*h-1)*s+s0*(1-h));
717 recruits_determ(region) = recruits_unfished(region);
722 if(recruits_variation_on and quarter==0){
723 recruits_deviation = recruits_autocorr*recruits_deviation +
724 std::sqrt(1-std::pow(recruits_autocorr,2))*recruits_distrib.random();
725 recruits_multiplier = std::exp(recruits_deviation - 0.5*std::pow(recruits_sd,2));
727 recruits(region) = recruits_determ(region) * recruits_multiplier;
730 numbers(region,ages.size()-1) += numbers(region,ages.size()-2);
733 for(uint age=ages.size()-2;age>0;age--){
734 numbers(region,age) = numbers(region,age-1);
738 numbers(region,0) = recruits(region);
742 for(
auto region : regions){
743 for(
auto age : ages){
744 numbers(region,age) *= survival(age);
749 for(
auto region_from : region_froms){
750 for(
auto region_to : regions){
751 for(
auto age : ages){
753 numbers(Level<Region>(region_from),age) *
754 movement_region(region_from,region_to) *
756 numbers(Level<Region>(region_from),age) -= movers;
757 numbers(region_to,age) += movers;
763 if(exploit!=exploit_none){
765 for(
auto region : regions){
766 for(
auto method : methods){
768 double biomass_vuln = 0;
769 for(
auto age : ages){
770 biomass_vuln += numbers(region,age) *
771 weight_age(age)/1000 *
772 selectivity_age(method,age);
774 biomass_vulnerable(region,method) = biomass_vuln;
778 if(year==1985) cpue_base(region,method).reset();
782 if(year>=1985 and year<=1989){
783 cpue_base(region,method).append(biomass_vuln);
785 cpue(region,method) = biomass_vuln/cpue_base(region,method);
791 if(exploit==exploit_catch){
793 double c = catches(region,method);
801 double e = effort(region,method);
804 if(year==2005) catchability_estim(region,method).reset();
805 if(q>0 and year>=2005 and year<=2014) catchability_estim(region,method).append(q);
807 catchability(region,method) = catchability_estim(region,method);
809 if(not std::isfinite(catchability(region,method))){
810 catchability(region,method) = 0;
815 else if(exploit==exploit_effort){
818 er = catchability(region,method) * effort(region,method);
821 er = exploitation_rate_specified(region,method);
823 exploitation_rate(region,method) = er;
824 catches_taken(region,method) = er * biomass_vuln;
828 for(
auto region : regions){
829 for(
auto age : ages){
830 double proportion_taken = 0;
831 for(
auto method : methods){
832 proportion_taken += exploitation_rate(region,method) * selectivity_age(method,age);
834 escapement(region,age) = (proportion_taken>1)?0:(1-proportion_taken);
842 for(
auto region : regions){
843 for(
auto age : ages){
844 numbers(region,age) *= escapement(region,age);
855 std::cout<<
"************equilibrium()**************\n";
859 bool recruits_variation_on_setting = recruits_variation_on;
860 recruits_variation_on =
false;
865 const uint steps_max = 1000;
866 Array<double,Region> biomass_prev = 1;
867 while(steps<steps_max){
870 for(uint quarter=0;quarter<4;quarter++) update(quarter);
875 if(biomass(sum)<0.01)
break;
878 for(
auto region : regions){
879 diffs += fabs(biomass(region)-biomass_prev(region))/biomass_prev(region);
881 diffs /= regions.size();
882 if(diffs<0.0001)
break;
883 biomass_prev = biomass;
886 std::cout<<steps<<
"\t"<<biomass(WE)<<
"\t"<<biomass(MA)<<
"\t"<<biomass(EA)<<
"\t"<<diffs<<std::endl;
890 if(not std::isfinite(biomass(WE)+biomass(MA)+biomass(EA))){
892 throw std::runtime_error(
"Biomass is not finite. Check inputs. Model has been written to `model/output`");
898 if(steps>steps_max)
throw std::runtime_error(
"No convergence in equilibrium() function");
900 recruits_variation_on = recruits_variation_on_setting;
903 void pristine_go(
void){
906 recruits_relation_on =
false;
907 exploit = exploit_none;
910 recruits_unfished = 1e10;
915 for(
auto region : regions){
917 double scalar = biomass_spawners_unfished(region)/biomass_spawners(region);
919 recruits_unfished(region) *= scalar;
920 for(
auto age : ages) numbers(region,age) *= scalar;
921 for(
auto quarter : quarters){
922 biomass_spawning_unfished(region,quarter) = biomass_spawning(region,quarter)*scalar;
928 recruits_relation_on =
true;
929 exploit = exploit_catch;
937 "exprate",
"f",
"yield",
"status",
"vuln",
938 "catch_we_ps",
"catch_ma_pl",
"catch_ea_gn",
939 "vuln_we_ps",
"vuln_ma_pl",
"vuln_ea_gn" 941 for(
double exprate=0;exprate<1;exprate+=step){
943 std::cout<<
"************yield_curve "<<exprate<<
"**************\n";
945 exploitation_rate_set(std::max(exprate,1e-6));
948 exprate,fishing_mortality_get(),sum(catches_taken),biomass_status(),sum(biomass_vulnerable),
949 catches_taken(WE,PS),catches_taken(MA,PL),catches_taken(EA,GN),
950 biomass_vulnerable(WE,PS),biomass_vulnerable(MA,PL),biomass_vulnerable(EA,GN)
963 Frame ypr({
"age",
"number",
"length",
"weight"});
964 for(
auto age : ages){
968 for(
auto region : regions){
969 double n = numbers(region,age);
977 ypr.append({double(age.index()),number,length,weight});
987 auto result = boost::math::tools::brent_find_minima([&](
double exprate){
989 exploitation_rate_set(exprate);
991 return -sum(catches_taken);
993 e_msy = result.first;
994 f_msy = -std::log(1-e_msy);
995 msy = -result.second;
998 exploitation_rate_set(e_msy);
1000 biomass_spawners_msy = sum(biomass_spawners);
1014 msy_trials = calc.msy_trials;
1015 biomass_spawners_msy = calc.biomass_spawners_msy;
1024 auto result = boost::math::tools::brent_find_minima([&](
double exprate){
1026 exploitation_rate_set(exprate);
1028 return std::fabs(biomass_status()-status);
1030 e_40 = result.first;
1031 f_40 = -std::log(1-e_40);
1033 exploitation_rate_set(e_40);
1035 biomass_spawners_40 = sum(biomass_spawners);
1049 biomass_spawners_40 = calc.biomass_spawners_40;
1056 numbers.write(
"model/output/numbers.tsv");
1057 spawning.write(
"model/output/spawning.tsv");
1058 biomass_spawning_unfished.write(
"model/output/biomass_spawning_unfished.tsv");
1060 length_size.write(
"model/output/length_size.tsv");
1061 length_age.write(
"model/output/length_age.tsv",{
"mean",
"sd"},[](std::ostream& stream,
const Normal& dist){
1062 stream<<dist.mean<<
"\t"<<dist.sd;
1064 age_size.write(
"model/output/age_size.tsv");
1066 weight_size.write(
"model/output/weight_size.tsv");
1067 weight_age.write(
"model/output/weight_age.tsv");
1069 maturity_size.write(
"model/output/maturity_size.tsv");
1070 maturity_age.write(
"model/output/maturity_age.tsv");
1072 mortality.write(
"model/output/mortality.tsv");
1073 survival.write(
"model/output/survival.tsv");
1075 movement_region.write(
"model/output/movement_region.tsv");
1076 movement_size.write(
"model/output/movement_size.tsv");
1077 movement_age.write(
"model/output/movement_age.tsv");
1079 selectivity_size.write(
"model/output/selectivity_size.tsv");
1080 selectivity_age.write(
"model/output/selectivity_age.tsv");
1082 catchability.write(
"model/output/catchability.tsv");
Array< double, Region > biomass_spawners
Definition: model.hpp:29
void initialise(void)
Definition: model.hpp:539
double mortality_mean
Definition: model.hpp:208
double growth_rate_1
Definition: model.hpp:129
Array< double, Region > biomass
Definition: model.hpp:24
Array< double, Region, Method > exploitation_rate_specified
Definition: model.hpp:333
void movement_uniform(void)
Definition: model.hpp:417
Array< double, RegionFrom, Region > movement_region
Definition: model.hpp:247
void msy_go(void)
Definition: model.hpp:985
Array< double, Region > biomass_spawners_unfished
Definition: model.hpp:37
Array< double, Region, Method > catchability
Definition: model.hpp:326
Array< double, Size > length_size
Definition: model.hpp:141
double biomass_status(void) const
Definition: model.hpp:399
Array< double, Method, SelectivityKnot > selectivity_values
Definition: model.hpp:274
double recruits_sd
Definition: model.hpp:89
void catches_set(double catches_, double error=0.2)
Definition: model.hpp:493
Array< double, Region, Method > catches_taken
Definition: model.hpp:339
Array< double, Age > mortality
Definition: model.hpp:227
void equilibrium(void)
Definition: model.hpp:853
Array< Normal, Age > length_age
Definition: model.hpp:146
Array< double, Method, Size > selectivity_size
Definition: model.hpp:279
Definition: distributions.hpp:4
void fishing_mortality_set(double value)
Definition: model.hpp:476
double weight_length_a
Definition: model.hpp:165
Definition: distributions.hpp:188
Frame yield_per_recruit(void)
Definition: model.hpp:961
Array< double, Region > recruits_unfished
Definition: model.hpp:63
double recruits_autocorr
Definition: model.hpp:99
Array< double, Age > survival
Definition: model.hpp:232
double maturity_length_inflection
Definition: model.hpp:186
double recruits_steepness
Definition: model.hpp:68
void exploitation_rate_set(double value)
Definition: model.hpp:451
Array< double, Size > weight_size
Definition: model.hpp:171
Array< double, Age, Size > age_size
Definition: model.hpp:151
double fishing_mortality_get(void) const
Definition: model.hpp:484
double movement_length_inflection
Definition: model.hpp:252
Frame yield_curve(double step=0.01)
Definition: model.hpp:935
Array< double, Size > maturity_size
Definition: model.hpp:192
double msy
Definition: model.hpp:358
Array< double, Region, Quarter > biomass_spawning_unfished
Definition: model.hpp:58
Array< double, Region, Method > exploitation_rate
Definition: model.hpp:344
void effort_set(double effort_)
Definition: model.hpp:524
void write(void)
Definition: model.hpp:1055
Array< double, Region > recruits_determ
Definition: model.hpp:79
Array< double, Region, Method > effort
Definition: model.hpp:321
double e_40
Definition: model.hpp:367
void spawning_uniform(void)
Definition: model.hpp:429
Array< double, Region, Method > biomass_vulnerable
Definition: model.hpp:301
void msy_find(void)
Definition: model.hpp:1006
void update(uint time)
Definition: model.hpp:681
Array< double, Region, Age > escapement
Definition: model.hpp:349
void b40_find(void)
Definition: model.hpp:1041
Array< double, Region, Method > catches
Definition: model.hpp:313
Normal recruits_distrib
Definition: model.hpp:94
void status_go(const double &status)
Definition: model.hpp:1022
Array< double, Region, Age > numbers
Definition: model.hpp:19
Array< double, Region > recruits
Definition: model.hpp:114
Array< double, Region, Quarter > biomass_spawning
Definition: model.hpp:52
Array< double, Region, Method > cpue
Definition: model.hpp:307
Definition: distributions.hpp:262
Array< double, Quarter > spawning
Definition: model.hpp:47
double exploitation_rate_get(void) const
Definition: model.hpp:467