27 #include "IpIpoptApplication.hpp" 28 #include "IpSolveStatistics.hpp" 101 for(uint i=0;i<
regIds2.size();i++){
154 double stvalue = sl+sa;
155 double q1 = 1/ ( 1+pow(dl/da,1/psi)*(pl/pWo) );
158 q1*pow(da,(psi-1)/psi) + p1*pow(dl,(psi-1)/psi)
162 double pc = (da/dc)*pWo
164 double pw = (dl*pl+da*pWo)/(dl+da);
190 double t1 = 1/ ( 1+(pow(sl/sa,1/eta))*(pl/pWo) );
193 t1*pow(sa,(eta-1)/eta) + r1*pow(sl,(eta-1)/eta)
197 double pc = (sa/sc)*pWo+(sl/sc)*pl;
198 double pw = (sl*pl+sa*pWo)/(sl+sa);
213 for(uint r1=0;r1<
l2r.size();r1++){
214 for(uint r2=0;r2<
l2r[r1].size();r2++){
216 for(uint r2To=0;r2To<
l2r[r1].size();r2To++){
218 if(
l2r[r1][r2] ==
l2r[r1][r2To]){
224 for(uint r2To=0;r2To<
l2r[r1].size();r2To++){
225 if(
l2r[r1][r2] ==
l2r[r1][r2To]){
236 static double cumOverHarvesting = 0.0;
247 for(uint i=0;i<
regIds2.size();i++){
255 double pol_mktDirInt_d =
gpd(
"pol_mktDirInt_d",r2,
secProducts[sp]);
256 double pol_mktDirInt_d_1 =
gpd(
"pol_mktDirInt_d",r2,
secProducts[sp],previousYear);
260 double q1_polCorr = min(1.0, (q1-0.5)*pol_mktStr_d+0.5);
264 double k = (1+g1)*k_1;
265 double aa = (sigma/(sigma+1))*pc_1*pow(dc_1,-1/sigma) * pol_mktDirInt_d_1/pol_mktDirInt_d ;
266 double gg = dc_1*pow(pc_1*pol_mktDirInt_d_1,-sigma);
299 double pol_mktDirInt_s =
gpd(
"pol_mktDirInt_s",r2,
priProducts[pp]);
300 double pol_mktDirInt_s_1 =
gpd(
"pol_mktDirInt_s",r2,
priProducts[pp],previousYear);
306 double carbonPrice_1 =
gpd(
"carbonPrice",r2,
"",previousYear);
307 double omega =
gpd(
"co2content_products", r2,
priProducts[pp])/1000;
308 double Pct_1 = carbonPrice_1*intRate;
313 double t1_polCorr = min(1.0, (t1-0.5)*pol_mktStr_s+0.5);
316 double gamma = in>in_1 ? gamma_incr: gamma_decr;
317 double gamma_d = in_d>in_d_1 ? gamma_d_incr: gamma_d_decr;
320 double in_ratio = in/in_1;
321 double in_d_ratio = useDeathTimber ? max(min_in_d,in_d) / max(min_in_d, in_d_1 ) : 1.0 ;
330 if (in_d_ratio < 0.01){
333 if (in_d_ratio > 100){
338 double bb = (sigma/(sigma+1.0))*pc_1*pow(sc_1,-1.0/sigma)*pow(1/in_ratio,gamma/sigma)*pow(1.0,1.0/sigma) * pol_mktDirInt_s_1/pol_mktDirInt_s ;
345 double ff = sc_1*pow((pc_1 - omega * Pct_1)*pol_mktDirInt_s_1,-sigma)*pow(in_ratio,gamma)*pow(in_d_ratio,gamma_d);
364 SmartPtr<IpoptApplication> application =
new IpoptApplication();
366 application->Options()->SetStringValue(
"linear_solver", linearSolver);
369 application->Options()->SetNumericValue(
"obj_scaling_factor", -1);
370 application->Options()->SetNumericValue(
"max_cpu_time", 1800);
371 application->Options()->SetStringValue(
"check_derivatives_for_naninf",
"yes");
385 ApplicationReturnStatus status;
386 status = application->Initialize();
387 if (status != Solve_Succeeded) {
388 printf(
"\n\n*** Error during initialization!\n");
389 msgOut(
MSG_INFO,
"Error during initialization! Do you have the solver compiled for the specified linear solver?");
393 msgOut(
MSG_INFO,
"Running optimisation problem for this year (it may take a few minutes for large models)..");
394 status = application->OptimizeTNLP(
MTHREAD->
OPT);
406 if (status == Solve_Succeeded) {
407 Index iter_count = application->Statistics()->IterationCount();
408 Number final_obj = application->Statistics()->FinalObjective();
409 printf(
"\n*** The problem solved year %d in %d iterations!\n", thisYear, iter_count);
410 printf(
"\n*** The final value of the objective function is %e.\n", final_obj);
411 msgOut(
MSG_INFO,
"The problem solved successfully year "+
i2s(thisYear)+
" in "+
i2s(iter_count)+
" iterations.");
412 int icount = iter_count;
413 double obj = final_obj;
418 cout <<
"***ERROR: MODEL DIDN'T SOLVE FOR THIS YEAR ("<<thisYear<<
")"<< endl;
428 for(uint r2= 0; r2<
regIds2.size();r2++){
465 double pw = dt?(dl*pl+da*pworld)/dt:0.0;
474 double st_fromFor = st *
gpd(
"supply_fromForestShare",regId,
priProducts[p]);
475 double pw = st?(sl*pl+sa*pworld)/st:0.0;
484 int nPriPrCombs = priPrCombs.size();
486 for (uint i=0;i<priPrCombs.size();i++){
487 double stMkMod = 0.0;
490 for (uint p=0;p<priPrCombs[i].size();p++){
501 string pProductsInvolved =
"";
502 for (uint p=0;p<priPrCombs[i].size();p++){
503 pProductsInvolved += (
priProducts[priPrCombs[i][p]]+
"; ");
505 double inV_over_hV_ratio = stMkMod ? sumIn/stMkMod : 0.0;
506 cumOverHarvesting += (stMkMod-sumIn);
507 msgOut(
MSG_DEBUG,
"Overharvesting has happened. Year: "+
i2s(thisYear)+
"Region: "+
i2s(regId)+
"Involved products: "+pProductsInvolved+
". sumIn: "+
d2s(sumIn)+
" stMkMod:" +
d2s(stMkMod) +
" cumOverHarvesting: "+
d2s(cumOverHarvesting));
508 for (uint p=0;p<priPrCombs[i].size();p++){
509 double st_fromFor_orig =
gpd(
"st_fromFor",regId,
priProducts[priPrCombs[i][p]]);
510 spd(st_fromFor_orig*inV_over_hV_ratio,
"st_fromFor",regId,
priProducts[priPrCombs[i][p]]);
522 vector <double> in_deathTimber(
priProducts.size(),0.);
523 vector <double> in_aliveForest (
priProducts.size(),0.);
540 if (cumOverHarvesting>0.0){
541 msgOut(
MSG_DEBUG,
"Overharvesting is present. Year: "+
i2s(thisYear)+
" cumOverHarvesting: "+
d2s(cumOverHarvesting));
567 for(uint i=0;i<
regIds2.size();i++){
573 double shareMortalityUsableTimber = 0.0;
575 for (uint p=0;p<
regPx.size();p++){
578 double pxId = px->
getID();
583 for(uint j=0;j<
fTypes.size();j++){
586 vector <double> hV_byDiam;
587 vector <double> productivity_byDc;
588 vector < vector <double> > hV_byDiamAndPrd;
589 vector <double> hArea_byDc;
590 vector <double> newVol_byDiam;
591 vector <double> vMort_byDc;
592 vector <double> vMortAdd_byDc ;
593 vector <double> areasMovingUp(
dClasses.size(), 0.0);
594 double areaFirstProdClass;
608 int tp_u0 = px->
tp.at(j).at(0);
614 double availableArea = px->
area_l.at(j).at(0);
616 double vHa = px->
vHa.at(j).at(1);
619 areaFirstProdClass = pastRegArea;
621 areaFirstProdClass = min(availableArea, pastRegArea);
623 px->
vReg.push_back(areaFirstProdClass*vHa/1000000.0);
628 if (areaFirstProdClass < 0.0){
631 if ( (availableArea-pastRegArea) < -0.00000001 ){
640 double regRegVolumes =
gfd(
"vReg",r2,ft,
"");
641 double newVReg = regionArea ? regRegVolumes*pxArea/regionArea : 0.0;
642 px->
vReg.push_back(newVReg);
645 areaFirstProdClass = (1.0 / ((double) tp_u0) ) * px->
initialDc0Area.at(j);
655 if (areaFirstProdClass<0.0){
658 if (areaFirstProdClass > px->
area_l.at(j).at(0)){
671 shareMortalityUsableTimber =
gfd(
"shareMortalityUsableTimber",r2,ft,
"");
673 shareMortalityUsableTimber = 0.0;
676 for (uint u=0; u<
dClasses.size(); u++){
682 double pastYearVol = px->
vol_l.at(j).at(u);
683 vector <double> hV_byPrd;
684 vector <double> hr_byPrd;
695 hr_byPrd.push_back( hr_pr);
704 double hr_pr = origHr ? hr_byPrd[pp] * min(1.0,1.0/origHr) : 0.0;
705 hV_byPrd.push_back( hr_pr*pastYearVol*px->
avalCoef.at(j));
708 double hV = hr*pastYearVol*px->
avalCoef.at(j);
711 hV_byDiam.push_back(hV);
712 hV_byDiamAndPrd.push_back(hV_byPrd);
726 double tp = px->
tp.at(j).at(u);
727 double mort = px->
mort.at(j).at(u);
728 double addMort = px->
addMort.at(j).at(u);
729 double vReg = px->
vReg.at(j);
730 double beta = px->
beta.at(j).at(u);
732 double vHa = px->
vHa.at(j).at(u);
733 double finalHarvestFlag =
gfd(
"finalHarvestFlag",regId,ft,dc);
735 double vMort = mort*pastYearVol;
736 double vMortAdd = addMort*pastYearVol;
738 vMort_byDc.push_back(vMort);
739 vMortAdd_byDc.push_back(vMortAdd);
742 iisskey key(thisYear,r2,ft,dc);
750 vol = max(0.0,(1-1/tp-mort-addMort))*pastYearVol+vReg;
753 if ((1-1/tp-mort-addMort)<0.0){
754 msgOut(
MSG_DEBUG,
"The sum of leaving trres and mortality would have lead to nevative volume if we didn't put a max. 1/tp: "+
d2s(1/tp)+
", mort: "+
d2s(mort)+
", total coeff: "+
d2s((1-1/tp-mort))+
" ");
759 double inc = (u==
dClasses.size()-1)?0:1./tp;
760 double tp_1 = px->
tp.at(j).at(u-1);
761 double pastYearVol_1 = px->
vol_l.at(j).at(u-1);
763 vol = max(0.0,(1-inc-mort-addMort)*pastYearVol-hV+(1/tp_1)*beta*pastYearVol_1);
765 if ((1-inc-mort)*pastYearVol-hV+(1/tp_1)*beta*pastYearVol_1 < 0){
766 double realVolumes = (1-inc-mort-addMort)*pastYearVol-hV+(1/tp_1)*beta*pastYearVol_1;
767 msgOut(
MSG_DEBUG,
"Negative real volumes ("+
d2s(realVolumes)+
"), possibly because of little bit larger bounds in the market module to avoid zeros. Volumes in the resource module set back to zero, so it should be ok.");
772 double inc = (u==
dClasses.size()-1)?0:1.0/tp;
773 double volumesMovingUp = inc*pastYearVol;
774 double pastArea = px->
area_l.at(j).at(u);
776 areasMovingUp.at(u) = inc*pastArea;
779 hArea_byDc.push_back(finalHarvestFlag*1000000*hV/vHa);
781 double finalHarvestedVolumes = finalHarvestFlag* hV;
782 double finalHarvestedRate = pastYearVol?finalHarvestedVolumes/pastYearVol:0.0;
784 if (finalHarvestedRate > 1.0){
788 hArea_byDc.push_back(finalHarvestedRate*pastArea);
790 px->
area.at(j).at(u) = max(0.0, px->
area_l.at(j).at(u) - areasMovingUp.at(u) + areasMovingUp.at(u-1) - hArea_byDc.at(u));
792 if ((px->
area_l.at(j).at(u) - areasMovingUp.at(u) + areasMovingUp.at(u-1) - hArea_byDc.at(u))< 0.0){
793 msgOut(
MSG_DEBUG,
"If not for a max, we would have had a negative area ("+
d2s(px->
area_l.at(j).at(u) - areasMovingUp.at(u) + areasMovingUp.at(u-1) - hArea_byDc.at(u))+
" ha).");
797 areasMovingUp.at(u) = areaFirstProdClass;
798 hArea_byDc.push_back(0.);
799 px->
area.at(j).at(u) = px->
area_l.at(j).at(u) - areasMovingUp.at(u) - hArea_byDc.at(u);
804 newVol_byDiam.push_back(vol);
806 if(px->
area.at(j).at(u)< 0.0 || areasMovingUp.at(u) < 0.0 || hArea_byDc.at(u) < 0.0 ){
819 double productivity = hArea_byDc.at(u) ? (1000000.0 * hV_byDiam.at(u))/(hArea_byDc.at(u)*age) : 0.0;
820 productivity_byDc.push_back(productivity);
822 px->
hVol.push_back(hV_byDiam);
824 px->
hArea.push_back(hArea_byDc);
825 px->
vol.push_back(newVol_byDiam);
826 px->
vMort.push_back(vMort_byDc);
827 px->
vMortAdd.push_back(vMortAdd_byDc);
832 for (uint u=1; u<
dClasses.size(); u++){
833 double volMort = vMort_byDc[u];
834 double harvVol = hV_byDiam[u];
835 double vol_new = newVol_byDiam[u];
836 double vol_lagged = px->
vol_l.at(j).at(u);
837 double gain = vol_new - (vol_lagged-harvVol-volMort);
838 if (volMort > vol_lagged){
853 for (uint p=0;p<
regPx.size();p++){
854 for(uint j=0;j<
fTypes.size();j++){
855 for (uint u=0; u<
dClasses.size(); u++){
858 sumHv +=
regPx[p]->hVol_byPrd[j][u][pp];
863 if(abs(sumSt-sumHv) > 0.000001){
877 map<string,double> hAreaByFTypeGroup =
vectorToMap(allFTypes,0.0);
882 for(uint i=0;i<
regIds2.size();i++){
897 double carbonPrice_NOW =
gpd(
"carbonPrice",r2,
"",thisYear+1);
898 vector<double> futureCarbonPrices;
899 if(flagHartman!=
"NONE"){
900 for (
int y=0; y<1000; y++) {
901 futureCarbonPrices.push_back(
gpd(
"carbonPrice",r2,
"",thisYear + y));
905 vector<double> polBal_fiSub (
fTypes.size(),0.0);
908 double fArea_reg = REG->
getArea();
909 double fArea_diff = 0.0;
910 double fArea_reldiff = 0.0;
912 fArea_reldiff =
gfd(
"forestChangeAreaIncrementsRel",r2,
"",
"",
DATA_NOW);
913 fArea_diff = fArea_reg * fArea_reldiff;
915 fArea_diff =
gfd(
"forestChangeAreaIncrementsHa",r2,
"",
"",
DATA_NOW);
916 fArea_reldiff = fArea_diff / fArea_reg;
919 double regHArea = 0.0;
944 vector<vector<double>> futureCarbonRef;
945 vector<vector<double>> futureExtraBiomass_ratio;
947 if(flagHartman!=
"NONE"){
948 for(uint j=0;j<
fTypes.size();j++){
950 vector<double> futureCarbonRef_ft;
951 vector<double>futureExtraBiomass_ratio_ft;
952 for (
int y=0; y<1000; y++) {
953 double carbonRef =
gfd(
"carbonRef",r2,ft,
"", thisYear + y);
954 futureCarbonRef_ft.push_back(carbonRef);
955 double extraBiomass_ratio =
gfd(
"extraBiomass_ratio",regId,ft,
"",
DATA_NOW);
956 futureExtraBiomass_ratio_ft.push_back(extraBiomass_ratio);
958 futureCarbonRef.push_back(futureCarbonRef_ft);
959 futureExtraBiomass_ratio.push_back(futureExtraBiomass_ratio_ft);
964 for (uint p=0;p<
regPx.size();p++){
975 double totalHarvestedAreaOrig =
vSum(px->
hArea);
976 double totalHarvestedArea = 0.0;
977 vector<double> thisYearRegAreas(
fTypes.size(),0.0);
978 vector<double> expectedReturns(
fTypes.size(),0.0);
979 vector<double> expectedReturnsCarbon(
fTypes.size(),0.0);
980 vector<int> rotation_dc(
fTypes.size(),0.0);
981 vector< vector<double> > deltaAreas(
fTypes.size()+1, vector<double>(
fTypes.size()+1,0));
986 double fArea_diff_px = fArea_px * fArea_diff/ fArea_reg;
988 double fArea_incr = max(0.0,fArea_diff_px);
989 double fArea_incr_rel = totalHarvestedAreaOrig?fArea_incr/totalHarvestedAreaOrig:0.0;
990 double fArea_decr = - min(0.0,fArea_diff_px);
991 double fArea_decr_rel = totalHarvestedAreaOrig?min(1.0,fArea_decr/totalHarvestedAreaOrig):0.0;
992 regHArea += totalHarvestedAreaOrig;
993 totalHarvestedArea = totalHarvestedAreaOrig *(1-fArea_decr_rel);
997 for(uint j=0;j<
fTypes.size();j++){
1000 double hAreaThisFt=
vSum(px->
hArea.at(j))*(1-fArea_decr_rel);
1019 for(uint j=0;j<
fTypes.size();j++){
1023 double co2content_inventory =
gfd(
"co2content_inventory",r2,ft,
"",
DATA_NOW)/1000;
1027 double expReturns = std::numeric_limits<double>::lowest();
1028 double expReturns_carbon = std::numeric_limits<double>::lowest();
1029 double expReturns_timber = std::numeric_limits<double>::lowest();
1031 for (uint u=0; u<
dClasses.size(); u++){
1033 double vHa = px->
vHa_exp.at(j).at(u);
1034 double finalHarvestFlag =
gfd(
"finalHarvestFlag",regId,ft,dc);
1035 double cumTp_u = px->
cumTp_exp.at(j).at(u);
1043 double raw_amount = finalHarvestFlag*pw_exp*vHa*
app(
priProducts[pp],ft,dc);
1045 double anualised_amount = anualised_amount_timber;
1049 double raw_amount_carbon = 0;
1050 if (flagHartman ==
"EXO") {
1051 double carbonPrice_y = carbonPrice_NOW;
1052 for (
int y=0; y<cumTp_u; y++) {
1054 double carbonRef = futureCarbonRef[j][y];
1055 double expectedVHa_y =
getVHaByYear(px, j, y, futureExtraBiomass_ratio[j][y], regId);
1056 double carbonPayment_y = carbonPrice_y*ir*(co2content_inventory*expectedVHa_y - carbonRef);
1057 raw_amount_carbon += carbonPayment_y*pow(1+ir,cumTp_u - y);
1061 raw_amount_carbon += pickling * carbonPrice_y * finalHarvestFlag * vHa *
app(
priProducts[pp],ft,dc);
1065 anualised_amount += anualised_amount_carbon;
1071 if (anualised_amount>expReturns) {
1072 expReturns=anualised_amount;
1074 expReturns_carbon = anualised_amount_carbon;
1075 expReturns_timber = anualised_amount_timber;
1081 if (flagHartman==
"NONE" || flagHartman==
"EXO") {
1085 px->
optDc.push_back(optDc);
1093 double origExpReturns = expReturns;
1094 expReturns = origExpReturns * (1.0 - ra*cumMort);
1098 if (flagHartman==
"NONE" || flagHartman==
"EXO") {
1102 expectedReturns.at(j) = expReturns;
1103 rotation_dc.at(j) = optDc;
1114 if (flagHartman ==
"ENDO") {
1116 int ft_opt_index =
getMaxPos(expectedReturns);
1117 string ft_opt =
fTypes[ft_opt_index];
1118 int dc_opt_index = rotation_dc[ft_opt_index];
1119 string dc_opt =
dClasses[dc_opt_index];
1120 double cumTP_opt = px->
cumTp_exp.at(ft_opt_index).at(dc_opt_index);
1121 double co2content_inventory_opt =
gfd(
"co2content_inventory",r2,ft_opt,
"",
DATA_NOW)/1000;
1124 vector <double> FutureCarbonContent_opt;
1125 for (
int y=0; y<=cumTP_opt; y++) {
1126 double expectedVHa_opt_y =
getVHaByYear(px, ft_opt_index, y, futureExtraBiomass_ratio[ft_opt_index][y], regId);
1127 FutureCarbonContent_opt.push_back(co2content_inventory_opt*expectedVHa_opt_y);
1130 while (FutureCarbonContent_opt.size()<=2000){
1131 FutureCarbonContent_opt.insert(std::end(FutureCarbonContent_opt), std::begin(FutureCarbonContent_opt), std::end(FutureCarbonContent_opt));
1137 for(uint j=0;j<
fTypes.size();j++){
1139 double co2content_inventory =
gfd(
"co2content_inventory",r2,ft,
"",
DATA_NOW)/1000;
1141 double expReturns_hartman = -10000000000;
1142 double expReturns_timber_hartman;
1143 double expReturns_carbon_hartman;
1144 int optDc_hartman = -1;
1145 for (uint u=1; u<
dClasses.size(); u++){
1147 double cumTp_u = px->
cumTp_exp.at(j).at(u);
1150 double raw_amount_carbon=0;
1151 double carbonPrice_y = carbonPrice_NOW;
1152 for (
int y=0; y<=cumTp_u; y++) {
1153 double expectedVHa_y =
getVHaByYear(px, j, y, futureExtraBiomass_ratio[j][y], regId);
1154 double carbonPayment_y;
1155 carbonPayment_y = carbonPrice_y*ir*(co2content_inventory*expectedVHa_y - FutureCarbonContent_opt[y]);
1167 raw_amount_carbon += carbonPayment_y*pow(1+ir,cumTp_u - y);
1171 double vHa = px->
vHa_exp.at(j).at(u);
1172 double finalHarvestFlag =
gfd(
"finalHarvestFlag",regId,ft,dc);
1180 double raw_amount = finalHarvestFlag*pw_exp*vHa*
app(
priProducts[pp],ft,dc);
1184 raw_amount_carbon += pickling * carbonPrice_y * finalHarvestFlag * vHa *
app(
priProducts[pp],ft,dc);
1189 double anualised_amount = anualised_amount_timber + anualised_amount_carbon;
1192 if (anualised_amount>=expReturns_hartman) {
1193 expReturns_hartman=anualised_amount;
1194 expReturns_carbon_hartman = anualised_amount_carbon;
1195 expReturns_timber_hartman = anualised_amount_timber;
1205 px->
optDc.push_back(optDc_hartman);
1210 double cumMort = 1-px->
cumAlive_exp.at(j).at(optDc_hartman);
1212 double origExpReturns_hartman = expReturns_hartman;
1213 expReturns_hartman = origExpReturns_hartman * (1.0 - ra*cumMort);
1220 expectedReturns.at(j) = expReturns_hartman;
1221 rotation_dc.at(j) = optDc_hartman;
1230 for(uint j=0;j<
fTypes.size();j++){
1234 double harvestedAreaForThisFT =
vSum(px->
hArea.at(j))*(1-fArea_decr_rel);
1235 deltaAreas[j][
fTypes.size()] +=
vSum(px->
hArea.at(j))*(fArea_decr_rel);
1236 vector<double> corrExpectedReturns(
fTypes.size(),0.0);
1237 vector<double> polBal_fiSub_unitvalue(
fTypes.size(),0.0);
1241 for(uint j2=0;j2<
fTypes.size();j2++){
1243 double invTransCost = (
gfd(
"invTransCost",regId,ft,ft2,
DATA_NOW) *
gfd(
"pol_fiSub",regId,ft,ft2,
DATA_NOW) ) ;
1244 polBal_fiSub_unitvalue[j2] =
gfd(
"invTransCost",regId,ft,ft2,
DATA_NOW) * (
gfd(
"pol_fiSub",regId,ft,ft2,
DATA_NOW) - 1) ;
1245 corrExpectedReturns[j2] = (expectedReturns[j2]/
ir)-invTransCost;
1269 int optFtChosen =
getMaxPos(corrExpectedReturns);
1273 thisYearRegAreas[
getMaxPos(corrExpectedReturns)] += harvestedAreaForThisFT*mr;
1274 thisYearRegAreas[
getMaxPos(expectedReturns)] += fArea_incr*mr/((double)
fTypes.size());
1276 deltaAreas[j][
getMaxPos(corrExpectedReturns)] += harvestedAreaForThisFT*mr;
1279 polBal_fiSub[
getMaxPos(corrExpectedReturns)] += harvestedAreaForThisFT*mr*polBal_fiSub_unitvalue[
getMaxPos(corrExpectedReturns)];
1287 double hAreaThisFtGroup =
findMap(hAreaByFTypeGroup,parentFt);
1288 double hRatio = 1.0;
1289 if(hAreaThisFtGroup>0){
1291 hRatio = harvestedAreaForThisFT/hAreaThisFtGroup;
1294 hRatio = 1.0/nFtChilds;
1296 thisYearRegAreas[j] += totalHarvestedArea*(1-mr)*freq*hRatio;
1297 thisYearRegAreas[j] += fArea_incr*(1-mr)*freq*hRatio;
1300 for(uint j2=0;j2<
fTypes.size();j2++){
1301 deltaAreas[j2][j] +=
vSum(px->
hArea.at(j2))*(1-fArea_decr_rel)*(1-mr)*freq*hRatio;
1303 deltaAreas[
fTypes.size()][j] += fArea_incr*(1-mr)*freq*hRatio;
1313 if(mortRatePath > 0){
1317 vector <double> siblingAreas;
1318 for(uint j2=0;j2<siblings.size();j2++){
1319 if(siblings[j2]==ft){
1320 siblingAreas.push_back(0.0);
1325 siblingAreas.push_back(thisSiblingArea);
1328 double areaAllSiblings =
vSum(siblingAreas);
1329 thisYearRegAreas[j] += harvestedAreaForThisFT*(1-mr)*(1-mortRatePath);
1330 deltaAreas[j][j] += harvestedAreaForThisFT*(1-mr)*(1-mortRatePath);
1332 if(areaAllSiblings>0.0){
1333 for(uint j2=0;j2<siblings.size();j2++){
1341 thisYearRegAreas[
getPos(siblings[j2],
fTypes)] += harvestedAreaForThisFT*(1.0-mr)*(mortRatePath)*(siblingAreas[j2]/areaAllSiblings);
1342 deltaAreas[j][
getPos(siblings[j2],
fTypes)] += harvestedAreaForThisFT*(1.0-mr)*(mortRatePath)*(siblingAreas[j2]/areaAllSiblings);
1344 }
else if (siblings.size()>1) {
1345 for(uint j2=0;j2<siblings.size();j2++){
1346 if (siblings[j2] != ft){
1347 thisYearRegAreas[
getPos(siblings[j2],
fTypes)] += harvestedAreaForThisFT*(1.0-mr)*(mortRatePath)* 1.0 / (( (float) siblings.size())-1.0);
1348 deltaAreas[j][
getPos(siblings[j2],
fTypes)] += harvestedAreaForThisFT*(1.0-mr)*(mortRatePath)* 1.0 / (( (float) siblings.size())-1.0);
1353 thisYearRegAreas[j] += harvestedAreaForThisFT*(1.0-mr);
1354 deltaAreas[j][j] += harvestedAreaForThisFT*(1.0-mr);
1359 thisYearRegAreas[j] += newAreaThisFt;
1360 deltaAreas[
fTypes.size()][j] += newAreaThisFt;
1362 if(! (thisYearRegAreas[j] >= 0.0) ){
1363 msgOut(
MSG_ERROR,
"thisYearRegAreas[j] is not non negative (j: "+
i2s(j)+
", thisYearRegAreas[j]: "+
i2s( thisYearRegAreas[j])+
").");
1371 for(uint j=0;j<
fTypes.size();j++){
1372 px->
area.at(j).at(0) += thisYearRegAreas.at(j);
1376 double totalRegArea =
vSum(thisYearRegAreas);
1377 if (! (totalRegArea==0.0 && totalHarvestedArea==0.0)){
1378 double ratio = totalRegArea / totalHarvestedArea ;
1380 msgOut(
MSG_CRITICAL_ERROR,
"Sum of regeneration areas not equal to sum of harvested area in runManagementModel()!");
1389 if (-fArea_diff > regHArea){
1390 msgOut(
MSG_WARNING,
"In region "+
i2s(regId) +
" the exogenous area decrement ("+
d2s(-fArea_diff) +
" ha) is higger than the harvesting ("+
d2s(regHArea) +
" ha). Ratio forced to 1.");
1393 for(uint j=0;j<
fTypes.size();j++){
1394 double debug = polBal_fiSub[j]/1000000;
1395 sfd((polBal_fiSub[j]/1000000.0),
"polBal_fiSub",regId,
fTypes[j],
"",
DATA_NOW,
true);
1424 msgOut(
MSG_INFO,
"Cashing model settings that may change every year..");
1441 for(uint i=0;i<
regIds2.size();i++){
1444 for (uint j=0;j<rpx.size();j++){
1447 rpx[j]->vol.clear();
1448 for(uint y=0;y<
fTypes.size();y++){
1449 vector <double> vol_byu;
1451 for (uint z=0;z<
dClasses.size();z++){
1454 double pxArea = rpx[j]->getDoubleValue(
"forArea_"+
fTypes[y],
true);
1458 double pxVol = regForArea ? regVol * pxArea/regForArea: 0;
1460 vol_byu.push_back(pxVol);
1462 rpx[j]->vol.push_back(vol_byu);
1502 for(uint r=0;r<
regIds2.size();r++){
1506 for(uint f=0;f<
fTypes.size();f++){
1509 double sStDev =
gfd(
"sStDev",
regIds2[r],ft,
"");
1510 vector<double> vols;
1511 vector<double> diffVols;
1512 vector<double> diffVols_rescaled;
1513 double diffVols_rescaled_deviation;
1514 double diffVols_rescaled_deviation_rescaled;
1517 vector<double> multipliers;
1519 double vol_max, rescale_ratio_avg, rescale_ratio_sd;
1520 double diffVols_avg, diffVols_rescaled_avg;
1521 double diffVols_rescaled_sd;
1523 for (uint p=0;p<rpx.size();p++){
1525 vols.push_back(
vSum(px->
vol[f]));
1529 for(uint p=0;p<vols.size();p++){
1530 diffVols.push_back(vol_max-vols[p]);
1533 diffVols_avg =
getAvg(diffVols);
1534 rescale_ratio_avg = (diffVols_avg != 0.0) ? agr/diffVols_avg : 1.0;
1535 for(uint p=0;p<diffVols.size();p++){
1536 diffVols_rescaled.push_back(diffVols[p]*rescale_ratio_avg);
1538 diffVols_rescaled_avg =
getAvg(diffVols_rescaled);
1539 diffVols_rescaled_sd =
getSd(diffVols_rescaled,
false);
1541 rescale_ratio_sd = (diffVols_rescaled_sd != 0.0) ? sStDev/diffVols_rescaled_sd : 1.0;
1542 for(uint p=0;p<diffVols_rescaled.size();p++){
1543 diffVols_rescaled_deviation = diffVols_rescaled[p] - diffVols_rescaled_avg;
1544 diffVols_rescaled_deviation_rescaled = diffVols_rescaled_deviation * rescale_ratio_sd;
1545 final_value = diffVols_rescaled_avg + diffVols_rescaled_deviation_rescaled;
1546 multiplier = (agr != 0.0) ? min(1.6, max(0.4,final_value/agr)) : 1.0;
1551 multipliers.push_back(multiplier);
1556 double avgMultipliers =
getAvg(multipliers);
1557 double sdMultipliers =
getSd(multipliers,
false);
1558 if ( avgMultipliers < 0.9 || avgMultipliers > 1.1){
1561 if ( ( sdMultipliers - (sStDev/agr) ) < -0.5 || ( sdMultipliers - (sStDev/agr) ) > 0.5 ){
1562 double cv = sStDev/agr;
1563 msgOut(
MSG_CRITICAL_ERROR,
"The sd of multipliers of ft "+ ft +
" for the region " +
i2s(rId) +
" is not equal to the spatial cv for the region!");
1578 for(uint i=0;i<
regIds2.size();i++){
1579 vector<double> deathBiomass;
1580 for(uint j=0;j<
fTypes.size();j++){
1582 deathBiomass.push_back(deathBiomass_ft);
1585 vector<double>qProducts;
1589 qProducts.push_back(int_exports);
1594 qProducts.push_back(consumption);
1604 for(
int y=currentYear;y>currentYear-30;y--){
1605 for(uint i=0;i<
regIds2.size();i++){
1606 for(uint j=0;j<
fTypes.size();j++){
1607 for (uint u=0;u<
dClasses.size();u++){
1630 for(uint i=0;i<
regIds2.size();i++){
1633 for (uint p=0;p<rpx.size();p++){
1635 double pxid= px->
getID();
1636 for(uint j=0;j<
fTypes.size();j++){
1638 vector <double> tempAreas;
1639 vector <double> areasByFt;
1641 for (uint u=0;u<
dClasses.size();u++){
1644 double regRegVolumes =
gfd(
"vReg",
regIds2[i],ft,
"");
1645 double newVReg = regionArea ? regRegVolumes*pxArea/regionArea : 0.0;
1646 double tp_u0 = px->
tp.at(j).at(0);
1647 double entryVolHa =
gfd(
"entryVolHa",
regIds2[i],ft,
"");
1648 double tempArea = (newVReg*1000000.0/entryVolHa)*tp_u0;
1649 tempAreas.push_back(tempArea);
1652 double dcVol = px->
vol_l.at(j).at(u)*1000000.0;
1653 double dcVHa = px->
vHa.at(j).at(u);
1655 if(dcVol < 0.0 || dcVHa < 0.0){
1659 double tempArea = dcVHa?dcVol/dcVHa:0;
1660 tempAreas.push_back(tempArea);
1664 double sumTempArea =
vSum(tempAreas);
1668 double normCoef = sumTempArea?pxArea/ sumTempArea:0;
1675 for (uint u=0;u<
dClasses.size();u++){
1676 areasByFt.push_back(tempAreas.at(u)*normCoef);
1680 double ratio =
vSum(areasByFt)/ pxArea;
1681 if(ratio < 0.99999999999 || ratio > 1.00000000001) {
1686 px->
area_l.push_back(areasByFt);
1708 for(uint r2= 0; r2<
regIds2.size();r2++){
1712 for (uint p=0;p<
regPx.size();p++){
1722 for(uint j=0;j<
fTypes.size();j++){
1731 double pathMort_now, pathMort_t0;
1744 vector <double> cumTp_temp;
1745 vector <double> vHa_temp;
1746 vector <double> cumAlive_temp;
1747 vector <double> cumTp_exp_temp;
1748 vector <double> vHa_exp_temp;
1749 vector <double> cumAlive_exp_temp;
1752 for (uint u=0; u<
dClasses.size(); u++){
1754 double cumTp_u, cumTp_u_exp, cumTp_u_noExp, cumTp_u_fullExp;
1755 double tp, tp_exp, tp_noExp, tp_fullExp;
1756 double vHa_u, vHa_u_exp, vHa_u_noExp, vHa_u_fullExp, beta, beta_exp, beta_noExp, beta_fullExp, mort, mort_exp, mort_noExp, mort_fullExp;
1757 double cumAlive_u, cumAlive_exp_u;
1760 double additionalMortality_multiplier_reg_ft_dc =
gfd(
"additionalMortality_multiplier",regId,ft,dc,
DATA_NOW);
1761 double additionalMortality_multiplier_reg_ft_dc_t0 =
gfd(
"additionalMortality_multiplier",regId,ft,dc,
firstYear);
1762 double additionalMortality_now = px->
getSTData(
"additionalMortality", ft,
DATA_NOW, dc, 0.0)*additionalMortality_multiplier_reg_ft_dc;
1763 double additionalMortality_t0 = px->
getSTData(
"additionalMortality", ft,
firstYear, dc, 0.0)*additionalMortality_multiplier_reg_ft_dc_t0;
1773 cumTp_temp.push_back(cumTp_u);
1774 vHa_temp.push_back(vHa_u);
1775 cumTp_exp_temp.push_back(cumTp_u);
1776 vHa_exp_temp.push_back(vHa_u);
1777 cumAlive_temp.push_back(cumAlive_u);
1778 cumAlive_exp_temp.push_back(cumAlive_u);
1783 tp =
gfd(
"tp",regId,ft,
dClasses[u-1],thisYear)*tp_multiplier_now;
1784 cumTp_u = cumTp_temp[u-1] + tp;
1793 vHa_u =
gfd(
"entryVolHa",regId,ft,
"",thisYear);
1796 mort = 1-pow(1-min(
gfd(
"mortCoef",regId,ft,
dClasses[u-1],thisYear)*mortCoef_multiplier_now+pathMort_now+additionalMortality_now,1.0),tp);
1797 beta =
gfd(
"betaCoef",regId,ft,dc, thisYear)*betaCoef_multiplier_now;
1798 vHa_u = vHa_temp[u-1]*beta*(1-mort);
1800 cumAlive_u = max(0.,cumAlive_temp[u-1]*(1-mort));
1801 cumAlive_temp.push_back(cumAlive_u);
1802 cumTp_temp.push_back(cumTp_u);
1803 vHa_temp.push_back(vHa_u);
1813 cumTp_u_exp = cumTp_exp_temp[u-1]+tp_exp;
1814 cumTp_exp_temp.push_back(cumTp_u_exp);
1819 mort_exp = 1-pow(1-min(
gfd(
"mortCoef",regId,ft,
dClasses[u-1],
firstYear)*mortCoef_multiplier_t0+pathMort_t0+additionalMortality_t0,1.0),tp_exp);
1820 beta_exp =
gfd(
"betaCoef",regId,ft,dc,
firstYear)*betaCoef_multiplier_t0;
1821 vHa_u_exp = vHa_exp_temp[u-1]*beta_exp*(1-mort_exp);
1824 double tp_multiplier_dynamic = px->
getMultiplier(
"tp_multiplier",ft,thisYear+ceil(cumTp_exp_temp[u-1]));
1825 tp_noExp =
gfd(
"tp",regId,ft,
dClasses[u-1])*tp_multiplier_now;
1826 cumTp_u_noExp = cumTp_exp_temp[u-1]+tp_noExp;
1827 tp_fullExp =
gfd(
"tp",regId,ft,
dClasses[u-1],thisYear+ceil(cumTp_exp_temp[u-1]))*tp_multiplier_dynamic ;
1828 cumTp_u_fullExp = cumTp_exp_temp[u-1]+tp_fullExp ;
1829 cumTp_u_exp = cumTp_u_fullExp*expType+cumTp_u_noExp*(1-expType);
1830 cumTp_exp_temp.push_back(cumTp_u_exp);
1832 vHa_u_noExp =
gfd(
"entryVolHa",regId,ft,
"",
DATA_NOW);
1833 vHa_u_fullExp =
gfd(
"entryVolHa",regId,ft,
"",thisYear+ceil(cumTp_u));
1834 vHa_u_exp = vHa_u_fullExp*expType+vHa_u_noExp*(1-expType);
1837 mort_noExp = 1-pow(1-min(1.0,
gfd(
"mortCoef",regId,ft,
dClasses[u-1],
DATA_NOW)*mortCoef_multiplier_now+pathMort_now+additionalMortality_now), tp_noExp);
1838 double mortCoef_multiplier_dynamic = px->
getMultiplier(
"mortCoef_multiplier",ft,thisYear+ceil(cumTp_exp_temp[u-1]));
1839 double pathMort_dynamic = px->
getPathMortality(ft,dc,thisYear+ceil(cumTp_exp_temp[u-1]));
1840 double additionalMortality_multiplier_reg_ft_dc_dynamic =
gfd(
"additionalMortality_multiplier",regId,ft,dc, thisYear+ceil(cumTp_exp_temp[u-1]));
1841 double additionalMortality_dynamic = px->
getSTData(
"additionalMortality", ft, thisYear+ceil(cumTp_exp_temp[u-1]), dc, 0.0)*additionalMortality_multiplier_reg_ft_dc_dynamic;
1842 mort_fullExp = 1-pow(1-min(1.0,
gfd(
"mortCoef",regId,ft,
dClasses[u-1],thisYear+ceil(cumTp_exp_temp[u-1]))*mortCoef_multiplier_dynamic+pathMort_dynamic+additionalMortality_dynamic),tp_fullExp);
1851 beta_noExp =
gfd(
"betaCoef",regId,ft,dc,
DATA_NOW)*betaCoef_multiplier_now;
1852 double betaCoef_multiplier_dynamic = px->
getMultiplier(
"betaCoef_multiplier",ft,thisYear+ceil(cumTp_u));
1853 beta_fullExp =
gfd(
"betaCoef",regId,ft,dc, thisYear+ceil(cumTp_u))*betaCoef_multiplier_dynamic;
1854 mort_exp = mort_fullExp*expType+mort_noExp*(1-expType);
1855 beta_exp = beta_fullExp*expType+beta_noExp*(1-expType);
1856 vHa_u_exp = vHa_exp_temp[u-1]*beta_exp*(1-mort_exp);
1859 vHa_exp_temp.push_back(vHa_u_exp);
1860 cumAlive_exp_u = max(0.,cumAlive_exp_temp[u-1]*(1-mort_exp));
1861 cumAlive_exp_temp.push_back(cumAlive_exp_u);
1877 px->
cumTp.push_back(cumTp_temp);
1878 px->
vHa.push_back(vHa_temp);
1879 px->
cumAlive.push_back(cumAlive_temp);
1880 px->
cumTp_exp.push_back(cumTp_exp_temp);
1881 px->
vHa_exp.push_back(vHa_exp_temp);
1903 for(uint r2= 0; r2<
regIds2.size();r2++){
1906 for (uint p=0;p<
regPx.size();p++){
1944 msgOut(
MSG_INFO,
"Starting cashing on pixel spatial-level exogenous data");
1947 for(uint r2= 0; r2<
regIds2.size();r2++){
1950 for (uint p=0;p<
regPx.size();p++){
1958 for(uint j=0;j<
fTypes.size();j++){
1960 vector <double> tp_byu;
1961 vector <double> beta_byu;
1962 vector <double> mort_byu;
1963 vector <double> addMort_byu;
1975 for (uint u=0; u<
dClasses.size(); u++){
1978 double additionalMortality_multiplier_reg_ft_dc =
gfd(
"additionalMortality_multiplier",regId,ft,dc,
DATA_NOW);
1979 double additionalMortality = px->
getSTData(
"additionalMortality", ft,
DATA_NOW, dc, 0.0)*additionalMortality_multiplier_reg_ft_dc;
1980 double tp, beta_real, mort_real;
1990 mort_real = min(u?
gfd(
"mortCoef",regId,ft,
dClasses[u],
DATA_NOW)*mortCoef_multiplier_now+pathMortality :0,1.0);
1991 tp_byu.push_back(tp);
1992 beta_byu.push_back(beta_real);
1993 mort_byu.push_back(mort_real);
1994 addMort_byu.push_back(additionalMortality);
1996 px->
tp.push_back(tp_byu);
1997 px->
beta.push_back(beta_byu);
1998 px->
mort.push_back(mort_byu);
1999 px->
addMort.push_back(addMort_byu);
2000 px->
avalCoef.push_back(avalCoef_ft);
2008 msgOut(
MSG_INFO,
"Starting computing inventary available for this year..");
2013 for(uint i=0;i<
regIds2.size();i++){
2019 vector <double> in_deathTimber_reg(
priProducts.size(),0.);
2020 for (uint p=0;p<
regPx.size();p++){
2027 for(uint ft=0;ft<
fTypes.size();ft++){
2028 for(uint dc=0;dc<
dClasses.size();dc++){
2033 in_reg.at(pp) += in;
2039 vector<string> priProducts_vector;
2043 in_deathTimber_reg.at(pp) += in_deathMortality;
2053 spd(in_deathTimber_reg.at(pp),
"in_deathTimber",r2,priProducts[pp],
DATA_NOW,
true);
2055 if (in_reg.at(pp) < -0.0){
2070 for (uint i=0; i<nbounds; i++){
2071 vector<int> concernedPriProducts = concernedPriProductsTotal[i];
2079 double bound_total = bound_alive + bound_deathTimber;
2093 for(uint i=0;i<
regIds2.size();i++){
2096 for (uint p=0;p<rpx.size();p++){
2098 double pxid= px->
getID();
2099 for(uint j=0;j<
fTypes.size();j++){
2101 double forArea =
vSum(px->
area.at(j));
2113 map<int,double> forestArea;
2114 pair<int,double > forestAreaPair;
2117 int nFTypes = fTypes.size();
2118 int nL2Regions = l2Regions.size();
2119 for(
int i=0;i<nL2Regions;i++){
2120 int regId = l2Regions[i];
2122 for(
int j=0;j<nFTypes;j++){
2123 string ft = fTypes[j];
2130 for(uint z=0;z<rpx.size();z++){
2136 double newValue = oldValue-hArea+regArea;
2137 double areaNetOfRegeneration = oldValue-hArea;
2139 if (areaNetOfRegeneration<0.0){
2146 rpx[z]->changeValue(
"forArea_"+ft, newValue*10000);
2158 int nFTypes = fTypes.size();
2159 int nL2Regions = l2Regions.size();
2160 for(
int i=0;i<nL2Regions;i++){
2161 int regId = l2Regions[i];
2163 for(
int j=0;j<nFTypes;j++){
2164 string ft = fTypes[j];
2165 for(uint z=0;z<rpx.size();z++){
2167 double vol =
vSum(px->
vol.at(j));
2170 rpx[z]->changeValue(
"vol_"+ft, vol);
2173 rpx[z]->changeValue(
"expectedReturns_"+ft, expectedReturns);
2180 for(
int j=0;j<nFTypes;j++){
2181 string ft = fTypes[j];
2198 map<tr1::array<string, 4>,
double> hVol_byPrd;
2201 for(uint r2= 0; r2<
regIds2.size();r2++){
2207 for(uint j=0;j<
fTypes.size();j++){
2210 double regArea = 0.;
2211 double sumAreaByFt = 0.;
2212 double pxForAreaByFt = 0.;
2214 double sumSumHProductivity = 0.;
2215 double sumHArea = 0.;
2217 for (uint u=0; u<
dClasses.size(); u++){
2223 double vMortAdd = 0;
2224 double sumHProductivity = 0.;
2225 for (uint pi=0;pi<
regPx.size();pi++){
2227 vol += px->
vol.at(j).at(u);
2228 hV += px->
hVol.at(j).at(u);
2229 hArea += px->
hArea.at(j).at(u);
2230 vMort += px->
vMort.at(j).at(u);
2231 vMortAdd += px->
vMortAdd.at(j).at(u);
2237 tr1::array<string, 4> hVKey = {
i2s(regId), ft, dc, pr};
2247 double hProductivityByDc = hArea ? sumHProductivity/hArea : 0.;
2248 sumSumHProductivity += (hProductivityByDc*hArea);
2250 sfd(hProductivityByDc,
"hProductivityByDc",regId,ft,dc,
DATA_NOW,
true);
2251 sfd(hArea,
"harvestedArea",regId,ft,dc,
DATA_NOW,
true);
2253 sfd(vMortAdd,
"vMortAdd",regId,ft,dc,
DATA_NOW,
true);
2254 double vol_1 =
gfd(
"vol",regId,ft,dc,currentYear-1);
2263 double hProductivity = sumHArea? sumSumHProductivity / sumHArea : 0.;
2264 sfd(hProductivity,
"hProductivity",regId,ft,
"",
DATA_NOW,
true);
2266 for (uint p=0;p<
regPx.size();p++){
2268 vReg += px->
vReg.at(j);
2272 sumAreaByFt += pxForAreaByFt;
2274 if(! (sumAreaByFt >= 0.0) ){
2279 sfd(regArea,
"regArea",regId,ft,
"",
DATA_NOW,
true);
2280 sfd(sumAreaByFt,
"forArea",regId,ft,
"",
DATA_NOW,
true);
2283 for (uint p=0;p<
regPx.size();p++){
2285 double totPxForArea =
vSum(px->
area);
2288 double totPxForArea_debug = 0.0;
2289 for(uint j=0;j<
fTypes.size();j++){
2291 totPxForArea_debug += (px->
getDoubleValue(
"forArea_"+ft,
true)/10000);
2294 if ( (totPxForArea - totPxForArea_debug) > 0.0001 || (totPxForArea - totPxForArea_debug) < -0.0001 ){
2295 cout <<
"*** ERROR: area discrepance in pixel " << px->
getID() <<
" of " << (totPxForArea - totPxForArea_debug) <<
" ha!" << endl;
2296 msgOut(
MSG_CRITICAL_ERROR,
"Total forest area in pixel do not coincide if token from layer forArea or (pixel) vector area!");
2313 for(uint r2= 0; r2<
regIds2.size();r2++){
2316 double totRegionForArea = 0.;
2317 double totSumExpRet = 0.;
2318 vector <double> totSumExpRet_byFTParent(parentFtypes.size(),0.0);
2319 vector <double> totSumExpRet_byFTypes(
fTypes.size(),0.0);
2322 for (uint p=0;p<
regPx.size();p++){
2326 totRegionForArea += pxForArea;
2328 for(uint i=0;i<parentFtypes.size();i++){
2331 vector<double> pxExpReturnsByChilds(childPos.size(),0.0);
2332 for(uint j=0;j<childPos.size();j++){
2336 pxExpReturnsByChilds.at(j) = (childIds.at(j) ==
"ash") ? 0.0 : pxExpReturn_singleFt;
2338 totSumExpRet_byFTypes.at(childPos[j]) += pxExpReturn_singleFt*pxForArea;
2340 totSumExpRet_byFTParent[i] +=
getMax(pxExpReturnsByChilds)*pxForArea;
2342 totSumExpRet += bestPxExpectedRet * pxForArea;
2346 for(uint i=0;i<parentFtypes.size();i++){
2348 for(uint j=0;j<childPos.size();j++){
2350 sfd(totSumExpRet_byFTypes.at(childPos[j]),
"sumExpReturns",regId,
fTypes.at(childPos[j]),
"",
DATA_NOW,
true);
2351 sfd(totSumExpRet_byFTypes.at(childPos[j])/totRegionForArea,
"expReturns",regId,
fTypes.at(childPos[j]),
"",
DATA_NOW,
true);
2354 sfd(totSumExpRet_byFTParent.at(i),
"sumExpReturns",regId,parentFtypes[i],
"",
DATA_NOW,
true);
2355 sfd(totSumExpRet_byFTParent.at(i)/totRegionForArea,
"expReturns",regId,parentFtypes[i],
"",
DATA_NOW,
true);
2359 sfd(totSumExpRet,
"sumExpReturns",regId,
"",
"",
DATA_NOW,
true);
2360 sfd(totSumExpRet/totRegionForArea,
"expReturns",regId,
"",
"",
DATA_NOW,
true);
2366 for(uint r2= 0; r2<
regIds2.size();r2++){
2369 double totalForArea = 0.0;
2370 double invadedArea = 0.0;
2371 for (uint p=0;p<
regPx.size();p++){
2374 for(uint j=0;j<
fTypes.size();j++){
2375 for (uint u=0; u<
dClasses.size(); u++){
2382 invadedArea +=
vSum(px->
area)*invaded;
2384 sfd(invadedArea/totalForArea,
"totalShareInvadedArea",regId,
"",
"",
DATA_NOW,
true);
2410 for(uint i=0;i<
regIds2.size();i++){
2411 for(uint j=0;j<
fTypes.size();j++){
2431 for (uint r1=0;r1<
l2r.size();r1++){
2432 for (uint r2=0;r2<
l2r[r1].size();r2++){
2433 int rfrom=
l2r[r1][r2];
2434 double distQProd = 0.0;
2435 for (uint r3=0;r3<
l2r[r1].size();r3++){
2436 int rto =
l2r[r1][r3];
2462 double fullExpWPrice = (curLocPrice*(worldFutPrice/worldCurPrice)*sl+worldFutPrice*sa)/(sa+sl);
2463 double curWPrice = (curLocPrice*sl+worldCurPrice*sa)/(sl+sa);
2464 return curWPrice * (1-expCoef) + fullExpWPrice * expCoef;
2481 int nFTypes =
fTypes.size();
2489 pxC +=
regPx.size();
2492 static vector<vector<vector<double>>> original_vols(pxC, vector<vector<double>>(nFTypes, vector<double>(nDC, 0.0)));
2496 for(uint i=0;i<
fTypes.size();i++){
2497 for (uint u=0; u<
dClasses.size(); u++){
2503 for (uint p=0;p<
regPx.size();p++){
2505 original_vols[pxC_loc][i][u] += px->
vol[i][u];
2511 for(uint i=0;i<
fTypes.size();i++){
2513 for(uint o=0;o<
fTypes.size();o++){
2515 for (uint u=1; u<
dClasses.size(); u++){
2516 string layerName =
"spInput#vol#"+fto+
"#"+fti+
"#"+
i2s(u);
2522 for (uint p=0;p<
regPx.size();p++){
2524 double vol_transfer = min(px->
getDoubleValue(layerName,
true)/1000000,px->
vol[i][u]) ;
2525 px->
vol[i][u] -= vol_transfer;
2526 px->
vol[o][u] += vol_transfer;
2556 vector<vector<vector<double>>> original_areas(pxC, vector<vector<double>>(nFTypes, vector<double>(nDC, 0.0)));
2557 for(uint i=0;i<
fTypes.size();i++){
2558 for (uint u=0; u<
dClasses.size(); u++){
2564 for (uint p=0;p<
regPx.size();p++){
2566 original_areas[pxC_loc][i][u] += px->
area_l[i][u];
2575 vector<vector<vector<double>>> transferred_areas(pxC, vector<vector<double>>(nFTypes, vector<double>(nFTypes, 0.0)));
2577 for(uint i=0;i<
fTypes.size();i++){
2579 for(uint o=0;o<
fTypes.size();o++){
2581 for (uint u=1; u<
dClasses.size(); u++){
2582 string layerName =
"spInput#vol#"+fto+
"#"+fti+
"#"+
i2s(u);
2589 for (uint p=0;p<
regPx.size();p++){
2591 double vol_i_orig = original_vols[pxC_loc][i][u];
2592 double vol_transfer = vol_i_orig?px->
getDoubleValue(layerName,
true)/1000000:0.0;
2593 double area_i_orig = original_areas[pxC_loc][i][u];
2594 double area_transfer = vol_i_orig?area_i_orig*vol_transfer/vol_i_orig:0.0;
2595 px->
area_l[i][u] -= area_transfer;
2597 px->
area_l[o][u] += area_transfer;
2599 transferred_areas[pxC_loc][i][o] += area_transfer;
2614 for (uint p=0;p<
regPx.size();p++){
2616 for(uint i=0;i<
fTypes.size();i++){
2617 for(uint o=0;o<
fTypes.size();o++){
2618 double area_i_orig = 0.0;
2619 for (uint u=1; u<
dClasses.size(); u++){
2620 area_i_orig += original_areas[pxC_loc][i][u];
2622 double area_transfer_u0 = area_i_orig?original_areas[pxC_loc][i][0]*(transferred_areas[pxC_loc][i][o]/area_i_orig):0.0;
2623 px->
area_l[i][0] -= area_transfer_u0 ;
2625 px->
area_l[o][0] += area_transfer_u0 ;
2634 for(uint i=0;i<
fTypes.size();i++){
2635 string fti_id =
fTypes[i];
2637 int ft_memType = fti->
memType;
2638 string ft_layerName = fti->
forLayer;
2642 if(ft_memType==3 ||ft_memType==2){
2647 for (uint p=0;p<
regPx.size();p++){
2649 double area_px =
vSum(px->
area[i]);
2661 cout <<
"Printing debug information on initial regional inventories and supplies.." << endl;
2662 cout <<
"Reg\tProduct\t\tInv\tSt\tSa\tSl" << endl;
2663 for(uint r1=0;r1<
l2r.size();r1++){
2664 for(uint r2c=0;r2c<
l2r[r1].size();r2c++){
2666 int r2 =
l2r[r1][r2c];
2671 cout << r2 <<
"\t" <<
priProducts[p] <<
"\t\t" << inv <<
"\t" << st <<
"\t" << sl <<
"\t" << sa << endl;
2699 for(uint y = currentYear-1; y>currentYear-1-maxYears; y--){
2700 for (
int u =
dClasses.size()-1; u>=0; u--){
2702 for (uint f=0; f<
fTypes.size(); f++){
2707 double sum_total_st_allocable = 0;
2709 for(uint ap=0;ap<allocableProducts.size();ap++){
2710 sum_total_st_allocable += total_st.at(allocableProducts[ap]);
2712 for(uint ap=0;ap<allocableProducts.size();ap++){
2713 double allocableShare = sum_total_st_allocable?total_st.at(allocableProducts[ap])/sum_total_st_allocable:0.0;
2714 double allocated = min(total_st[allocableProducts[ap]],deathTimber*allocableShare);
2716 total_st[allocableProducts[ap]] -= allocated;
2736 for(uint r2=0; r2<
regIds2.size();r2++){
2741 double pol_mktDirInt_s =
gpd(
"pol_mktDirInt_s",regId,
priProducts[p]);
2742 double pol_mktDirInt_s_1 =
gpd(
"pol_mktDirInt_s",regId,
priProducts[p],previousYear);
2753 double gamma = in>in_1 ? gamma_incr: gamma_decr;
2754 double polBal_mktDirInt_s = pc * (1-pol_mktDirInt_s) * sc;
2755 double surplus_prod = pc * sc -
2758 * pow(pol_mktDirInt_s,-1)
2759 * pow(sc_1,-1/sigma)
2760 * pow(in_1/in,gamma/sigma)
2762 * pow(sc,(sigma+1)/sigma);
2768 double pol_mktDirInt_d =
gpd(
"pol_mktDirInt_d",regId,
secProducts[p]);
2769 double pol_mktDirInt_d_1 =
gpd(
"pol_mktDirInt_d",regId,
secProducts[p],previousYear);
2780 double polBal_mktDirInt_d = pc * (pol_mktDirInt_d - 1) * dc;
2781 double polBal_trSub = m * (pol_trSub-1) * sl;
2783 double surplus_cons = pc_1
2785 * pow(dc_1,-1/sigma)
2786 * pow(pol_mktDirInt_d,-1)
2788 * (pow(dc,(sigma+1)/sigma) - pow(trs*dc0,(sigma+1)/sigma))
2789 - (dc - trs * dc0) * pc ;
2798 double polBal_tcSub = 0;
2799 vector<ModelRegion*> siblings = reg->
getSiblings();
2800 for(uint rTo=0;rTo<siblings.size();rTo++){
2801 int regId2 = siblings[rTo]->getRegId();
2804 polBal_tcSub += ct*(pol_tcSub-1) * rt;
2818 if(dc ==
dClasses.size()-1) {
return px->
cumTp[ft][dc] * 1.2;}
2819 else {
return (px->
cumTp[ft][dc]+px->
cumTp[ft][dc+1])/2; }
2837 for (
int u = 0; u<
dClasses.size(); u++){
2848 double cumTP_plus = px->
cumTp_exp[ft][u];
2849 double cumTP_minus = px->
cumTp_exp[ft][u-1];
2850 double volHa_plus = px->
vHa_exp[ft][u];
2851 double volHa_minus = px->
vHa_exp[ft][u-1];
2852 double slope = (volHa_plus - volHa_minus)/(cumTP_plus - cumTP_minus);
2854 vHa = (volHa_minus + (year-cumTP_minus)*slope)*(1+extraBiomass_ratio);
2862 double cumTP_max = px-> cumTp_exp[ft][dc];
2863 double time_elapsed = year - cumTP_max;
2864 double volHa_max = px->
cumTp_exp[ft][dc];
2868 vHa = volHa_max*pow(1-mortCoeff,time_elapsed)*(1+extraBiomass_ratio);
void updateImage(string layerName_h)
Add one layer to the system.
vector< vector< double > > deltaArea
void setSpModifier(const double &value, const int &ftindex)
Class to provide a simple integer-integer-string-string key in std maps.
int getPos(const K &element, const vector< K > &v, const int &msgCode_h=MSG_CRITICAL_ERROR)
Print an ERROR message, but don't stop the model.
The required data is for the current year.
void runBiologicalModule()
computes hV, hArea and new vol at end of year
vector< int > getAllocableProductIdsFromDeathTimber(const int ®Id_h, const string &ft, const string &dc, const int &harvesting_year, int request_year=DATA_NOW)
Returns the ids of the primary products that is possible to obtain using the timber recorded death in...
double getArea(const string &fType_h, const string &dClass_h)
Get area by ft and dc (from pixel->area matrix)
void initialiseDeathBiomassStocks(const vector< double > &deathByFt, const int ®Id)
Initialises the stocks of death biomass for the avgLive_* years before the simulation starts...
int getIntSetting(const string &name_h, int position=0, int reg=WORLD) const
vector< vector< int > > l2r
vector< vector< double > > area
vector< string > dClasses
vector< string > getForTypeParents()
vector< vector< double > > cumAlive_exp
This is the expected version of cumAlive, used for calculating profits.
bool getBoolSetting(const string &name_h, int position=0, int reg=WORLD) const
void runManagementModule()
computes regArea and expectedReturns
Do not actually output any message.
void initializePixelVolumes()
distribuite regional exogenous volumes to pixel volumes using corine land cover area as weight ...
vector< vector< int > > createCombinationsVector(const int &nItems)
Return a vector containing any possible combination of nItems items (including any possible subset)...
void sumRegionalForData()
computes vol, hV, harvestedArea, regArea and expReturns at reg level from the pixel level ...
vector< vector< double > > addMort
void spd(const double &value_h, const string &type_h, const int ®Id_h, const string &prodId_h, const int &year=DATA_NOW, const bool &allowCreate=false, const string &freeDim_h="") const
string i2s(const int &int_h) const
integer to string conversion
ThreadManager * MTHREAD
Pointer to the Thread manager.
K getMax(const vector< K > &v)
Returns the value of the maximum element in the vector (the last one in case of multiple equivalent m...
double getAvailableDeathTimber(const vector< string > &primProd_h, int regId_h, int year_h)
Returns the timber available for a given set of primary products as stored in the deathTimberInventor...
bool layerExist(const string &layerName_h, bool exactMatch=true) const
Return a pointer to a layer given its name.
void changeValue(const string &layerName_h, const double &value_h, const bool &setNoValueForZero=false)
Change the value of an existing layerMTHREAD->GIS->pack(parName, forName, dClass, year)...
double getValue(string layerName, int op=OP_SUM)
return the values of its own pixels for the specified layer. Possible operations: OP_SUM or OP_AVG ...
double calculateAnnualisedEquivalent(const double &amount_h, const int &years_h, const double &ir) const
Calculate the annual equivalent flow.
ModelData * MD
the model data object
void resetMapValues(map< K, V > &mymap, const V &value)
Reset all values stored in a map to the specified one.
void loadExogenousForestLayers(const string &what)
Set pixel volumes (what="vol") OR areas (what="area") by specific forest types as defined in gis laye...
double expType
Sampling derived expectation types of this agent (forest bilogical parameters: growth, mortality)
vector< double > avalCoef
Availability (of wood resources) coefficient. A [0,1] coefficient (new: by forest type) that reduces ...
vector< string > priProducts
string forestAreaChangeMethod
double getAvailableAliveTimber(const vector< string > &primProd_h, int regId_h)
Returns the timber available for a given set of primary products as stored in the px->vol_l vector...
vector< vector< double > > mort
void printOptLog(bool optimal, int &nIterations, double &obj)
Scheduler * SCD
the scheduler object (simulation-loops scheduler)
vector< vector< double > > vMort
vector< T > positionsToContent(const vector< T > &vector_h, const vector< int > &positions)
Return a vector of content from a vector and a vector of positions (int)
vector< vector< double > > vol_l
store the volumes of the previous year
void msgOut(const int &msgCode_h, const string &msg_h, const bool &refreshGUI_h=true) const
Overloaded function to print the output log.
vector< double > expectedAnnualIncome_carbon
Gis * GIS
GIS information and methods.
Thread manager. Responsable to manage the main thread and "speak" with the GUI.
void incrMapValue(map< K, V > &mymap, const K &key, const V &value, const int &error_level=MSG_CRITICAL_ERROR)
Increments a value stored in a map of the specified value, given the key.
vector< string > getStringVectorSetting(const string &name_h, int reg=WORLD) const
void resetPixelValues()
swap volumes->lagged_volumes and reset the other pixel vectors
double deathTimberInventory_get(const iisskey &thekey)
vector< vector< double > > vHa_exp
This is the expected version of vHa, used for calculating profits.
vector< string > pDClasses
vector< double > initialDc0Area
vector< vector< double > > cumAlive
Cumulative prob of remaining alive at beginnin of a given diam class.
vector< int > getForTypeChilds_pos(const string &forTypeId_h, bool all=false)
int getMaxPos(const vector< K > &v)
Returns the position of the maximum element in the vector (the last one in case of multiple equivalen...
void computeInventary()
in=f(vol_t-1)
vector< vector< double > > vHa
Volume at hectar by each diameter class [m^3/ha].
vector< double > inResByAnyCombination
Vector of inventory resource for each possible combination of primary products. This store both alive...
string getStringSetting(const string &name_h, int position=0, int reg=WORLD) const
void runMarketModule()
computes st (supply total) and pw (weighted price). Optimisation inside.
void registerTransports(const double &distQ, const int ®Id)
Registers the quantities emitted by transport of wood FROM a given region.
int getNForTypesChilds(const string &forTypeId_h)
void cacheSettings()
just cache exogenous settings from ModelData
Print an error message and stop the model.
void registerDeathBiomass(const double &value, const int ®Id, const string &fType)
Registers the "death" of a given amount of biomass, storing it in the deathBiomass map...
vector< vector< double > > vMortAdd
double getSTData(const string &parName, const string &forName, int year, const string &d2="", double naToReturn=RETNA)
vector< int > optDcChosen
double getDoubleValue(const string &layerName_h, const bool &returnZeroForNoValue=false) const
Return the value for a specific layer.
string d2s(const double &double_h) const
double to string conversion
vector< double > expectedAnnualIncome_timber
const double getForData(const string &type_h, const int ®Id_h, const string &forType_h, const string &freeDim_h, const int &year=DATA_NOW)
void updateOtherMapData()
update (if the layer exists) other gis-based data, as volumes and expected returns, taking them from the data in the px object
int vSum(const vector< int > &vector_h) const
void initialiseDeathTimber()
Set deathTimberInventory to zero for the previous years (under the hipotesis that we don't have advan...
double getPastRegArea(const int &ft_idx, const int &year)
vector< vector< double > > hProductivity
void initialiseProductsStocks(const vector< double > &qByProduct, const int ®Id)
Initialises the stocks of products for the avgLive_* years before the simulation starts.
void setTempBool(bool tempBool_h)
vector< vector< double > > vol
double getVHaByYear(const Pixel *px, const int &ft, const int &year, const double &extraBiomass_ratio, const int ®Id) const
return the Volume/ha in a forest after a given number of year after planting, for a specific forest t...
double getMultiplier(const string &multiplierName, const string &forName, int year=DATA_NOW)
vector< string > allProducts
vector< string > secProducts
vector< vector< double > > cumTp_exp
This is the expected version of cumTp, used for calculating profits.
double expTypePrices
Sampling derived expectation types of this agent (prices)
void registerHarvesting(const double &value, const int ®Id, const string &fType)
Registers the harvesting of trees increasing the value of cumEmittedForOper.
Print a debug message, normally filtered out.
Ipopt::SmartPtr< Ipopt::TNLP > OPT
Market optimisation.
Carbon * CBAL
Module for the Carbon Balance.
vector< vector< vector< double > > > hVol_byPrd
vector< vector< double > > area_l
store the areas of the previous year
vector< Pixel * > getAllPlotsByRegion(ModelRegion ®ion_h, bool shuffle=false)
Return the vector of all plots by a specific region (main region or subregion), optionally shuffled;...
string getForTypeParentId(const string &forTypeId_h)
vector< string > getForTypeIds(bool all=false)
By default it doesn't return forTypes used only as input.
double getSd(const vector< K > &v, bool sample=true)
double gpd(const string &type_h, const int ®Id_h, const string &prodId_h, const int &year=DATA_NOW, const string &freeDim_h="") const
map< K, V > vectorToMap(const vector< K > &keys, const V &value=0.0)
Returns a map built using the given vector and the given (scalar) value as keys/values pairs...
vector< int > optFtChosen
vector< double > expectedReturns
V findMap(const map< K, V > &mymap, const K &key, const int &error_level=MSG_CRITICAL_ERROR, const V ¬FoundValue=numeric_limits< V >::min()) const
Lookup a map for a value. Return the value starting from the key.
vector< vector< double > > tp
double getPathMortality(const string &forType, const string &dC, int year=DATA_NOW)
Return the INCREASED mortality due to pathogen presence for a given ft and dc in a certain year (defa...
ModelCoreSpatial(ThreadManager *MTHREAD_h)
double getAvgAgeByDc(Pixel *px, int ft, int dc)
return the average age of a tree at a given diameter class, using the cumTp vector ...
void swap(const int &swap_what)
Assign to the delayed value the current values, e.g. vol_l = vol.
vector< ModelRegion * > getSiblings(bool excludeResidual=true)
Return a vector of pointers to the siblings regions.
void printDetailedHV(map< tr1::array< string, 4 >, double > hVol_byPrd)
vector< double > expectedReturnsNotCorrByRa
by ft. Attenction, reported expReturns at "forest" level (compared with those at forest type level) d...
vector< vector< double > > hVol
void incrOrAddMapValue(map< K, V > &mymap, const K &key, const V &value)
Increments a value stored in a map of the specified value, given the key.
void initialiseEmissionCounters()
Initialises the emission counters to zero.
void setErrorLevel(int errorLevel_h)
void initMarketModule()
computes st and pw for second year and several needed-only-at-t0-vars for the market module ...
vector< int > getRegionIds(int level_h, bool excludeResidual=true)
double computeExpectedPrice(const double &curLocPrice, const double &worldCurPrice, const double &worldFutPrice, const double &sl, const double &sa, const double &expCoef)
Compute weighted expected price for a given product.
void print(bool earlyPrint=true)
Print output. If earlyPrinting it doesn't print some stuff for which we don't yet have values...
void HWP_eol2energy()
Computes the energy substitution for the quota of HWP that reachs end of life and doesn't go to landf...
void initializePixelArea()
compute px->area for each ft and dc
double getDoubleSetting(const string &name_h, int position=0, int reg=WORLD) const
vector< vector< double > > cumTp
This is time of passage to REACH a diameter class (while the exogenous tp by diameter class is the ti...
vector< vector< double > > hArea
void sfd(const double &value_h, const string &type_h, const int ®Id_h, const string &forType_h, const string &freeDim_h, const int &year=DATA_NOW, const bool &allowCreate=false) const
string getRegSName() const
double gfd(const string &type_h, const int ®Id_h, const string &forType_h, const string &freeDim_h, const int &year=DATA_NOW) const
bool app(const string &prod_h, const string &forType_h, const string &dClass_h) const
vector< vector< double > > beta
vector< Pixel * > getMyPixels()
void assignSpMultiplierPropToVols()
ModelCoreSpatial::assignSpMultiplierPropToVols assigns the spatial multiplier (used in the time of re...
ModelRegion * getRegion(int regId_h)
void cacheDynamicSettings()
cache settings that may change with time
void initialiseCarbonModule()
call initialiseDeathBiomassStocks(), initialiseProductsStocks() and initialiseEmissionCounters() ...
void cachePixelExogenousData()
computes pixel level tp, meta and mort
double getAvg(const vector< K > &v)
Returns the average of the elements in the vector.
#define DIAM_ALL
All diameter classes.
void updateMapAreas()
computes forArea_{ft}
void deathTimberInventory_incrOrAdd(const iisskey &thekey, double value_h)
void registerCarbonEvents()
call registerHarvesting(), registerDeathBiomass(), registerProducts() and registerTransports() ...
vector< string > getForTypeChilds(const string &forTypeId_h)
void computeCumulativeData()
computes cumTp_exp, vHa_exp, vHa
void registerProducts(const double &value, const int ®Id, const string &productName)
Registers the production of a given amount of products, storing it in the products maps...
void printDebugInitRegionalValues()
print initial inv, st, sl and sa in each region
void computeEconomicBalances()
compute the policy balances (- -> costs; + -> rev) and the producer/consumer surpluses ...
forType * getForType(int position)
map< int, vector< double > > regArea
const int getMaxYearUsableDeathTimber(const string &prod_h, const string &forType_h, const string &dClass_h)
vector< double > allocateHarvesting(vector< double > total_st, const int ®Id)
Using the deathTimberInventory map, this function allocate the total st in st from death timber (that...