ALMaSS Rabbit ODdox  1.00
The rabbit model description following ODdox protocol
farm.cpp
Go to the documentation of this file.
1 
14 //
15 // farm.cpp
16 //
17 /*
18 *******************************************************************************************************
19 Copyright (c) 2011, Christopher John Topping, University of Aarhus
20 All rights reserved.
21 
22 Redistribution and use in source and binary forms, with or without modification, are permitted provided
23 that the following conditions are met:
24 
25 Redistributions of source code must retain the above copyright notice, this list of conditions and the
26 following disclaimer.
27 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
28 the following disclaimer in the documentation and/or other materials provided with the distribution.
29 
30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
31 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
32 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
33 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
35 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 ********************************************************************************************************
39 */
40 
41 //
42 #define _CRT_SECURE_NO_DEPRECATE
43 
44 #include <string.h>
45 #include <algorithm>
46 #include <vector>
47 #include <iostream>
48 #include <fstream>
49 #include "../BatchALMaSS/BoostRandomGenerators.h"
50 #include <math.h> //for optimisation
51 #include <time.h> //for dec. making
52 
53 
54 #define _CRTDBG_MAP_ALLOC
55 
56 using namespace std;
57 
58 #define _CRT_SECURE_NO_DEPRECATE
59 #include <random> //for dec. making - draw from a dist.
60 #include "../BatchALMaSS/ALMaSS_Setup.h"
61 #include "../Landscape/ls.h"
62 #include "../Landscape/cropprogs/BroadBeans.h"
63 #include "../Landscape/cropprogs/Carrots.h"
64 #include "../Landscape/cropprogs/CloverGrassGrazed1.h"
65 #include "../Landscape/cropprogs/CloverGrassGrazed2.h"
66 #include "../Landscape/cropprogs/FieldPeas.h"
67 #include "../Landscape/cropprogs/FieldPeasSilage.h"
68 #include "../Landscape/cropprogs/Fodderbeet.h"
69 #include "../Landscape/cropprogs/Sugarbeet.h"
70 #include "../Landscape/cropprogs/FodderGrass.h"
71 #include "../Landscape/cropprogs/Maize.h"
72 #include "../Landscape/cropprogs/MaizeSilage.h"
73 #include "../Landscape/cropprogs/OFodderbeet.h"
74 #include "../Landscape/cropprogs/OMaizeSilage.h"
75 #include "../Landscape/cropprogs/OBarleyPeaCloverGrass.h"
76 #include "../Landscape/cropprogs/OSBarleySilage.h"
77 #include "../Landscape/cropprogs/OCarrots.h"
78 #include "../Landscape/cropprogs/OCloverGrassGrazed1.h"
79 #include "../Landscape/cropprogs/OCloverGrassGrazed2.h"
80 #include "../Landscape/cropprogs/OCloverGrassSilage1.h"
81 #include "../Landscape/cropprogs/OFirstYearDanger.h"
82 #include "../Landscape/cropprogs/OGrazingPigs.h"
83 #include "../Landscape/cropprogs/OPermanentGrassGrazed.h"
84 #include "../Landscape/cropprogs/OSeedGrass1.h"
85 #include "../Landscape/cropprogs/OSeedGrass2.h"
86 #include "../Landscape/cropprogs/OSpringBarleyPigs.h"
87 #include "../Landscape/cropprogs/OFieldPeas.h"
88 #include "../Landscape/cropprogs/OFieldPeasSilage.h"
89 #include "../Landscape/cropprogs/OrchardCrop.h"
90 #include "../Landscape/cropprogs/OOats.h"
91 #include "../Landscape/cropprogs/Oats.h"
92 #include "../Landscape/cropprogs/OPotatoes.h"
93 #include "../Landscape/cropprogs/OSpringBarley.h"
94 #include "../Landscape/cropprogs/OSpringBarleyExt.h"
95 #include "../Landscape/cropprogs/OWinterBarley.h"
96 #include "../Landscape/cropprogs/OWinterBarleyExt.h"
97 #include "../Landscape/cropprogs/OWinterRape.h"
98 #include "../Landscape/cropprogs/OWinterRye.h"
99 #include "../Landscape/cropprogs/OWinterWheat.h"
100 #include "../Landscape/cropprogs/OWinterWheatUndersown.h"
101 #include "../Landscape/cropprogs/OWinterWheatUndersownExt.h"
102 #include "../Landscape/cropprogs/PermanentGrassGrazed.h"
103 #include "../Landscape/cropprogs/PermanentGrassLowYield.h"
104 #include "../Landscape/cropprogs/PermanentGrassTussocky.h"
105 #include "../Landscape/cropprogs/PermanentSetAside.h"
106 #include "../Landscape/cropprogs/Potatoes.h"
107 #include "../Landscape/cropprogs/PotatoesIndustry.h"
108 #include "../Landscape/cropprogs/seedgrass1.h"
109 #include "../Landscape/cropprogs/seedgrass2.h"
110 #include "../Landscape/cropprogs/setaside.h"
111 #include "../Landscape/cropprogs/SpringBarley.h"
112 #include "../Landscape/cropprogs/SpringBarleySpr.h"
113 #include "../Landscape/cropprogs/SpringBarleyPTreatment.h"
114 #include "../Landscape/cropprogs/SpringBarleySKManagement.h"
115 #include "../Landscape/cropprogs/SpringBarleyCloverGrass.h"
116 #include "../Landscape/cropprogs/SpringBarleySeed.h"
117 #include "../Landscape/cropprogs/SpringBarleySilage.h"
118 #include "../Landscape/cropprogs/SpringRape.h"
119 #include "../Landscape/cropprogs/Triticale.h"
120 #include "../Landscape/cropprogs/OTriticale.h"
121 #include "../Landscape/cropprogs/WinterBarley.h"
122 #include "../Landscape/cropprogs/winterrape.h"
123 #include "../Landscape/cropprogs/WinterRye.h"
124 #include "../Landscape/cropprogs/WinterWheat.h"
125 #include "../Landscape/cropprogs/WWheatPControl.h"
126 #include "../Landscape/cropprogs/WWheatPTreatment.h"
127 #include "../Landscape/cropprogs/WWheatPToxicControl.h"
128 #include "../Landscape/cropprogs/AgroChemIndustryCereal.h"
129 
130 #include "../Landscape/cropprogs/WinterWheatStrigling.h"
131 #include "../Landscape/cropprogs/WinterWheatStriglingCulm.h"
132 #include "../Landscape/cropprogs/WinterWheatStriglingSingle.h"
133 #include "../Landscape/cropprogs/SpringBarleyCloverGrassStrigling.h"
134 #include "../Landscape/cropprogs/SpringBarleyStrigling.h"
135 #include "../Landscape/cropprogs/SpringBarleyStriglingCulm.h"
136 #include "../Landscape/cropprogs/SpringBarleyStriglingSingle.h"
137 #include "../Landscape/cropprogs/MaizeStrigling.h"
138 #include "../Landscape/cropprogs/winterrapestrigling.h"
139 #include "../Landscape/cropprogs/WinterRyeStrigling.h"
140 #include "../Landscape/cropprogs/WinterBarleyStrigling.h"
141 #include "../Landscape/cropprogs/FieldPeasStrigling.h"
142 #include "../Landscape/cropprogs/SpringBarleyPeaCloverGrassStrigling.h"
143 #include "../Landscape/cropprogs/YoungForest.h"
144 
145 
146 #include "../Landscape/map_cfg.h"
147 #include "../BatchALMaSS/BoostRandomGenerators.h"
148 
149 extern boost::variate_generator<base_generator_type&, boost::uniform_real<> > g_rand_uni;
150 
151 extern Landscape * g_landscape_p;
152 
153 CfgBool cfg_organic_extensive( "FARM_ORGANIC_EXTENSIVE", CFG_CUSTOM, false );
154 // Enable this for reading the farm reference file instead of the
155 // automated (not at all random) farm generation. Should not really
156 // be set to false, ever.
157 static CfgBool l_map_read_farmfile( "MAP_READ_FARMFILE", CFG_PRIVATE, true );
158 static CfgStr l_map_farmref_file( "MAP_FARMREF_FILE", CFG_CUSTOM, "farmrefs.txt" );
159 
160 static CfgStr l_emaize_price_file( "EMAIZE_PRICE_FILE", CFG_CUSTOM, "EM_price.txt" );
161 
163 CfgBool cfg_OptimisingFarms("OPTIMISING_FARMS",CFG_CUSTOM, false);
166 CfgBool cfg_OptimiseBedriftsmodelCrops("OPTIMISE_BEDRIFTSMODEL_CROPS",CFG_CUSTOM, false); //12.03.13, set it to true to run the optimisation like in the Bedriftsmodel (with the same crops)
168 CfgBool cfg_DumpFarmAreas ("DUMP_FARM_AREAS", CFG_CUSTOM, false);
171 CfgBool cfg_UseBedriftsmodelFarmAreas ("USE_BEDRIFTSMODEL_FARM_AREAS", CFG_CUSTOM, false);
173 CfgBool cfg_OnlyDeliberation ("ONLY_DELIBERATION", CFG_CUSTOM, true); //041213 if true, farmers will always choose to deliberate (see function ChooseDecisionMode)
174 
176 CfgFloat cfg_Neighbor_dist ("NEIGHBOR_DIST",CFG_CUSTOM,1.5);
178 CfgFloat cfg_Min_certainty("MIN_CERTAINTY",CFG_CUSTOM,0);
180 CfgFloat cfg_Min_need_satisfaction1 ("MIN_NEED_SATISFACTION_ONE",CFG_CUSTOM, 100); //profit, %
182 CfgFloat cfg_Min_need_satisfaction2 ("MIN_NEED_SATISFACTION_TWO",CFG_CUSTOM, 100); //yield, %
184 CfgFloat cfg_Profit_max_proportion ("PROFIT_MAX_PROPORTION",CFG_CUSTOM, 100);//proportion in the population
186 CfgFloat cfg_Yield_max_proportion ("YIELD_MAX_PROPORTION",CFG_CUSTOM, 0);
188 CfgFloat cfg_Environmentalist_proportion ("ENVIRONMENTALIST_PROPORTION",CFG_CUSTOM, 0);
192 CfgFloat cfg_Yield_max_pest_prob_multiplier ("YIELD_MAX_PEST_PROB_MULITPLIER",CFG_CUSTOM, 1.5);
195 CfgFloat cfg_Env_pest_multiplier ("ENV_PEST_MULTIPLIER",CFG_CUSTOM, 1.25); //>1
198 CfgFloat cfg_Env_fert_multiplier ("ENV_FERT_MULTIPLIER",CFG_CUSTOM, 0.8);//<1
199 CfgBool cfg_Sensitivity_analysis ("SENSITIVITY_ANALYSIS", CFG_CUSTOM, false);
201 CfgBool cfg_Areas_Based_on_Distribution ("AREAS_BASED_ON_DISTRIBUTION", CFG_CUSTOM, false);
203 CfgBool cfg_MaizeEnergy ("MAIZE_ENERGY", CFG_CUSTOM, false);
204 
206  CfgFloat cfg_AnimalsThreshold ("ANIMALS_THRESHOLD",CFG_CUSTOM, 0);
208  CfgFloat cfg_PriceChangeThreshold ("PRICE_CHANGE_THRESHOLD",CFG_CUSTOM, 0.2);
210  CfgInt cfg_LifeStage ("LIFE_STAGE", CFG_CUSTOM, 0);
212  CfgInt cfg_Animals_number_test_day ("ANIMALS_NUMBER_TEST_DAY", CFG_CUSTOM, 152);
213 
215 CfgFloat cfg_Price_FU ("PRICE_FU",CFG_CUSTOM, 1.157);
217 CfgFloat cfg_Price_Nt ("PRICE_NT",CFG_CUSTOM, 1.93);
218 CfgFloat cfg_Price_SBarley ("PRICE_SBARLEY",CFG_CUSTOM, 83);
219 CfgFloat cfg_Price_Oats ("PRICE_OATS",CFG_CUSTOM, 75);
220 CfgFloat cfg_Price_WBarley ("PRICE_WBARLEY",CFG_CUSTOM, 93);
221 CfgFloat cfg_Price_WWheat ("PRICE_WWHEAT",CFG_CUSTOM, 94);
222 CfgFloat cfg_Price_Triticale ("PRICE_TRITICALE",CFG_CUSTOM, 80);
223 CfgFloat cfg_Price_WRape ("PRICE_WRAPE",CFG_CUSTOM, 163);
224 CfgFloat cfg_Price_SRape ("PRICE_SRAPE",CFG_CUSTOM, 163);
225 
227 CfgFloat cfg_Min_fodder_prod_pig ("MIN_FODDER_PROD_PIG", CFG_CUSTOM, 20);
229 CfgFloat cfg_Min_fodder_prod_cattle ("MIN_FODDER_PROD_CATTLE", CFG_CUSTOM, 35);
230 
231 
233 CfgFloat cfg_ClosestFarmProbParam1( "CLOSESTFARMPROBPARAMONE", CFG_CUSTOM, 0.005 );
235 CfgFloat cfg_FarmSizeProbParam1( "FARMSIZEPROBPARAMONE", CFG_CUSTOM, 1.5 );
237 CfgFloat cfg_ClosestFarmProbParam2("CLOSESTFARMPROBPARAMTWO", CFG_CUSTOM, 1.0);
238 FarmManager * g_farmmanager; //added 19.03.13
240 CfgFloat cfg_RoostDistProbParam1( "ROOSTDISTPROBPARAMONE", CFG_CUSTOM, 1.5 );
241 
242 
243 
245 bool CompPcts (tpct i,tpct j) { return (i.pct<j.pct); }
246 
247 
249 {
250  m_ddegstoharvest = -1; // Set to -1 to indicate that this is not using ddegs to harvest, this will be reset in descendent classes as needed
251 }
252 
253 bool Crop::Do( Farm * /* a_farm */, LE * /* a_field */, FarmEvent* /* a_ev */ ) {
254  return true;
255 }
256 
257 void Crop::SimpleEvent( long a_date, int a_todo, bool a_lock ) {
258 
259  m_farm->AddNewEvent( m_field->GetVegType(), a_date, m_field, a_todo, m_field->GetRunNum(), a_lock, 0, false, (TTypesOfVegetation) 0 );
260 }
261 
262 
263 void Crop::ChooseNextCrop (int a_no_dates){
264 
268  if(cfg_OptimisingFarms.value()){ // do this only if we have optimising farms
269  if(!cfg_OptimiseBedriftsmodelCrops.value()){ // do this only if we use almass crops!!
270 
271  if (g_date->GetYearNumber()>0){ //changed 030713 since we dont use m_rotation anymore - but we do in the hidden year!
272  OptimisingFarm * opf;
273  if(m_farm->GetType() == tof_OptimisingFarm){ //take only optimising farms
274  opf = dynamic_cast<OptimisingFarm*>(m_farm);
275  opf->Match_crop_to_field (m_field);
276  //move MDates if necessary, use the new_startdate:
277  if (m_ev->m_startday > g_date->DayInYear(1,7)) {
278  if (m_field->GetMDates(0,0) >=m_ev->m_startday)
279  {
280  g_msg->Warn( WARN_BUG, "Crop::ChooseNextCrop(): ","Harvest too late for the next crop to start!!!" );
281  exit( 1 );
282  }
283  // Now fix any late finishing problems
284  for (int i=0; i<a_no_dates; i++) {
285  if(m_field->GetMDates(0,i)>=m_ev->m_startday) {
286  m_field->SetMDates(0,i,m_ev->m_startday-1); //move the starting date
287  }
288  if(m_field->GetMDates(1,i)>=m_ev->m_startday){
289  m_field->SetMConstants(i,0); //change the default value of the MConst (=1) to 0 (necessary to correctly execute farm events in case the finishing date (MDate) was moved)
290  m_field->SetMDates(1,i,m_ev->m_startday-1); //move the finishing date
291  }
292  }
293  }
294 
295  }
296  }
297  }
298  }
299 
300 }
301 
306 void Farm::Management( void ) {
307  HandleEvents();
308  for ( unsigned int i = 0; i < m_fields.size(); i++ ) {
309  // Check for infinite loop in management plan.
310  int count = m_fields[ i ]->GetVegStore();
311  if ( count >= 0 )
312  m_fields[ i ]->SetVegStore( ++count );
313  if ( count > 800 ) {
314  // More than two years where nothing happened.
315  // Raise 'Merry Christmas'!
316  char error_num[ 20 ];
317  sprintf( error_num, "%d", m_fields[ i ]->GetVegType() );
318  g_msg->Warn( WARN_BUG, "I the Farm Manager caught infinite loop in tov type:", error_num );
319  sprintf( error_num, "%d", m_fields[ i ]->m_tried_to_do );
320  g_msg->Warn( WARN_BUG, "It was last seen trying to perform action # ""(or thereabouts):", error_num );
321  exit( 1 );
322  }
323  }
324 }
325 
326 
331 bool Farm::LeSwitch( FarmEvent * ev ) {
332  // Ignore this event if it is from the execution of
333  // a previous management plan.
334  if (ev->m_field->GetRunNum() > ev->m_run)
335  return false;
336  // Store what we are trying to do this time.
337  // ***FN*** To be cleaned up later.
338  ev->m_field->m_tried_to_do = ev->m_todo;
339 
340  bool done;
341 
342  switch (ev->m_event) {
343  case tov_Carrots:
344  done = m_carrots->Do( this, ev->m_field, ev );
345  break;
346  case tov_BroadBeans:
347  done = m_broadbeans->Do( this, ev->m_field, ev );
348  break;
349  case tov_FodderGrass:
350  done = m_foddergrass->Do( this, ev->m_field, ev );
351  break;
353  done = m_CGG1->Do( this, ev->m_field, ev );
354  break;
356  done = m_CGG2->Do( this, ev->m_field, ev );
357  break;
358  case tov_FieldPeas:
359  done = m_fieldpeas->Do( this, ev->m_field, ev );
360  break;
361  case tov_FieldPeasSilage:
362  done = m_fieldpeassilage->Do( this, ev->m_field, ev );
363  break;
364  case tov_FodderBeet:
365  done = m_fodderbeet->Do( this, ev->m_field, ev );
366  break;
367  case tov_SugarBeet:
368  done = m_sugarbeet->Do( this, ev->m_field, ev );
369  break;
370  case tov_OFodderBeet:
371  done = m_ofodderbeet->Do( this, ev->m_field, ev );
372  break;
373  case tov_Maize:
374  done = m_maize->Do( this, ev->m_field, ev );
375  break;
377  done = m_OBarleyPCG->Do( this, ev->m_field, ev );
378  break;
379  case tov_OCarrots:
380  done = m_ocarrots->Do( this, ev->m_field, ev );
381  break;
383  done = m_OCGS1->Do( this, ev->m_field, ev );
384  break;
386  done = m_OCGG1->Do( this, ev->m_field, ev );
387  break;
389  done = m_OCGG2->Do( this, ev->m_field, ev );
390  break;
391  case tov_OFieldPeas:
392  done = m_ofieldpeas->Do( this, ev->m_field, ev );
393  break;
395  done = m_ofieldpeassilage->Do( this, ev->m_field, ev );
396  break;
397  case tov_OGrazingPigs:
398  done = m_ograzingpigs->Do( this, ev->m_field, ev );
399  break;
400  case tov_OrchardCrop:
401  done = m_orchardcrop->Do( this, ev->m_field, ev );
402  break;
403  case tov_OOats:
404  done = m_ooats->Do( this, ev->m_field, ev );
405  break;
406  case tov_Oats:
407  done = m_oats->Do( this, ev->m_field, ev );
408  break;
410  done = m_opermgrassgrazed->Do( this, ev->m_field, ev );
411  break;
412  case tov_OPotatoes:
413  done = m_opotatoes->Do( this, ev->m_field, ev );
414  break;
415  case tov_OSpringBarley:
416  done = m_ospringbarley->Do( this, ev->m_field, ev );
417  break;
418  case tov_OSBarleySilage:
419  done = m_osbarleysilage->Do( this, ev->m_field, ev );
420  break;
421  case tov_OSeedGrass1:
422  done = m_oseedgrass1->Do( this, ev->m_field, ev );
423  break;
424  case tov_OSeedGrass2:
425  done = m_oseedgrass2->Do( this, ev->m_field, ev );
426  break;
428  done = m_ospringbarleyext->Do( this, ev->m_field, ev );
429  break;
431  done = m_ospringbarleypigs->Do( this, ev->m_field, ev );
432  break;
433  case tov_OWinterBarley:
434  done = m_owinterbarley->Do( this, ev->m_field, ev );
435  break;
437  done = m_owinterbarleyext->Do( this, ev->m_field, ev );
438  break;
440  done = m_owinterwheatundersown->Do( this, ev->m_field, ev );
441  break;
442  case tov_OWinterWheat:
443  done = m_owinterwheat->Do( this, ev->m_field, ev );
444  break;
446  done = m_owinterwheatundersownext->Do( this, ev->m_field, ev );
447  break;
448  case tov_OWinterRape:
449  done = m_owinterrape->Do( this, ev->m_field, ev );
450  break;
451  case tov_OWinterRye:
452  done = m_owinterrye->Do( this, ev->m_field, ev );
453  break;
455  done = m_permgrassgrazed->Do( this, ev->m_field, ev );
456  break;
458  done = m_permgrasslowyield->Do( this, ev->m_field, ev );
459  break;
461  done = m_permgrasstussocky->Do( this, ev->m_field, ev );
462  break;
464  done = m_permanentsetaside->Do( this, ev->m_field, ev );
465  break;
466  case tov_Potatoes:
467  done = m_potatoes->Do( this, ev->m_field, ev );
468  break;
470  done = m_potatoesindustry->Do( this, ev->m_field, ev );
471  break;
472  case tov_SeedGrass1:
473  done = m_seedgrass1->Do( this, ev->m_field, ev );
474  break;
475  case tov_SeedGrass2:
476  done = m_seedgrass2->Do( this, ev->m_field, ev );
477  break;
478  case tov_Setaside:
479  done = m_setaside->Do( this, ev->m_field, ev );
480  break;
481  case tov_SpringBarley:
482  done = m_springbarley->Do( this, ev->m_field, ev );
483  break;
484  case tov_SpringBarleySpr:
485  done = m_springbarleyspr->Do( this, ev->m_field, ev );
486  break;
488  done = m_springbarleyptreatment->Do( this, ev->m_field, ev );
489  break;
491  done = m_springbarleyskmanagement->Do( this, ev->m_field, ev );
492  break;
494  done = m_sbarleyclovergrass->Do( this, ev->m_field, ev );
495  break;
497  done = m_springbarleyseed->Do( this, ev->m_field, ev );
498  break;
500  done = m_springbarleysilage->Do( this, ev->m_field, ev );
501  break;
502  case tov_SpringRape:
503  done = m_springrape->Do( this, ev->m_field, ev );
504  break;
505  case tov_Triticale:
506  done = m_triticale->Do( this, ev->m_field, ev );
507  break;
508  case tov_OTriticale:
509  done = m_otriticale->Do( this, ev->m_field, ev );
510  break;
511  case tov_WinterBarley:
512  done = m_winterbarley->Do( this, ev->m_field, ev );
513  break;
514  case tov_WinterRape:
515  done = m_winterrape->Do( this, ev->m_field, ev );
516  break;
517  case tov_WinterRye:
518  done = m_winterrye->Do( this, ev->m_field, ev );
519  break;
520  case tov_WinterWheat:
521  done = m_winterwheat->Do( this, ev->m_field, ev );
522  break;
523  case tov_WWheatPControl:
524  done = m_wwheatpcontrol->Do( this, ev->m_field, ev );
525  break;
527  done = m_wwheatptoxiccontrol->Do( this, ev->m_field, ev );
528  break;
530  done = m_wwheatptreatment->Do( this, ev->m_field, ev );
531  break;
533  done = m_agrochemindustrycereal->Do( this, ev->m_field, ev );
534  break;
536  done = m_winterwheatstrigling->Do( this, ev->m_field, ev );
537  break;
539  done = m_winterwheatstriglingsingle->Do( this, ev->m_field, ev );
540  break;
542  done = m_winterwheatstriglingculm->Do( this, ev->m_field, ev );
543  break;
545  done = m_springbarleyclovergrassstrigling->Do( this, ev->m_field, ev );
546  break;
548  done = m_springbarleystrigling->Do( this, ev->m_field, ev );
549  break;
551  done = m_springbarleystriglingsingle->Do( this, ev->m_field, ev );
552  break;
554  done = m_springbarleystriglingculm->Do( this, ev->m_field, ev );
555  break;
556  case tov_MaizeStrigling:
557  done = m_maizestrigling->Do( this, ev->m_field, ev );
558  break;
559  case tov_MaizeSilage:
560  done = m_maizesilage->Do( this, ev->m_field, ev );
561  break;
562  case tov_OMaizeSilage:
563  done = m_omaizesilage->Do( this, ev->m_field, ev );
564  break;
566  done = m_winterrapestrigling->Do( this, ev->m_field, ev );
567  break;
569  done = m_winterryestrigling->Do( this, ev->m_field, ev );
570  break;
572  done = m_winterbarleystrigling->Do( this, ev->m_field, ev );
573  break;
575  done = m_fieldpeasstrigling->Do( this, ev->m_field, ev );
576  break;
578  done = m_springbarleypeaclovergrassstrigling->Do( this, ev->m_field, ev );
579  break;
580  case tov_YoungForest:
581  done = m_youngforest->Do( this, ev->m_field, ev );
582  break;
583  /* case tov_OFirstYearDanger: done = m_ofirstyeardanger->Do( this, ev->m_field, ev ); break; */
584  default:
585  char veg_type[ 20 ];
586  sprintf( veg_type, "%d", ev->m_event );
587  g_msg->Warn( WARN_FILE, "Farm::LeSwitch(): ""Unknown crop type: ", veg_type );
588  exit( 1 );
589 
590  }
591  return done;
592 }
593 
594 
599 void Farm::AddNewEvent( TTypesOfVegetation a_event, long a_date, LE * a_field, int a_todo, long a_run, bool a_lock,
600  int a_start, bool a_first_year, TTypesOfVegetation a_crop ) {
601  FarmEvent * ev = new FarmEvent( a_event, a_field, a_todo, a_run, a_lock, a_start, a_first_year, a_crop );
602  m_queue.Push( ev, a_date );
603 }
604 
605 
610 bool Farm::DoIt( int a_probability ) {
611  return ( a_probability > ( int )( rand() % 100 ) );
612 }
613 
618 void Farm::ReadRotation(std::string str)
619 {
620  ifstream ifile;
621  ifile.open(str.c_str(),ios::in);
622  if ( !ifile.is_open() ) {
623  g_msg->Warn( "Cannot open file: ", str.c_str() );
624  exit( 1 );
625  }
626  int nocrops;
627  ifile >> nocrops;
628  m_rotation.resize( nocrops );
629  std::string cropref;
630  for ( int i = 0; i < nocrops; i++ ) {
631  ifile >> cropref;
632  TTypesOfVegetation tov = g_farmmanager->TranslateCropCodes( cropref );
633  m_rotation[ i ] = tov;
634  }
635  ifile.close();
636 }
637 
642  if ( ev->m_field->GetMgtLoopDetectDate() == g_date->Date() ) {
643  // The last crop managment plan stopped on the same day as
644  // it was started.
645 
646  // Bump loop counter.
648 
649  if ( ev->m_field->GetMgtLoopDetectCount() > ( long )( m_rotation.size() + 2 ) ) {
650  // We have a loop.
651  char errornum[ 20 ];
652  sprintf( errornum, "%d", m_farmtype );
653  g_msg->Warn( WARN_BUG, "Rotation management loop detected in farmtype ", errornum );
654  exit( 1 );
655  }
656  } else {
657  ev->m_field->SetMgtLoopDetectCount( 0 );
658  }
659 }
660 
661 
666 int Farm::GetNextCropStartDate( LE * a_field, TTypesOfVegetation & a_curr_veg ) {
667  TTypesOfVegetation l_tov2;
668 
669  if ( a_field->GetRotIndex() < 0 || g_farm_fixed_crop_enable.value() //|| g_farm_test_crop.value()
670  ) {
671  l_tov2 = a_curr_veg; // don't do it if no rotation
672  } else {
673  l_tov2 = m_rotation[ GetNextCropIndex( a_field->GetRotIndex() ) ];
674  }
675  a_curr_veg = l_tov2;
676  return GetFirstDate( l_tov2 );
677 }
678 
679 
684 void Farm::HandleEvents( void ) {
685  if ( m_queue.Empty() )
686  return;
687 
688  LowPriPair < FarmEvent * > pair = m_queue.Bottom();
689  FarmEvent * ev = pair.m_element;
690  while ( pair.m_pri <= g_date->Date() ) {
691  m_queue.Pop();
693  if ( LeSwitch( ev ) ) {
694  // This crop management plan has terminated.
695 
696  // First check for an infinite loop in the rotation scheme,
697  // ie. a scenario where all crops decide not to run given
698  // the date.
699  CheckRotationManagementLoop( ev );
700 
701  // Outdate any remaining events for this field.
702  ev->m_field->BumpRunNum();
703 
704  // Crop treatment done, select and initiate new crop if in rotation.
705  TTypesOfVegetation new_veg = ev->m_field->GetVegType();
706 
707  if ( ev->m_field->GetRotIndex() >= 0 ) {
708  int new_index = GetNextCropIndex( ev->m_field->GetRotIndex() );
709  new_veg = m_rotation[ new_index ];
710  // Running in fixed crop mode?
713  }
715  ev->m_field->SetRotIndex( new_index );
717  ev->m_field->SetVegType(new_veg, tov_Undefined);
718  }
719 
720  // Reset the event list for this field.
721  ev->m_field->ResetTrace();
722  // Reset event timeout counter.
723  ev->m_field->SetVegStore( 0 );
724 
725  // The next bit simply determines the start date of the next crop in
726  // the rotation and passes this to the start crop event.
727  // The crop is responsible for raising an error if the next crop is
728  // not possible or otherwise handling the problem
729 
730  // 19/5-2003: Note: This code was moved out into a dedicated
731  // method of the Farm class, GetNextCropStartDate(), as precisely
732  // the same piece of code needs to be run during initialization of
733  // farm management.
734  TTypesOfVegetation l_tov = new_veg;
735  int l_nextcropstartdate = GetNextCropStartDate( ev->m_field, l_tov );
736 
737  // Create 'start' event for today and put it on the queue.
738  AddNewEvent( new_veg, g_date->Date(), ev->m_field, PROG_START, ev->m_field->GetRunNum(),
739  false, l_nextcropstartdate, false, l_tov );
740 
741  // Set starting date for rotation mgmt loop detection.
743  }
744 
745  delete ev;
746 
747  if ( m_queue.Empty() )
748  return;
749  pair = m_queue.Bottom();
750  ev = pair.m_element;
751  }
752 }
753 
754 
756  if ( m_queue.Empty() )
757  return;
758 
759  LowPriPair < FarmEvent * > pair = m_queue.Bottom();
760  FarmEvent * ev = pair.m_element;
761  while ( pair.m_pri <= g_date->Date() ) {
762  m_queue.Pop();
763 
764  if ( LeSwitch( ev ) ) {
765  // This crop management plan has terminated.
766 
767  // First check for an infinite loop in the rotation scheme,
768  // ie. a scenario where all crops decide not to run given
769  // the date.
770  CheckRotationManagementLoop( ev );
771 
772  // Outdate any remaining events for this field.
773  ev->m_field->BumpRunNum();
774 
775  // Crop treatment done, select and initiate new crop if in rotation.
776  TTypesOfVegetation new_veg = ev->m_field->GetVegType();
777 
778  if ( ev->m_field->GetRotIndex() >= 0 ) {
779  int new_index = GetNextCropIndex( ev->m_field->GetRotIndex() );
780  new_veg = m_rotation[ new_index ];
781  // Running in fixed crop mode?
784  }
785  /*
786  if ( g_farm_test_crop.value() ) {
787  new_veg = g_letype->TranslateVegTypes( g_farm_test_crop_type.value() );
788  }
789  */
790  ev->m_field->SetRotIndex( new_index );
791  ev->m_field->SetVegType( new_veg, tov_Undefined );
792  // ***CJT*** Testing removal 3/2/2015 ev->m_field->ForceGrowthTest();
793  }
794 
795 
796  //------------05.03.12 AM - tell a field the crop has changed - here the OptimisingFarm part---------------------------------------
797  if(!cfg_OptimiseBedriftsmodelCrops.value()){ //don't do this if you simulate the bedriftsmodel (original farm optimization model) crops
798  //switch the previous crop (if it is still there) to position 1 in an array m_CropDataStorage; put a new crop at position 0
799  VegElement * pf = dynamic_cast<VegElement*>(ev->m_field);
800  if(pf->Get_taken(0)){ //there is a crop at position 0 - so need to copy it to position 1 and clear all values at position 0
801  if(pf->Get_taken(1)){ //problem - we have 3rd crop when two previous crops were not calculated yet - it shouldn't happen!
802  char error_num[ 20 ];
803  sprintf( error_num, "%d", new_veg );
804  g_msg->Warn( WARN_FILE, "Farm::HandleEvents(): there is 3rd crop starting when 2 previous were not calculated yet, the 3rd crop is", error_num );
805  exit( 1 );
806  }
807  pf->Set_CropDataStorage(1, pf->Get_CropDataStorage(0)); //copy the content of a struct at position 0 of the m_CropDataStorage array to position 1
808  pf->Set_taken(true, 1); //mark the struct at position 1 as taken by a crop
809  pf->Clean_CropDataStorage(0); //clear struct at position 0
810 
811  }
812  //now save the new crop at position zero - whether there was a crop here or not
813  pf->Clean_CropDataStorage(0); //clear struct at position 0 //do it cause the previous crop's operations could have been saved here - if there was some time between accoutning and start of this new crop
814  pf->Set_taken(true, 0); // the new crop is at position 0
815  pf->Set_tov_type(new_veg, 0); //save the tov_type of a new crop
816  pf->Set_area_in_crop_data(pf->GetArea());
817  }
818  //---------------------end 05.03.13----------------------------------------------------------------
819 
820 
821  // Reset the event list for this field.
822  ev->m_field->ResetTrace();
823  // Reset event timeout counter.
824  ev->m_field->SetVegStore( 0 );
825 
826  // The next bit simply determines the start date of the next crop in
827  // the rotation and passes this to the start crop event.
828  // The crop is responsible for raising an error if the next crop is
829  // not possible or otherwise handling the problem
830 
831  // 19/5-2003: Note: This code was moved out into a dedicated
832  // method of the Farm class, GetNextCropStartDate(), as precisely
833  // the same piece of code needs to be run during initialization of
834  // farm management.
835  TTypesOfVegetation l_tov = new_veg;
836  int l_nextcropstartdate = GetNextCropStartDate( ev->m_field, l_tov );
837 
838  // Create 'start' event for today and put it on the queue.
839  AddNewEvent( new_veg, g_date->Date(), ev->m_field, PROG_START, ev->m_field->GetRunNum(),
840  false, l_nextcropstartdate, false, l_tov );
841 
842  // Set starting date for rotation mgmt loop detection.
844  }
845 
846  delete ev;
847 
848  if ( m_queue.Empty() )
849  return;
850  pair = m_queue.Bottom();
851  ev = pair.m_element;
852  }
853 }
854 
855 
856 
857 
862 Farm::Farm( FarmManager* a_manager )
863 {
864  m_OurManager = a_manager;
865  m_carrots = new Carrots;
866  m_broadbeans = new BroadBeans;
867  m_CGG1 = new CloverGrassGrazed1;
868  m_CGG2 = new CloverGrassGrazed2;
869  m_fieldpeas = new FieldPeas;
870  m_fieldpeassilage = new FieldPeasSilage;
871  m_fodderbeet = new Fodderbeet;
872  m_sugarbeet = new Sugarbeet;
873  m_ofodderbeet = new OFodderbeet;
874  m_foddergrass = new FodderGrass;
875  m_maize = new Maize;
876  m_maizesilage = new MaizeSilage;
877  m_omaizesilage = new OMaizeSilage;
878  m_OBarleyPCG = new OBarleyPeaCloverGrass;
879  m_ocarrots = new OCarrots;
880  m_OCGG1 = new OCloverGrassGrazed1;
881  m_OCGG2 = new OCloverGrassGrazed2;
882  m_OCGS1 = new OCloverGrassSilage1;
883  m_ofieldpeas = new OFieldPeas;
884  m_ofieldpeassilage = new OFieldPeasSilage;
885  m_ofirstyeardanger = new OFirstYearDanger;
886  m_ograzingpigs = new OGrazingPigs;
887  m_orchardcrop = new OrchardCrop;
888  m_oats = new Oats;
889  m_ooats = new OOats;
890  m_opermgrassgrazed = new OPermanentGrassGrazed;
891  m_opotatoes = new OPotatoes;
892  m_oseedgrass1 = new OSeedGrass1;
893  m_oseedgrass2 = new OSeedGrass2;
894  m_ospringbarley = new OSpringBarley;
895  m_osbarleysilage = new OSBarleySilage;
896  m_ospringbarleyext = new OSpringBarleyExt;
897  m_ospringbarleypigs = new OSpringBarleyPigs;
898  m_owinterbarley = new OWinterBarley;
899  m_owinterbarleyext = new OWinterBarleyExt;
900  m_owinterrape = new OWinterRape;
901  m_owinterrye = new OWinterRye;
902  m_owinterwheat = new OWinterWheat;
903  m_owinterwheatundersown = new OWinterWheatUndersown;
904  m_owinterwheatundersownext = new OWinterWheatUndersownExt;
905  m_permanentsetaside = new PermanentSetAside;
906  m_permgrassgrazed = new PermanentGrassGrazed;
907  m_permgrasslowyield = new PermanentGrassLowYield;
908  m_permgrasstussocky = new PermanentGrassTussocky;
909  m_potatoes = new Potatoes;
910  m_potatoesindustry = new PotatoesIndustry;
911  m_sbarleyclovergrass = new SpringBarleyCloverGrass;
912  m_seedgrass1 = new SeedGrass1;
913  m_seedgrass2 = new SeedGrass2;
914  m_setaside = new SetAside;
915  m_springbarley = new SpringBarley;
916  m_springbarleyspr = new SpringBarleySpr;
917  m_springbarleyptreatment = new SpringBarleyPTreatment;
918  m_springbarleyskmanagement = new SpringBarleySKManagement;
919  m_springbarleyseed = new SpringBarleySeed;
920  m_springbarleysilage = new SpringBarleySilage;
921  m_springrape = new SpringRape;
922  m_triticale = new Triticale;
923  m_otriticale = new OTriticale;
924  m_winterbarley = new WinterBarley;
925  m_winterrape = new WinterRape;
926  m_winterrye = new WinterRye;
927  m_winterwheat = new WinterWheat;
928  m_wwheatpcontrol = new WWheatPControl;
929  m_wwheatptoxiccontrol = new WWheatPToxicControl;
930  m_wwheatptreatment = new WWheatPTreatment;
931  m_agrochemindustrycereal = new AgroChemIndustryCereal;
932  m_winterwheatstrigling = new WinterWheatStrigling;
933  m_winterwheatstriglingsingle = new WinterWheatStriglingSingle;
934  m_winterwheatstriglingculm = new WinterWheatStriglingCulm;
935  m_springbarleyclovergrassstrigling = new SpringBarleyCloverGrassStrigling;
936  m_springbarleystrigling = new SpringBarleyStrigling;
937  m_springbarleystriglingsingle = new SpringBarleyStriglingSingle;
938  m_springbarleystriglingculm = new SpringBarleyStriglingCulm;
939  m_maizestrigling = new MaizeStrigling;
940  m_winterrapestrigling = new WinterRapeStrigling;
941  m_winterryestrigling = new WinterRyeStrigling;
942  m_winterbarleystrigling = new WinterBarleyStrigling;
943  m_fieldpeasstrigling = new FieldPeasStrigling;
944  m_springbarleypeaclovergrassstrigling = new SpringBarleyPeaCloverGrassStrigling;
945  m_youngforest = new YoungForestCrop;
946  m_rotation_sync_index = -1;
947  // Defaults that need to be overridden when necessary
948  m_stockfarmer = false;
949  m_intensity = 0;
950  m_HuntersList.resize(0); // Set the number of hunters to zero at the start.
951 }
952 
953 
958 Farm::~Farm( void ) {
959  delete m_carrots;
960  delete m_broadbeans;
961  delete m_CGG2;
962  delete m_CGG1;
963  delete m_fieldpeas;
964  delete m_fieldpeassilage;
965  delete m_fodderbeet;
966  delete m_sugarbeet;
967  delete m_ofodderbeet;
968  delete m_foddergrass;
969  delete m_maizesilage;
970  delete m_omaizesilage;
971  delete m_maize;
972  delete m_ocarrots;
973  delete m_OCGG1;
974  delete m_OCGG2;
975  delete m_OCGS1;
976  delete m_ofieldpeas;
977  delete m_ofieldpeassilage;
978  delete m_ofirstyeardanger;
979  delete m_ograzingpigs;
980  delete m_orchardcrop;
981  delete m_ooats;
982  delete m_oats;
983  delete m_opermgrassgrazed;
984  delete m_opotatoes;
985  delete m_ospringbarley;
986  delete m_ospringbarleyext;
987  delete m_osbarleysilage;
988  delete m_ospringbarleypigs;
989  delete m_owinterbarley;
990  delete m_owinterbarleyext;
991  delete m_owinterrape;
992  delete m_owinterrye;
993  delete m_owinterwheatundersown;
994  delete m_owinterwheatundersownext;
995  delete m_OBarleyPCG;
996  delete m_permanentsetaside;
997  delete m_permgrassgrazed;
998  delete m_permgrasstussocky;
999  delete m_permgrasslowyield;
1000  delete m_potatoes;
1001  delete m_potatoesindustry;
1002  delete m_sbarleyclovergrass;
1003  delete m_seedgrass2;
1004  delete m_seedgrass1;
1005  delete m_setaside;
1006  delete m_springbarley;
1007  delete m_springbarleyptreatment;
1008  delete m_springbarleyskmanagement;
1009  delete m_springbarleyseed;
1010  delete m_springrape;
1011  delete m_springbarleysilage;
1012  delete m_agrochemindustrycereal;
1013  delete m_triticale;
1014  delete m_winterbarley;
1015  delete m_winterrape;
1016  delete m_winterrye;
1017  delete m_winterwheat;
1018  delete m_wwheatpcontrol;
1019  delete m_wwheatptoxiccontrol;
1020  delete m_wwheatptreatment;
1021  delete m_winterwheatstrigling;
1022  delete m_winterwheatstriglingsingle;
1023  delete m_winterwheatstriglingculm;
1024  delete m_springbarleyclovergrassstrigling;
1025  delete m_springbarleystrigling;
1026  delete m_springbarleystriglingsingle;
1027  delete m_springbarleystriglingculm;
1028  delete m_maizestrigling;
1029  delete m_winterrapestrigling;
1030  delete m_winterryestrigling;
1031  delete m_winterbarleystrigling;
1032  delete m_fieldpeasstrigling;
1033  delete m_springbarleypeaclovergrassstrigling;
1034  delete m_youngforest;
1036 
1037  while ( !m_queue.Empty() ) {
1038  pair = m_queue.Bottom();
1039  m_queue.Pop();
1040  delete pair.m_element;
1041  }
1042 }
1043 
1046  int area = 0;
1047  for (unsigned int i = 0; i < m_fields.size(); i++) {
1048  if (m_fields[i]->GetElementType() == tole_Field) area += (int)m_fields[i]->GetArea();
1049  }
1050  return area;
1051 }
1052 
1055  int area = 0;
1056  for (unsigned int i = 0; i < m_fields.size(); i++)
1057  {
1058  area += (int)m_fields[i]->GetArea();
1059  }
1060  return area;
1061 }
1062 
1065  double area = 0;
1066  for ( unsigned int i = 0; i < m_fields.size(); i++ ) {
1067  if (m_fields[i]->GetElementType()==tole_Field) area += m_fields[i]->GetArea();
1068  }
1069  return area;
1070 }
1071 
1073 int Farm::GetNoOpenFields(int a_openness)
1074 {
1075  int num = 0;
1076  for (unsigned int i = 0; i < m_fields.size(); i++) {
1077  if (m_fields[i]->GetOpenness() > a_openness) num++;
1078  }
1079  return num;
1080 }
1081 
1083 int Farm::GetAreaOpenFields(int a_openness)
1084 {
1085  int area = 0;
1086  for (unsigned int i = 0; i < m_fields.size(); i++) {
1087  if (m_fields[i]->GetOpenness() > a_openness) area += int(m_fields[i]->GetArea());
1088  }
1089  return area;
1090 }
1091 
1100  // If g_farm_fixed_rotation, then determine the first
1101  // crop number in the rotation rotation number.
1103 
1105  // We are running all the farms synchronized, so
1106  // simply set the first crop to run on all farm fields.
1107  return 0;
1108  }
1109 
1110  // Each farm runs its fields sync'ed but independently from
1111  // the other farmers.
1112 
1113  // Determine if this farm has selected its own start index
1114  // and set it if not. m_rotation_sync_index is initialized
1115  // to -1 by the Farm::Farm() constructor.
1116  if ( -1 == m_rotation_sync_index ) {
1117  m_rotation_sync_index = (int) (rand() % m_rotation.size());
1118  }
1119  // Return farm localized rotation index.
1120  return m_rotation_sync_index;
1121  }
1122 
1123  // Not synchronised, but we want to follow our rotation sequence, so check
1124  // if we have started this process, if not set the sync value.
1125  // afterwards just increment this.
1126  if ( -1 == m_rotation_sync_index ) {
1127  m_rotation_sync_index = (int) (rand() % m_rotation.size());
1128  }
1129  else m_rotation_sync_index = (int) ((m_rotation_sync_index+1) % m_rotation.size());
1130  return m_rotation_sync_index;
1131 }
1132 
1133 
1141 int Farm::GetNextCropIndex( int a_rot_index ) {
1143  // Rotation not enabled.
1144  return a_rot_index;
1145  }
1146 
1147  if ( a_rot_index == -1 )
1148  return -1;
1149 
1150  if ( ( unsigned int ) ( ++a_rot_index ) == m_rotation.size() ) //AM comm: the last crop was the last element of the vector - so go back to the element zero; otherwise just add 1 to the index
1151  a_rot_index = 0;
1152 
1153  return a_rot_index;
1154 }
1155 
1156 
1161 void Farm::AddField( LE * a_newfield ) {
1162  int i = (int) m_fields.size();
1163 
1164  m_fields.resize( i + 1 );
1165  m_fields[ i ] = a_newfield;
1166  // Must set the rot index to something other than -1, but identify it as not usefully set as yet.
1167  TTypesOfLandscapeElement ele = a_newfield->GetElementType();
1168  switch (ele) {
1170  case tole_YoungForest:
1171  case tole_PermPasture:
1174  case tole_Orchard:
1175  m_fields[ i ]->SetRotIndex(-2);
1176  break;
1177  default:
1178  m_fields[ i ]->SetRotIndex(-1);
1179  }
1180 }
1181 
1186 void Farm::RemoveField( LE * a_field ) {
1187  int nf = (int) m_fields.size();
1188  for ( int i = 0; i < nf; i++ ) {
1189  if ( m_fields[ i ] == a_field ) {
1190  m_fields.erase( m_fields.begin() + i );
1191  return;
1192  }
1193  }
1194  // If we reach here there is something wrong because the field is not a
1195  // member of this farm
1196  g_msg->Warn( WARN_BUG, "Farm::RemoveField(LE* a_field): ""Unknown field! ", "" );
1197  exit( 1 );
1198 }
1199 
1200 
1201 void Farm::Assign_rotation(vector<TTypesOfVegetation>a_new_rotation) {
1202 
1203  m_rotation.clear();
1204  m_rotation = a_new_rotation;
1205 
1206 }
1207 
1213  // First we need to assign the permanent crops if any.
1214  if (m_PermCrops.size()>0) {
1215  // We have something to do
1216  for (int i=0; i<(int)m_PermCrops.size(); i++) {
1217  AssignPermanentCrop(m_PermCrops[i].Tov, m_PermCrops[i].Pct);
1218  }
1219  }
1221 }
1222 
1228  for ( unsigned int i = 0; i < m_fields.size(); i++ ) {
1229  int rot_index = m_fields[ i ]->GetRotIndex();
1231  // If the field has been designated as non-rotating and therefore already has its veg type, then skip it.
1232  if ( rot_index < -1 ) {
1233  // Check for any type of permanent element type with management plan.
1234  TTypesOfLandscapeElement ele = m_fields[ i ]->GetElementType();
1235  switch (ele) {
1237  new_veg = tov_PermanentGrassLowYield;
1238  break;
1239  case tole_YoungForest:
1240  new_veg = tov_YoungForest;
1241  break;
1242  case tole_PermPasture:
1243  new_veg = tov_PermanentGrassGrazed;
1244  break;
1246  new_veg = tov_PermanentGrassTussocky;
1247  break;
1249  new_veg = tov_PermanentSetaside;
1250  break;
1251  case tole_Orchard:
1252  new_veg = tov_OrchardCrop;
1253  break;
1254  default:
1255  if (rot_index != -4) {
1256  // Error
1257  g_msg->Warn("Unexpected negative value in Farm::InitiateManagement","");
1258  exit(0);
1259  } else new_veg = m_fields[ i ]->GetVegType();
1260  }
1261  }
1262  else {
1263  rot_index = GetFirstCropIndex( m_fields[ i ]->GetElementType() );
1264  new_veg = m_rotation[ rot_index ];
1265  }
1266  // Running in fixed crop mode?
1267  if ( g_farm_fixed_crop_enable.value() ) {
1268  int fv = g_farm_fixed_crop_type.value();
1269  new_veg = g_letype->TranslateVegTypes( fv );
1270  }
1271  m_fields[ i ]->SetVegType( new_veg, tov_Undefined );
1272  m_fields[ i ]->SetRotIndex( rot_index );
1273  m_fields[ i ]->SetGrowthPhase( janfirst );
1274  // Reset event timeout counter. We are now 800 days from
1275  // oblivion.
1276  long prog_start_date = g_date->Date();
1277  m_fields[ i ]->SetVegStore( 0 );
1278  TTypesOfVegetation l_tov = new_veg;
1279  int l_nextcropstartdate = GetNextCropStartDate( m_fields[ i ], l_tov );
1280  AddNewEvent( new_veg, prog_start_date, m_fields[ i ], PROG_START, 0, false, l_nextcropstartdate, true, l_tov );
1281  }
1282 }
1283 
1289  switch ( a_tov2 ) {
1290  case tov_Carrots:
1291  return m_carrots->GetFirstDate();
1292  case tov_BroadBeans:
1293  return m_broadbeans->GetFirstDate( );
1294  case tov_FodderGrass:
1295  return m_foddergrass->GetFirstDate();
1297  return m_CGG1->GetFirstDate();
1299  return m_CGG2->GetFirstDate();
1300  case tov_FieldPeas:
1301  return m_fieldpeas->GetFirstDate();
1302  case tov_FieldPeasSilage:
1303  return m_fieldpeassilage->GetFirstDate();
1304  case tov_FodderBeet:
1305  return m_fodderbeet->GetFirstDate();
1306  case tov_SugarBeet:
1307  return m_sugarbeet->GetFirstDate();
1308  case tov_OFodderBeet:
1309  return m_ofodderbeet->GetFirstDate();
1310  case tov_Maize:
1311  return m_maize->GetFirstDate();
1312  case tov_OMaizeSilage:
1313  return m_omaizesilage->GetFirstDate();
1314  case tov_MaizeSilage:
1315  return m_maizesilage->GetFirstDate();
1317  return m_OBarleyPCG->GetFirstDate();
1318  case tov_OCarrots:
1319  return m_ocarrots->GetFirstDate();
1321  return m_OCGG1->GetFirstDate();
1323  return m_OCGG2->GetFirstDate();
1325  return m_OCGS1->GetFirstDate();
1326  case tov_OFieldPeas:
1327  return m_ofieldpeas->GetFirstDate();
1328  case tov_OFirstYearDanger:
1329  return m_ofirstyeardanger->GetFirstDate();
1330  case tov_OGrazingPigs:
1331  return m_ograzingpigs->GetFirstDate();
1332  case tov_OrchardCrop:
1333  return m_orchardcrop->GetFirstDate();
1334  case tov_OOats:
1335  return m_ooats->GetFirstDate();
1336  case tov_Oats:
1337  return m_oats->GetFirstDate();
1339  return m_opermgrassgrazed->GetFirstDate();
1340  case tov_OPotatoes:
1341  return m_opotatoes->GetFirstDate();
1342  case tov_OSpringBarley:
1343  return m_ospringbarley->GetFirstDate();
1344  case tov_OSBarleySilage:
1345  return m_osbarleysilage->GetFirstDate();
1346  case tov_OSpringBarleyExt:
1347  return m_ospringbarleyext->GetFirstDate();
1348  case tov_OSpringBarleyPigs:
1349  return m_ospringbarleypigs->GetFirstDate();
1350  case tov_OWinterBarley:
1351  return m_owinterbarley->GetFirstDate();
1352  case tov_OWinterBarleyExt:
1353  return m_owinterbarleyext->GetFirstDate();
1354  case tov_OWinterRape:
1355  return m_owinterrape->GetFirstDate();
1356  case tov_OWinterRye:
1357  return m_owinterrye->GetFirstDate();
1359  return m_owinterwheatundersown->GetFirstDate();
1360  case tov_OWinterWheat:
1361  return m_owinterwheat->GetFirstDate();
1363  return m_owinterwheatundersownext->GetFirstDate();
1365  return m_permgrassgrazed->GetFirstDate();
1367  return m_permgrasslowyield->GetFirstDate();
1368  case tov_PermanentGrassTussocky: // Only used for tole_PermPastureTussocky
1369  return m_permgrasstussocky->GetFirstDate();
1370  case tov_PermanentSetaside:
1371  return m_permanentsetaside->GetFirstDate();
1372  case tov_Potatoes:
1373  return m_potatoes->GetFirstDate();
1374  case tov_SeedGrass1:
1375  return m_seedgrass1->GetFirstDate();
1376  case tov_SeedGrass2:
1377  return m_seedgrass2->GetFirstDate();
1378  case tov_Setaside:
1379  return m_setaside->GetFirstDate();
1380  case tov_SpringBarley:
1381  return m_springbarley->GetFirstDate();
1382  case tov_SpringBarleySpr:
1383  return m_springbarleyspr->GetFirstDate();
1385  return m_springbarleyptreatment->GetFirstDate();
1387  return m_springbarleyskmanagement->GetFirstDate();
1389  return m_sbarleyclovergrass->GetFirstDate();
1390  case tov_SpringBarleySeed:
1391  return m_springbarleyseed->GetFirstDate();
1393  return m_springbarleysilage->GetFirstDate();
1395  return m_springbarleystrigling->GetFirstDate();
1397  return m_springbarleystriglingsingle->GetFirstDate();
1399  return m_springbarleystriglingculm->GetFirstDate();
1400  case tov_SpringRape:
1401  return m_springrape->GetFirstDate();
1402  case tov_Triticale:
1403  return m_triticale->GetFirstDate();
1404  case tov_OTriticale:
1405  return m_otriticale->GetFirstDate();
1406  case tov_WinterBarley:
1407  return m_winterbarley->GetFirstDate();
1408  case tov_WinterRape:
1409  return m_winterrape->GetFirstDate();
1410  case tov_WinterRye:
1411  return m_winterrye->GetFirstDate();
1412  case tov_WinterWheat:
1413  return m_winterwheat->GetFirstDate();
1415  return m_winterwheatstrigling->GetFirstDate();
1417  return m_winterwheatstriglingsingle->GetFirstDate();
1419  return m_winterwheatstriglingculm->GetFirstDate();
1420  case tov_WWheatPControl:
1421  return m_wwheatpcontrol->GetFirstDate();
1423  return m_wwheatptoxiccontrol->GetFirstDate();
1424  case tov_WWheatPTreatment:
1425  return m_wwheatptreatment->GetFirstDate();
1427  return m_agrochemindustrycereal->GetFirstDate();
1428  case tov_YoungForest:
1429  return m_youngforest->GetFirstDate();
1430  default:
1431  return 0;
1432  }
1433 }
1434 
1435 TTypesOfVegetation FarmManager::TranslateCropCodes( std::string& astr ) { //changed to farm manager - was a Farm function, 19.03.13
1436  // This simply checks through the list of legal crop names and returns
1437  // the correct tov type
1438 
1439  string str = astr;
1440 
1441  // Unfortunately switch cannot use string so the long way:
1442  if (str == "SpringBarley") return tov_SpringBarley;
1443  if (str == "SpringBarleySpr") return tov_SpringBarleySpr;
1444  if (str == "SpringBarleyPTreatment") return tov_SpringBarleyPTreatment;
1445  if (str == "WinterBarley") return tov_WinterBarley;
1446  if (str == "SpringWheat") return tov_SpringWheat;
1447  if (str == "WinterWheat") return tov_WinterWheat;
1448  if (str == "WinterRye") return tov_WinterRye;
1449  if (str == "OrchardCrop") return tov_OrchardCrop;
1450  if (str == "Oats") return tov_Oats;
1451  if (str == "OOats") return tov_OOats;
1452  if (str == "Triticale") return tov_Triticale;
1453  if (str == "OTriticale") return tov_OTriticale;
1454  if (str == "Maize") return tov_Maize;
1455  if (str == "MaizeSilage") return tov_MaizeSilage;
1456  if (str == "SpringBarleySeed") return tov_SpringBarleySeed;
1457  if (str == "OSpringRape") return tov_SpringRape;
1458  if (str == "SpringRape") return tov_SpringRape;
1459  if (str == "WinterRape") return tov_WinterRape;
1460  if (str == "BroadBeans") return tov_BroadBeans;
1461  if (str == "FieldPeas") return tov_FieldPeas;
1462  if (str == "FieldPeasSilage") return tov_FieldPeasSilage;
1463  if (str == "Setaside") return tov_Setaside;
1464  if (str == "PermanentSetaside") return tov_PermanentSetaside;
1465  if (str == "SugarBeet") return tov_SugarBeet;
1466  if (str == "FodderBeet") return tov_FodderBeet;
1467  if (str == "OFodderBeet") return tov_OFodderBeet;
1468  if (str == "FodderGrass") return tov_FodderGrass;
1469  if (str == "CloverGrassGrazed1") return tov_CloverGrassGrazed1;
1470  if (str == "PotatoesIndustry") return tov_PotatoesIndustry;
1471  if (str == "Potatoes") return tov_Potatoes;
1472  if (str == "SeedGrass1") return tov_SeedGrass1;
1473  if (str == "OWinterBarley") return tov_OWinterBarley;
1474  if (str == "OWinterBarleyExt") return tov_OWinterBarleyExt;
1475  if (str == "SpringBarleySilage") return tov_SpringBarleySilage;
1476  if (str == "OWinterRye") return tov_OWinterRye;
1477  if (str == "OFieldPeasSilage") return tov_OFieldPeasSilage;
1478  if (str == "SpringBarleyGrass") return tov_SpringBarleyGrass;
1479  if (str == "SpringBarleyCloverGrass") return tov_SpringBarleyCloverGrass;
1480  if (str == "OBarleyPeaCloverGrass") return tov_OBarleyPeaCloverGrass;
1481  if (str == "OWinterRape") return tov_OWinterRape;
1482  if (str == "PermanentGrassGrazed") return tov_PermanentGrassGrazed;
1483  if (str == "PermanentGrassLowYield") return tov_PermanentGrassLowYield;
1484  if (str == "PermanentGrassTussocky") return tov_PermanentGrassTussocky;
1485  if (str == "CloverGrassGrazed2") return tov_CloverGrassGrazed2;
1486  if (str == "SeedGrass2") return tov_SeedGrass2;
1487  if (str == "OSpringWheat") return tov_OSpringBarley;
1488  if (str == "OSpringBarley") return tov_OSpringBarley;
1489  if (str == "OSpringBarleyExt") return tov_OSpringBarleyExt;
1490  if (str == "OWinterWheat") return tov_OWinterWheat;
1491  if (str == "OWinterWheatUndersown") return tov_OWinterWheatUndersown;
1492  if (str == "OWinterWheatUndersownExt") return tov_OWinterWheatUndersownExt;
1493  if (str == "OOats") return tov_OOats;
1494  if (str == "OFieldPeas") return tov_OFieldPeas;
1495  if (str == "OCloverGrassGrazed1") return tov_OCloverGrassGrazed1;
1496  if (str == "OGrazingPigs") return tov_OGrazingPigs;
1497  if (str == "OCarrots") return tov_OCarrots;
1498  if (str == "Carrots") return tov_Carrots;
1499  if (str == "OPotatoes") return tov_OPotatoes;
1500  if (str == "OSeedGrass1") return tov_OSeedGrass1;
1501  if (str == "OSpringBarleyGrass") return tov_OSpringBarleyGrass;
1502  if (str == "OSpringBarleyClover") return tov_OSpringBarleyClover;
1503  if (str == "OPermanentGrassGrazed") return tov_OPermanentGrassGrazed;
1504  if (str == "OCloverGrassSilage1") return tov_OCloverGrassSilage1;
1505  if (str == "OCloverGrassGrazed2") return tov_OCloverGrassGrazed2;
1506  if (str == "OSeedGrass2") return tov_OSeedGrass2;
1507  if (str == "WWheatPControl") return tov_WWheatPControl;
1508  if (str == "WWheatPToxicControl") return tov_WWheatPToxicControl;
1509  if (str == "WWheatPTreatment") return tov_WWheatPTreatment;
1510  if (str == "AgroChemIndustryCereal") return tov_AgroChemIndustryCereal;
1511  if (str == "WinterWheatShort") return tov_WinterWheatShort;
1512  if (str == "WinterWheatStrigling") return tov_WinterWheatStrigling;
1513  if (str == "WinterWheatStriglingCulm") return tov_WinterWheatStriglingCulm;
1514  if (str == "WinterWheatStriglingSgl") return tov_WinterWheatStriglingSingle;
1515  if (str == "SpringBarleyCloverGrassStrigling") return tov_SpringBarleyCloverGrassStrigling;
1516  if (str == "SpringBarleyStrigling") return tov_SpringBarleyStrigling;
1517  if (str == "SpringBarleyStriglingSingle") return tov_SpringBarleyStriglingSingle;
1518  if (str == "SpringBarleyStriglingCulm") return tov_SpringBarleyStriglingCulm;
1519  if (str == "MaizeStrigling") return tov_MaizeStrigling;
1520  if (str == "WinterRapeStrigling") return tov_WinterRapeStrigling;
1521  if (str == "WinterRyeStrigling") return tov_WinterRyeStrigling;
1522  if (str == "WinterBarleyStrigling") return tov_WinterBarleyStrigling;
1523  if (str == "FieldPeasStrigling") return tov_FieldPeasStrigling;
1524  if (str == "SpringBarleyPeaCloverGrassStrigling") return tov_SpringBarleyPeaCloverGrassStrigling;
1525  if (str == "YoungForest") return tov_YoungForest;
1526  if (str == "OMaizeSilage") return tov_OMaizeSilage;
1527  if (str == "OSpringBarleySilage") return tov_OSBarleySilage;
1528  if (str == "OSpringBarleyPigs") return tov_OSpringBarleyPigs;
1529 
1530  // No match so issue a warning and quit
1531  g_msg->Warn( WARN_FILE, "FarmManager::TranslateCropCodes():"" Unknown Crop Code ", str.c_str() );
1532  exit( 1 );
1533 }
1534 
1535 
1537 
1538  //create a text file with the farms
1539  ofstream ofile ("FarmTotalAreas_almass.txt", ios::out);
1540  ofile << "Farm no" << '\t' << "Area" << endl;
1541 
1542  //print each farms no and then the numbers of its neighbours
1543  for(int i=0; i<(int)m_farms.size(); i++){
1544  OptimisingFarm * opf_i;
1545  if(m_farms[i]->GetType() == tof_OptimisingFarm){ //take only optimising farms
1546  opf_i = dynamic_cast<OptimisingFarm*>(m_farms[i]);
1547  ofile << opf_i->Get_almass_no() << '\t';
1548  ofile << opf_i->GetArea() <<'\t';
1549  ofile << endl;
1550  }
1551  }
1552 }
1553 
1555 {
1557  m_stockfarmer = true;
1558  // Adjust as needed.
1559  m_rotation.resize( 9 );
1563  m_rotation[ 3 ] = tov_WinterWheat;
1567  m_rotation[ 7 ] = tov_Maize; // was FodderBeet until 23/12/03
1569 }
1570 
1571 
1573 {
1575  m_stockfarmer = true;
1576 
1577  // Adjust as needed.
1578  m_rotation.resize( 9 );
1579  m_rotation[ 0 ] = tov_WinterRape;
1580  m_rotation[ 1 ] = tov_WinterWheat;
1583  m_rotation[ 4 ] = tov_Setaside;
1584  m_rotation[ 5 ] = tov_FieldPeas;
1585  m_rotation[ 6 ] = tov_WinterWheat;
1586  m_rotation[ 7 ] = tov_WinterRye;
1588 }
1589 
1590 
1592 {
1594  m_stockfarmer = false;
1595 
1596  // Adjust as needed.
1597  m_rotation.resize( 9 );
1598  m_rotation[ 0 ] = tov_WinterRape;
1599  m_rotation[ 1 ] = tov_WinterWheat;
1602  m_rotation[ 4 ] = tov_Setaside;
1603  m_rotation[ 5 ] = tov_FieldPeas;
1604  m_rotation[ 6 ] = tov_WinterWheat;
1605  m_rotation[ 7 ] = tov_WinterRye;
1607 }
1608 
1609 
1610 OrganicCattle::OrganicCattle(FarmManager* a_manager) : Farm(a_manager) // 3
1611 {
1613  m_stockfarmer = true;
1614  ReadRotation("OrganicCattle.rot");
1615  }
1616 
1617 OrganicPig::OrganicPig(FarmManager* a_manager) : Farm(a_manager) // 4
1618 {
1620  m_stockfarmer = true;
1621  ReadRotation("OrganicPig.rot");
1622 }
1623 
1624 OrganicPlant::OrganicPlant(FarmManager* a_manager) : Farm(a_manager) // 5
1625 {
1627  m_stockfarmer = false;
1628  ReadRotation("OrganicPlant.rot");
1629 }
1630 
1632 {
1634  m_stockfarmer = false;
1635  m_rotation.resize( 1 );
1637 }
1638 
1640 {
1642  m_stockfarmer = false;
1643  m_rotation.resize( 1 );
1645 }
1646 
1648 {
1650  m_stockfarmer = false;
1651  // This farm type reads its rotation from a special file PesticideTrialTreatment.rot
1652  ReadRotation("PesticideTrialTreatment.rot");
1653 }
1654 
1656 {
1658  m_stockfarmer = true;
1659 
1660  m_rotation.resize( 6 );
1666  m_rotation[ 5 ] = tov_FodderBeet;
1667 }
1668 
1670 {
1672  m_stockfarmer = true;
1673  // Adjust as needed.
1674  m_rotation.resize( 9 );
1681  m_rotation[ 6 ] = tov_FodderBeet;
1684 }
1685 
1687 {
1689  m_stockfarmer = true;
1690 
1691  // Adjust as needed.
1692  m_rotation.resize( 3 );
1693  m_rotation[ 0 ] = tov_WinterRape;
1696  /* m_rotation[ 3] = tov_AgroChemIndustryCereal; m_rotation[ 4] = tov_Setaside; m_rotation[ 5] = tov_FieldPeas;
1697  m_rotation[ 6] = tov_AgroChemIndustryCereal; m_rotation[ 7] = tov_WinterRye; m_rotation[ 8] = tov_AgroChemIndustryCereal; */
1698 }
1699 
1700 
1701 
1703 {
1705  m_stockfarmer = false;
1706 
1707  // Adjust as needed.
1708  m_rotation.resize( 9 );
1709  m_rotation[ 0 ] = tov_Setaside;
1710  m_rotation[ 1 ] = tov_FieldPeas;
1712  m_rotation[ 3 ] = tov_WinterRye;
1714  m_rotation[ 5 ] = tov_WinterRape;
1718 }
1719 
1721 {
1723  m_stockfarmer = false;
1724 
1725  // Adjust as needed.
1726  m_rotation.resize( 36 );
1730  m_rotation[ 3 ] = tov_WinterWheat;
1734  m_rotation[ 7 ] = tov_FodderBeet;
1736  m_rotation[ 9 ] = tov_WinterRape;
1737  m_rotation[ 10 ] = tov_WinterWheat;
1738  m_rotation[ 11 ] = tov_SpringBarley;
1739  m_rotation[ 12 ] = tov_SpringBarley;
1740  m_rotation[ 13 ] = tov_Setaside;
1741  m_rotation[ 14 ] = tov_FieldPeas;
1742  m_rotation[ 15 ] = tov_WinterWheat;
1743  m_rotation[ 16 ] = tov_WinterRye;
1744  m_rotation[ 17 ] = tov_WinterBarley;
1745  m_rotation[ 18 ] = tov_WinterRape;
1746  m_rotation[ 19 ] = tov_WinterWheat;
1747  m_rotation[ 20 ] = tov_SpringBarley;
1748  m_rotation[ 21 ] = tov_SpringBarley;
1749  m_rotation[ 22 ] = tov_Setaside;
1750  m_rotation[ 23 ] = tov_FieldPeas;
1751  m_rotation[ 24 ] = tov_WinterWheat;
1752  m_rotation[ 25 ] = tov_WinterRye;
1753  m_rotation[ 26 ] = tov_WinterBarley;
1754  m_rotation[ 27 ] = tov_WinterRape;
1755  m_rotation[ 28 ] = tov_WinterWheat;
1756  m_rotation[ 29 ] = tov_SpringBarley;
1757  m_rotation[ 30 ] = tov_SpringBarley;
1758  m_rotation[ 31 ] = tov_Setaside;
1759  m_rotation[ 32 ] = tov_FieldPeas;
1760  m_rotation[ 33 ] = tov_WinterWheat;
1761  m_rotation[ 34 ] = tov_WinterRye;
1762  m_rotation[ 35 ] = tov_WinterBarley;
1763 }
1764 
1766 {
1768  m_stockfarmer = false;
1769 
1770  // Adjust as needed.
1771  m_rotation.resize( 17 );
1775  m_rotation[ 3 ] = tov_OWinterRape;
1776  m_rotation[ 4 ] = tov_OFieldPeas;
1782  m_rotation[ 10 ] = tov_OFieldPeas;
1785  m_rotation[ 13 ] = tov_Setaside;
1786  m_rotation[ 14 ] = tov_OFieldPeas;
1787  m_rotation[ 15 ] = tov_OWinterRye;
1788  m_rotation[ 16 ] = tov_OFieldPeas;
1789 }
1790 
1791 
1792 UserDefinedFarm1::UserDefinedFarm1(FarmManager* a_manager ) : Farm(a_manager) // 15
1793 {
1795  m_stockfarmer = true;
1796  // This farm type reads its rotation from a special file UserDefinedFarm1.rot
1797  ReadRotation("UserDefinedFarm1.rot");
1798  }
1799 
1800 UserDefinedFarm2::UserDefinedFarm2(FarmManager* a_manager ) : Farm(a_manager) // 15
1801 {
1803  m_stockfarmer = true;
1804  // This farm type reads its rotation from a special file UserDefinedFarm1.rot
1805  ReadRotation("UserDefinedFarm2.rot");
1806  }
1807 
1808 UserDefinedFarm3::UserDefinedFarm3(FarmManager* a_manager ) : Farm(a_manager) // 17
1809 {
1811  m_stockfarmer = true;
1812  // This farm type reads its rotation from a special file PesticideTrialTreatment.rot
1813  ReadRotation("UserDefinedFarm3.rot");
1814 }
1815 
1816 UserDefinedFarm4::UserDefinedFarm4(FarmManager* a_manager ) : Farm(a_manager) // 18
1817 {
1819  m_stockfarmer = true;
1820  // This farm type reads its rotation from a special file PesticideTrialTreatment.rot
1821  ReadRotation("UserDefinedFarm4.rot");
1822  }
1823 
1824 UserDefinedFarm5::UserDefinedFarm5(FarmManager* a_manager ) : Farm(a_manager) // 19
1825 {
1827  m_stockfarmer = true;
1828  // This farm type reads its rotation from a special file PesticideTrialTreatment.rot
1829  ReadRotation("UserDefinedFarm5.rot");
1830 }
1831 
1832 UserDefinedFarm6::UserDefinedFarm6(FarmManager* a_manager ) : Farm(a_manager) // 20
1833 {
1835  m_stockfarmer = true;
1836  // This farm type reads its rotation from a special file PesticideTrialTreatment.rot
1837  ReadRotation("UserDefinedFarm6.rot");
1838 }
1839 
1840 UserDefinedFarm7::UserDefinedFarm7(FarmManager* a_manager ) : Farm(a_manager) // 21
1841 {
1843  m_stockfarmer = true;
1844  // This farm type reads its rotation from a special file PesticideTrialTreatment.rot
1845  ReadRotation("UserDefinedFarm7.rot");
1846 }
1847 
1848 UserDefinedFarm8::UserDefinedFarm8(FarmManager* a_manager ) : Farm(a_manager) // 22
1849 {
1851  m_stockfarmer = true;
1852  // This farm type reads its rotation from a special file PesticideTrialTreatment.rot
1853  ReadRotation("UserDefinedFarm8.rot");
1854 }
1855 
1856 UserDefinedFarm9::UserDefinedFarm9(FarmManager* a_manager ) : Farm(a_manager) // 23
1857 {
1859  m_stockfarmer = false;
1860  // This farm type reads its rotation from a special file PesticideTrialTreatment.rot
1861  ReadRotation("UserDefinedFarm9.rot");
1862 }
1863 
1865 {
1867  m_stockfarmer = false;
1868  ReadRotation("UserDefinedFarm10.rot");
1869 }
1870 
1872 {
1874  m_stockfarmer = false;
1875  ReadRotation("UserDefinedFarm11.rot");
1876 }
1877 
1879 {
1881  m_stockfarmer = false;
1882  ReadRotation("UserDefinedFarm12.rot");
1883 }
1884 
1886 {
1888  m_stockfarmer = false;
1889  ReadRotation("UserDefinedFarm13.rot");
1890 }
1891 
1893 {
1895  m_stockfarmer = true;
1896  ReadRotation("UserDefinedFarm14.rot");
1897 }
1898 
1900 {
1902  m_stockfarmer = false;
1903  ReadRotation("UserDefinedFarm15.rot");
1904 }
1905 
1907 {
1909  m_stockfarmer = false;
1910  ReadRotation("UserDefinedFarm16.rot");
1911 }
1912 
1913 
1915 {
1917  m_stockfarmer = false;
1918  ReadRotation("UserDefinedFarm17.rot");
1919 }
1920 
1921 UserDefinedFarm::UserDefinedFarm( const char* fname, FarmManager* a_manager ) : Farm(a_manager) // Base class for the real ones
1922 {
1933  ifstream ifile;
1934  ifile.open(fname,ios::in);
1935  if (!ifile.is_open()) {
1936  g_msg->Warn( WARN_FILE, " Unable to open file ", fname );
1937  exit( 1 );
1938  }
1939  int input, intensity;
1940  // First entry - arable/stock
1941  // Second entry - farm intensity. Zero = default, 1 extensive, 2 very extensive
1942  ifile >> input >> intensity;
1943  if (input==1) m_stockfarmer = true; else m_stockfarmer = false;
1944  // Thrid entry - no permanent crops
1945  int permcrops;
1946  std::string cropref ="";
1947  ifile >> permcrops;
1948  // The problem here is that at the time when we reach this code there are no fields attached to the farm - so we need
1949  // to store this information - hence the vector of the vector of PermCropData
1950  PermCropData pcd;
1951  for (int i=0; i<permcrops; i++) {
1952  int pct;
1953  ifile >> cropref;
1954  TTypesOfVegetation tov = g_farmmanager->TranslateCropCodes( cropref );
1955  ifile >> pct; // 0-100%
1956  pcd.Pct=pct;
1957  pcd.Tov=tov;
1958  m_PermCrops.push_back(pcd);
1959  }
1960  // 4th entry
1961  int nocrops;
1962  ifile >> nocrops;
1963  m_rotation.resize( nocrops );
1964  for ( int i = 0; i < nocrops; i++ ) {
1965  ifile >> cropref;
1966  TTypesOfVegetation tov = g_farmmanager->TranslateCropCodes( cropref );
1967  m_rotation[ i ] = tov;
1968  }
1969  ifile.close();
1970 }
1971 
1974  // Assumes that m_fields has all the fields already in it, and those that are occupied by permanent tole types
1975  // are denoted by -2 or -4 in rotindex, -1 is unassigned - can't use enum because positive values have other meanings
1976  // First get the areas of all fields and then convert these to percentages
1977  tpct a_tpct;
1978  vector<LE*> fields_cpy;
1979  fields_cpy.resize(m_fields.size());
1980  copy(m_fields.begin(), m_fields.end(), fields_cpy.begin());
1981  vector<tpct> pcts;
1982  double area = 0.0;
1983  int sz = (int) fields_cpy.size();
1984  for (int i=sz-1; i>=0; i--) {
1985  if ( fields_cpy[i]->GetRotIndex()<-1) {
1986  if (fields_cpy[i]->GetRotIndex()==-4) area += fields_cpy[i]->GetArea();
1987  fields_cpy.erase(fields_cpy.begin()+i);
1988  }
1989  else area += fields_cpy[i]->GetArea();
1990  }
1991  // Here we can take action if we only have a single field (could extend this if it was thought worth it)
1992  int fnos = (int) fields_cpy.size();
1993  if (fnos<1) return; // No fields to allocate, jump out
1994  else if (fnos<2) {
1995  // Use the pct as the chance that our single field is assigned
1996  if (random(100)>=pct) return;
1997  else {
1998  // Add field by default
1999  fields_cpy[0]->SetRotIndex(-4);
2000  // Assign the crop
2001  fields_cpy[0]->SetVegType(tov, tov_Undefined);
2002  return;
2003  }
2004  }
2005  for (int i=0; i<fnos; i++) {
2006  a_tpct.pct = (int) floor(0.5+((fields_cpy[i]->GetArea()/area)*100));
2007  a_tpct.index = i;
2008  pcts.push_back(a_tpct);
2009  }
2010  // We need to look for combinations of fields that are close to our target.
2011  // First we can sort the array and ignore any that are greater than pct
2012  sort (pcts.begin(), pcts.end(), CompPcts); // results in ordering on increasing pct
2013  // now remove all those with pct>target+10% to save loads of time in the inverse integer partition
2014  int index=-1;
2015  int ind=0;
2016  int apct=pct+10; // Lets assume we have a tolerance of 10%
2017  while ((index==-1) && (ind< (int)pcts.size())) {
2018  if (pcts[ind++].pct>apct) index=ind;
2019  }
2020  if (index!=-1) pcts.erase(pcts.begin()+index,pcts.end());
2021  // Now find the best combination of fields to get close to our target & set them
2022  int bits = InvIntPartition(&pcts,pct);
2023  int mask=1;
2024  ind = 0;
2025  int used=0;
2026  //double pctused = 0.0;
2027  double check = 0.0;
2028  for (int h=0; h< (int)pcts.size(); h++) check+=fields_cpy[pcts[h].index]->GetArea();
2029  while (bits>0) {
2030  if ((bits & mask) > 0) {
2031  // Set the field as non-rotating
2032  fields_cpy[pcts[ind].index]->SetRotIndex(-4);
2033  // Assign the crop
2034  fields_cpy[pcts[ind].index]->SetVegType(tov, tov_Undefined);
2035  used += (int) fields_cpy[pcts[ind].index]->GetArea();
2036  //pctused = used/area;
2037  bits -= mask;
2038  }
2039  mask = mask << 1;
2040  ind++;
2041  }
2042 }
2043 
2045 int Farm::InvIntPartition(vector<tpct>* items, int target){
2046  //Figure out how many bitmasks we need...
2047  //4 bits have a maximum value of 15, so we need 15 masks.
2048  //Calculated as:
2049  // (2 ^ ItemCount) - 1
2050  int sz = (int) items->size();
2051  if (sz>63) {
2052  g_msg->Warn("Too many potential fields in UserDefinedFarm::InvIntPartition: ",sz);
2053  g_msg->Warn("Farm Number: ",GetFarmNumber());
2054  exit(1);
2055  }
2056  long int calcs = (1 << sz);
2057  //Spit out the corresponding calculation for each bitmask
2058  int sum;
2059  int found = 0;
2060  int diff = 100;
2061  for (long int i=1; i<calcs; i++) {
2062  //Get the items from our array that correspond to
2063  //the on bits in our mask
2064  sum = 0;
2065  int mask = 1;
2066  for (int bit=0; bit<sz; bit++) {
2067  if ((i & mask) > 0) {
2068  sum+=(*items)[bit].pct;
2069  }
2070  mask = mask << 1;
2071  }
2072 
2073  if (abs(sum-target) < diff ){
2074  found = i;
2075  diff = abs(sum-target);
2076  if (diff<1) break; //added 01.11.12 to prevent from checking all the combinations when the right one is found
2077  }
2078  }
2079  return found;
2080 }
2081 
2082 UserDefinedFarm18::UserDefinedFarm18( const char* fname, FarmManager* a_manager ) : UserDefinedFarm(fname, a_manager) // 32
2083 {
2085 }
2086 
2087 UserDefinedFarm19::UserDefinedFarm19( const char* fname, FarmManager* a_manager ) : UserDefinedFarm(fname, a_manager) // 33
2088 {
2090 }
2091 
2092 UserDefinedFarm20::UserDefinedFarm20( const char* fname, FarmManager* a_manager ) : UserDefinedFarm(fname, a_manager) // 34
2093 {
2095 }
2096 
2097 UserDefinedFarm21::UserDefinedFarm21( const char* fname, FarmManager* a_manager ) : UserDefinedFarm(fname, a_manager) // 35
2098 {
2100 }
2101 
2102 UserDefinedFarm22::UserDefinedFarm22( const char* fname, FarmManager* a_manager ) : UserDefinedFarm(fname, a_manager) // 36
2103 {
2105 }
2106 
2107 UserDefinedFarm23::UserDefinedFarm23( const char* fname, FarmManager* a_manager ) : UserDefinedFarm(fname, a_manager) // 37
2108 {
2110 }
2111 
2112 UserDefinedFarm24::UserDefinedFarm24( const char* fname, FarmManager* a_manager ) : UserDefinedFarm(fname, a_manager) // 38
2113 {
2115 }
2116 
2117 UserDefinedFarm25::UserDefinedFarm25( const char* fname, FarmManager* a_manager ) : UserDefinedFarm(fname, a_manager) // 39
2118 {
2120 }
2121 
2122 UserDefinedFarm26::UserDefinedFarm26( const char* fname, FarmManager* a_manager ) : UserDefinedFarm(fname, a_manager) // 40
2123 {
2125 }
2126 
2127 UserDefinedFarm27::UserDefinedFarm27( const char* fname, FarmManager* a_manager ) : UserDefinedFarm(fname, a_manager) // 41
2128 {
2130 }
2131 
2132 UserDefinedFarm28::UserDefinedFarm28( const char* fname, FarmManager* a_manager ) : UserDefinedFarm(fname, a_manager) // 42
2133 {
2135 }
2136 
2137 UserDefinedFarm29::UserDefinedFarm29( const char* fname, FarmManager* a_manager ) : UserDefinedFarm(fname, a_manager) // 43
2138 {
2140 }
2141 
2142 UserDefinedFarm30::UserDefinedFarm30( const char* fname, FarmManager* a_manager ) : UserDefinedFarm(fname, a_manager) // 44
2143 {
2145 }
2146 
2147 UserDefinedFarm31::UserDefinedFarm31( const char* fname, FarmManager* a_manager ) : UserDefinedFarm(fname, a_manager) // 45
2148 {
2150 }
2151 
2152 UserDefinedFarm32::UserDefinedFarm32( const char* fname, FarmManager* a_manager ) : UserDefinedFarm(fname, a_manager) // 46
2153 {
2155 }
2156 
2157 UserDefinedFarm33::UserDefinedFarm33( const char* fname, FarmManager* a_manager ) : UserDefinedFarm(fname, a_manager) // 47
2158 {
2160 }
2161 
2162 UserDefinedFarm34::UserDefinedFarm34( const char* fname, FarmManager* a_manager ) : UserDefinedFarm(fname, a_manager) // 48
2163 {
2165 }
2166 
2167 UserDefinedFarm35::UserDefinedFarm35( const char* fname, FarmManager* a_manager ) : UserDefinedFarm(fname, a_manager) // 49
2168 {
2170 }
2171 
2172 
2173 //--------------------------------------------------------------------------------------------
2174 //--------------------------------------------------------------------------------------------
2175 //--------------------------------------------------------------------------------------------
2176 
2178 {
2179 
2180  g_farmmanager = this;
2181 
2182  if ( l_map_read_farmfile.value() ) {
2183  if (cfg_OptimisingFarms.value()){
2184  //make a data object
2185  pm_data=new DataForOptimisation;
2186  ReadFarmsData();
2187  ReadLivestockNumbers();
2188  ReadFarmsData_perFarmType();
2189  ReadLivestockData();
2190  //ReadGlobalData();
2191  ReadLookupTable();
2192  ofstream ofile ("Economic_figures.txt", ios::out);
2193  ofile.close();
2194  ofstream ofile1 ("Daydegrees.txt", ios::out);
2195  ofile1.close();
2196  if(cfg_MaizeEnergy.value()){
2197  ofstream ofileEM ("Maize_energy_price_yearly.txt", ios::out);
2198  ofileEM.close();
2199  }
2200 
2202  ReadInitialCropAreas();
2203  ReadCropsData();
2204  ReadCropsData_perSoilType();
2205  ReadCropsData_perFarmType();
2206  ReadCropsData_perFarm_and_Soil();
2207  ReadCropsData_perFarm_and_Soil_and_Size();
2208  }
2209  else{
2210  ReadInitialCropAreas_almass();
2211  ReadCropsData_almass();
2212  ReadCropsData_perSoilType_almass();
2213  ReadCropsData_perFarmType_almass();
2214  ReadCropsData_perFarm_and_Soil_almass();
2215  ReadCropsData_perFarm_and_Soil_and_Size_almass();
2216  m_crops_summary_BIs.resize(pm_data->Get_noCrops()); //no_crops - from the input file on initial crop areas
2217  m_cropTotals_sum.resize(pm_data->Get_noCrops());
2218  m_cropTotals_plant_sum.resize(pm_data->Get_noCrops());
2219  m_cropTotals_pig_sum.resize(pm_data->Get_noCrops());
2220  m_cropTotals_cattle_sum.resize(pm_data->Get_noCrops());
2221  m_cropTotals_other_sum.resize(pm_data->Get_noCrops());
2222  m_crops_fertilizer.resize(pm_data->Get_noCrops());
2223  m_crops_fertilizer_trade.resize(pm_data->Get_noCrops());
2224  m_crop_areas_stages.resize( 2 * pm_data->Get_noCrops()); //use just the results of the baseline and original model
2225  for(int i=0; i<pm_data->Get_noCrops(); i++){
2226  m_crops_summary_BIs[i].Tov = pm_data->Get_cropTypes_almass(i);
2227  m_crops_summary_BIs[i].BI=0;
2228  m_crops_summary_BIs[i].BIherb=0;
2229  m_crops_summary_BIs[i].BIfi=0;
2230  m_cropTotals_sum[i]=0;
2231  m_cropTotals_plant_sum[i]=0;
2232  m_cropTotals_pig_sum[i]=0;
2233  m_cropTotals_cattle_sum[i]=0;
2234  m_cropTotals_other_sum[i]=0;
2235  m_crops_fertilizer[i]=0;
2236  m_crops_fertilizer_trade[i]=0;
2237  }
2238 
2239  if(cfg_MaizeEnergy.value()){
2240  ReadEnergyMaizePrice();
2241  }
2242  }
2243  }//if optimising farm
2244  CreateFarms( l_map_farmref_file.value() );
2245  }
2246 
2247 }
2248 
2249 
2251 {
2252 
2253  for ( unsigned int i = 0; i < m_farms.size(); i++ )
2254  delete m_farms[ i ];
2255  if (cfg_OptimisingFarms.value()) delete pm_data;
2256 }
2257 
2259 {
2260  for ( unsigned int i = 0; i < m_farms.size(); i++ )
2261  {
2262  m_farms[ i ]->Management();
2263  }
2264 
2265  //050214
2266  if(g_landscape_p->SupplyYearNumber()>0){
2267  if(g_landscape_p->SupplyDayInYear() == cfg_Animals_number_test_day.value()){ //check if this is the day we want to collect data on animal numbers
2268  for ( unsigned int i = 0; i < m_farms.size(); i++ )
2269  {
2270  OptimisingFarm * opf;
2271  if(m_farms[i]->GetType() == tof_OptimisingFarm){ //take only optimising farms
2272  opf = dynamic_cast<OptimisingFarm*>(m_farms[i]);
2273  if(cfg_AnimalsThreshold.value() > 0 && opf->Get_main_goal() == tofg_environment){ //take only environmentalists and check if we are in the feedback mode (no if the config is zero)
2274  int farm_ref = opf->GetFarmNumber();
2275  int animals_no = g_landscape_p->SupplyFarmAnimalCensus(farm_ref, cfg_LifeStage.value());
2276  opf->Set_animals_no(animals_no);
2277  }
2278  }
2279  }
2280  }
2281  }
2282 }
2283 
2285 {
2286  for ( unsigned int i = 0; i < m_farms.size(); i++ )
2287  {
2288  m_farms[ i ]->InitiateManagement();
2289  }
2290 }
2291 
2292 void FarmManager::AddField(int a_OwnerIndex, LE* a_newland, int a_Owner)
2293 {
2294  m_farms[ a_OwnerIndex ]->AddField( a_newland );
2295  a_newland->SetOwner( m_farms[ a_OwnerIndex ], a_Owner, a_OwnerIndex );
2296 }
2297 
2298 void FarmManager::RemoveField(int a_OwnerIndex, LE* a_field)
2299 {
2300  m_farms[ a_OwnerIndex ]->RemoveField( a_field );
2301 }
2302 
2303 int FarmManager::ConnectFarm( int a_owner )
2304 {
2305  for ( unsigned int i = 0; i < m_farms.size(); i++ )
2306  {
2307  if ( a_owner == m_farms[ i ]->GetFarmNumber() )
2308  {
2309  // Found it. Set mapping and return.
2310  return i;
2311  }
2312  }
2313  // We didn't find the owner in the list of farms,
2314  // pregenerated in CreateFarms() above. Something
2315  // is not correct here, so raise an appropriate
2316  // error and exit.
2317  char error_num[ 20 ];
2318  sprintf( error_num, "%d", a_owner );
2319  g_msg->Warn( WARN_FILE, "FarmManager::ConnectFarm(): Unknown farm number"" referenced in polygon file:", error_num );
2320  exit( 1 );
2321 }
2322 
2323 void FarmManager::CreateFarms( const char * a_farmfile )
2324 {
2325  int No, FType, NoFarms;
2326  FILE * inpf = fopen(a_farmfile, "r" );
2327  if (!inpf) {
2328  g_msg->Warn( WARN_FILE, "Landscape::CreateFarms(): Unable to open file", a_farmfile );
2329  exit( 1 );
2330  }
2331 
2332  fscanf( inpf, "%d", & NoFarms );
2333 
2334  m_farms.resize( NoFarms );
2335 
2336  m_farmmapping_lookup = new int[NoFarms * 2];
2337 
2338  for (int i = 0; i < NoFarms; i++)
2339  {
2340  // File format:
2341  //
2342  // Two colunms of numbers 0..number of farms, 0-number of farmtypes-1
2343  // the second column determines what type of farm we have
2344  fscanf(inpf, "%d %d", &No, &FType);
2345  m_farmmapping_lookup[i * 2] = No;
2346  m_farmmapping_lookup[i * 2 + 1] = FType;
2347  }
2348  fclose(inpf);
2349 
2350  for (int i = 0; i < NoFarms; i++)
2351  {
2352  /*
2353  //If we are testing crop management, then ignore farm type from
2354  // the file and set to fixed one instead.
2355  if ( g_farm_test_crop.value() ) {
2356  FType = g_farm_test_crop_farmtype.value();
2357  }
2358  */
2359  // If we are running in fixed, sync'ed rotation mode, set all farms to
2360  // be of the requested type.
2363  }
2364 
2365  switch (m_farmmapping_lookup[i * 2 + 1]) // FType
2366  {
2367  case 0:
2368  m_farms[i] = new ConventionalCattle(this);
2369  break;
2370  case 1:
2371  m_farms[i] = new ConventionalPig(this);
2372  break;
2373  case 2:
2374  m_farms[i] = new ConventionalPlant(this);
2375  break;
2376  case 3:
2377  m_farms[i] = new OrganicCattle(this);
2378  break;
2379  case 4:
2380  m_farms[i] = new OrganicPig(this);
2381  break;
2382  case 5:
2383  m_farms[i] = new OrganicPlant(this);
2384  break;
2385  case 6:
2386  m_farms[i] = new PesticideTrialControl(this);
2387  break;
2388  case 7:
2389  m_farms[i] = new PesticideTrialToxicControl(this);
2390  break;
2391  case 8:
2392  m_farms[i] = new PesticideTrialTreatment(this);
2393  break;
2394  case 9:
2395  m_farms[i] = new ConvMarginalJord(this);
2396  break;
2397  case 10:
2398  m_farms[i] = new AgroChemIndustryCerealFarm1(this);
2399  break;
2400  case 11:
2401  m_farms[i] = new AgroChemIndustryCerealFarm2(this);
2402  break;
2403  case 12:
2404  m_farms[i] = new AgroChemIndustryCerealFarm3(this);
2405  break;
2406  case 13:
2407  m_farms[i] = new NoPesticideBaseFarm(this);
2408  break;
2409  case 14:
2410  m_farms[i] = new NoPesticideNoPFarm(this);
2411  break;
2412  case 15:
2413  m_farms[i] = new UserDefinedFarm1(this);
2414  break;
2415  case 16:
2416  m_farms[i] = new UserDefinedFarm2(this);
2417  break;
2418  case 17:
2419  m_farms[i] = new UserDefinedFarm3(this);
2420  break;
2421  case 18:
2422  m_farms[i] = new UserDefinedFarm4(this);
2423  break;
2424  case 19:
2425  m_farms[i] = new UserDefinedFarm5(this);
2426  break;
2427  case 20:
2428  m_farms[i] = new UserDefinedFarm6(this);
2429  break;
2430  case 21:
2431  m_farms[i] = new UserDefinedFarm7(this);
2432  break;
2433  case 22:
2434  m_farms[i] = new UserDefinedFarm8(this);
2435  break;
2436  case 23:
2437  m_farms[i] = new UserDefinedFarm9(this);
2438  break;
2439  case 24:
2440  m_farms[i] = new UserDefinedFarm10(this);
2441  break;
2442  case 25:
2443  m_farms[i] = new UserDefinedFarm11(this);
2444  break;
2445  case 26:
2446  m_farms[i] = new UserDefinedFarm12(this);
2447  break;
2448  case 27:
2449  m_farms[i] = new UserDefinedFarm13(this);
2450  break;
2451  case 28:
2452  m_farms[i] = new UserDefinedFarm14(this);
2453  break;
2454  case 29:
2455  m_farms[i] = new UserDefinedFarm15(this);
2456  break;
2457  case 30:
2458  m_farms[i] = new UserDefinedFarm16(this);
2459  break;
2460  case 31:
2461  m_farms[i] = new UserDefinedFarm17(this);
2462  break;
2463  // NB the user defing farms below require an extra parameter in the rotation file denoting the intensity (0 or 1 = high low)
2464  case 32:
2465  m_farms[i] = new UserDefinedFarm18("UserDefinedFarm18.rot", this);
2466  break;
2467  case 33:
2468  m_farms[i] = new UserDefinedFarm19("UserDefinedFarm19.rot", this);
2469  break;
2470  case 34:
2471  m_farms[i] = new UserDefinedFarm20("UserDefinedFarm20.rot", this);
2472  break;
2473  case 35:
2474  m_farms[i] = new UserDefinedFarm21("UserDefinedFarm21.rot", this);
2475  break;
2476  case 36:
2477  m_farms[i] = new UserDefinedFarm22("UserDefinedFarm22.rot", this);
2478  break;
2479  case 37:
2480  m_farms[i] = new UserDefinedFarm23("UserDefinedFarm23.rot", this);
2481  break;
2482  case 38:
2483  m_farms[i] = new UserDefinedFarm24("UserDefinedFarm24.rot", this);
2484  break;
2485  case 39:
2486  m_farms[i] = new UserDefinedFarm25("UserDefinedFarm25.rot", this);
2487  break;
2488  case 40:
2489  m_farms[i] = new UserDefinedFarm26("UserDefinedFarm26.rot", this);
2490  break;
2491  case 41:
2492  m_farms[i] = new UserDefinedFarm27("UserDefinedFarm27.rot", this);
2493  break;
2494  case 42:
2495  m_farms[i] = new UserDefinedFarm28("UserDefinedFarm28.rot", this);
2496  break;
2497  case 43:
2498  m_farms[i] = new UserDefinedFarm29("UserDefinedFarm29.rot", this);
2499  break;
2500  case 44:
2501  m_farms[i] = new UserDefinedFarm30("UserDefinedFarm30.rot", this);
2502  break;
2503  case 45:
2504  m_farms[i] = new UserDefinedFarm31("UserDefinedFarm31.rot", this);
2505  break;
2506  case 46:
2507  m_farms[i] = new UserDefinedFarm32("UserDefinedFarm32.rot", this);
2508  break;
2509  case 47:
2510  m_farms[i] = new UserDefinedFarm33("UserDefinedFarm33.rot", this);
2511  break;
2512  case 48:
2513  m_farms[i] = new UserDefinedFarm34("UserDefinedFarm34.rot", this);
2514  break;
2515  case 49:
2516  m_farms[i] = new UserDefinedFarm35("UserDefinedFarm35.rot", this);
2517  break;
2518  case 50: //optimising farm!
2519  if ((pm_data->Get_farmType(No)) == toof_Pig) {
2520  m_farms[i] = new OptimisingPigFarm(this, No);
2521  }
2522  else if ((pm_data->Get_farmType(No)) == toof_Cattle){
2523  m_farms[i] = new OptimisingCattleFarm(this, No);
2524  }
2525  else if ((pm_data->Get_farmType(No)) == toof_Plant){
2526  m_farms[i] = new OptimisingPlantFarm(this, No);
2527  }
2528  else if ((pm_data->Get_farmType(No)) == toof_Other){
2529  m_farms[i] = new OptimisingOtherFarm(this, No);
2530  }
2531  break;
2532 
2533  default:
2534  g_msg->Warn(WARN_FILE, "Landscape::CreateFarms(): Unknown farm ""type reference number", "");
2535  exit(1);
2536  }
2537  m_farms[i]->SetFarmNumber(i); // We use 'i' here because we renumber the farms internally. If the file did not come in this way then a dump file is created - tested in ReadPolys2
2538  }
2539 
2541  {
2542  DistributeFarmerTypes(); //added 240513
2543  }
2544 
2545  if (GetFarmNoLookup(NoFarms - 1) != NoFarms - 1) m_renumbered = false; else m_renumbered = true;
2546 }
2547 
2549 {
2550  ofstream opf("dump_farmrefs.txt");
2551  if (!opf.is_open())
2552  {
2553  g_msg->Warn(WARN_FILE, "Landscape::CreateFarms(): Unable to open file", "dump_farmrefs.txt");
2554  exit(1);
2555  }
2556  int NoFarms = (int) m_farms.size();
2557  opf << NoFarms << endl;
2558  for (int i = 0; i < NoFarms; i++)
2559  {
2560  opf << i << '\t' << m_farmmapping_lookup[i * 2 + 1] << endl;
2561  }
2562  opf.close();
2563 }
2564 
2566 
2567 
2569  Create_Output_file_for_farms(); //needed only for the OpitmisingFarms!
2570 }
2571 
2572 for(unsigned j=0; j<m_farms.size(); j++){
2573  if(m_farms[j]->GetType()==tof_OptimisingFarm){
2574  OptimisingFarm * opf = dynamic_cast<OptimisingFarm*>(m_farms[j]);
2575  opf->Init(pm_output_file);
2576  }
2577  }
2578 
2579 OptimisationOutput(); //03.05 - outputs of the optimisation
2580 
2581 }
2582 
2583 
2585 {
2586  /*
2587  * This data is grain distributions based on 2013 & 2014 data from cereal fields in Jutland
2588  */
2589  double graindist2013[26] = {
2590  29.59, 172.68, 60.59, 39.68, 51.02, 81.63, 268.71, 134.84, 57.40, 30.61, 204.08, 683.67, 108.04,
2591  141.29, 505.10, 444.61, 293.37, 355.18, 386.90, 381.83, 372.45, 377.55, 320.70, 392.46, 392.86, 435.17
2592  };
2593  double graindist2014[28] = {
2594  109.33, 382.65, 94.19, 765.31, 29.15, 70.15, 1096.94, 436.51, 309.21, 286.28, 480.44, 249.73, 784.10,
2595  688.78, 2035.45, 920.80, 341.61, 12.24, 113.38, 80.17, 178.57, 480.44, 0.00, 2.83, 1447.12, 1846.94, 1017.86, 477.74
2596  };
2597  if (m_SpilledGrain) return graindist2013[ (int)(g_rand_uni() * 28) ];
2598  else return graindist2014[ (int)(g_rand_uni() * 26) ];
2599 }
2600 
2602  /*
2603  * This data is maize distributions in kJ/m2 based on 2015 field data from maize fields in Jutland
2604  */
2605  double maizedist2015[ 9 ] = {
2606  102.7905327, 58.19878648, 85.65877728, 110.9055748, 30.65682555, 63.11699379, 59.05947276, 41.9277173, 95.57716202
2607  };
2608  return maizedist2015[ (int)(g_rand_uni() * 9) ];
2609 }
2610 
2611 bool FarmManager::InIllegalList( int a_farm_ref, vector<int> * a_farmlist ) {
2615  unsigned sz = (unsigned) a_farmlist->size();
2616  for (unsigned f = 0; f < sz; f++) {
2617  if ((*a_farmlist)[f] == a_farm_ref) return true;
2618  }
2619  return false;
2620 }
2621 
2622 void FarmManager::AddToIllegalList( int a_farm_ref, vector<int> * a_farmlist ) {
2626  bool found = false;
2627  unsigned sz = (unsigned)a_farmlist->size();
2628  for (unsigned f = 0; f < sz; f++) {
2629  if ((*a_farmlist)[f] == a_farm_ref) {
2630  found = true;
2631  break;
2632  }
2633  }
2634  if (!found) {
2635  a_farmlist->push_back( a_farm_ref );
2636  }
2637 }
2638 
2639 bool FarmManager::IsDuplicateRef(int a_ref, HunterInfo* a_hinfo)
2640 {
2641  for (int i = 0; i < int( a_hinfo->FarmHuntRef.size() ); i++)
2642  {
2643 
2644  if (a_ref == a_hinfo->FarmHuntRef[ i ]) return true;
2645  }
2646  return false;
2647 }
2648 
2649 int FarmManager::FindClosestFarm(HunterInfo a_hinfo, vector<int> * a_farmlist) {
2654  double best = 99999999999999999.0;
2655  int bestref = -1;
2656  double dist = best;
2657  for (unsigned i = 0; i < m_farms.size(); i++) {
2658  int fnum = m_farms[i]->GetFarmNumber();
2659  if (!InIllegalList(fnum, a_farmlist)) {
2660  if (!IsDuplicateRef(fnum, &a_hinfo)) {
2661  // Is possible to use this farm, so test it.
2662  APoint FPt = m_farms[i]->GetCentroids();
2663  dist = sqrt((double( FPt.m_x - a_hinfo.homeX ) * double( FPt.m_x - a_hinfo.homeX ) + double( FPt.m_y - a_hinfo.homeY ) * double( FPt.m_y - a_hinfo.homeY )));
2664  if (dist < best) {
2665  best = dist;
2666  bestref = fnum;
2667  }
2668  }
2669  }
2670  }
2671  if (bestref == -1) {
2672  g_msg->Warn( "FarmManager::FindClosestFarm - Cannot find open farm.", "" );
2673  exit( 0 );
2674  }
2675  return bestref;
2676 }
2677 
2678 int FarmManager::FindClosestFarmOpenness( HunterInfo a_hunterinfo, vector<int> * a_farmlist, int a_openness ) {
2679  // Centroid calculation on farms must be called before calling this method for the first time
2680  double best = 99999999999999999.0;
2681  int bestref = -1;
2682  double dist = best;
2683  for (unsigned i = 0; i < m_farms.size(); i++) {
2684  if (m_farms[ i ]->GetMaxOpenness() > a_openness) {
2685  int fref = m_farms[ i ]->GetFarmNumber();
2686  if (!InIllegalList( fref, a_farmlist )) {
2687  if (!IsDuplicateRef( fref, &a_hunterinfo )) {
2688  APoint FPt = m_farms[ i ]->GetCentroids();
2689  dist = sqrt( (double( FPt.m_x - a_hunterinfo.homeX ) * double( FPt.m_x - a_hunterinfo.homeX ) + double( FPt.m_y - a_hunterinfo.homeY ) * double( FPt.m_y - a_hunterinfo.homeY )) );
2690  if (dist < best) {
2691  best = dist;
2692  bestref = fref;
2693  }
2694  }
2695  }
2696  }
2697  }
2698  if (bestref == -1) {
2699  g_msg->Warn( "FarmManager::FindClosestFarmOpenness( ) - Cannot find open farm.", "" );
2700  exit( 0 );
2701  }
2702  return bestref;
2703 }
2704 
2705 int FarmManager::FindClosestFarmOpennessProb( HunterInfo a_hunterinfo, vector<int> * a_farmlist, int a_openness ) {
2714  typedef APoint AFarmDist;
2716  vector <AFarmDist> farmdists;
2718  struct FarmDistSort {
2719  bool operator()( AFarmDist a, AFarmDist b ) {
2720  return a.m_y < b.m_y;
2721  }
2722  };
2723  for (unsigned i = 0; i < m_farms.size(); i++) {
2724  int fnum = m_farms[ i ]->GetFarmNumber();
2725  if (!InIllegalList( fnum, a_farmlist )) {
2726  if (m_farms[ i ]->GetMaxOpenness() > a_openness) {
2727  if (!IsDuplicateRef( fnum, &a_hunterinfo )) {
2728  // Is possible to use this farm, so test it.
2729  APoint FPt = m_farms[ i ]->GetCentroids();
2730  int dist = int(sqrt( (double( FPt.m_x - a_hunterinfo.homeX ) * double( FPt.m_x - a_hunterinfo.homeX ) + double( FPt.m_y - a_hunterinfo.homeY ) * double( FPt.m_y - a_hunterinfo.homeY )) ));
2731  if (dist>40000) dist = 40000;
2732  AFarmDist fd( int( fnum ), dist );
2733  farmdists.push_back( fd );
2734  }
2735  }
2736  }
2737  }
2738  // By here we have a list of farms and their distances - now we have the option to sort it or randomise it - one or other line below should be commented out.
2739  // sort(farmdists.begin(), farmdists.end(), FarmDistSort()); // Sort
2740  random_shuffle( farmdists.begin(), farmdists.end() ); // Randomise
2741  // Now the vector is sorted/randomised we loop through and test probabilities
2742  for (int ch = 1; ch < 100000; ch++) // This loop just makes sure small chances don't mess up the run by tripping out early
2743  {
2744  int sz = int( farmdists.size() );
2745  for (int i = 0; i < sz; i++) {
2746  double chance = g_rand_uni();
2747  // Uses ch from the outer loop to scale probabilities - tripping out here will occur often for farms a long way from the area otherwise
2748  double calc = cfg_ClosestFarmProbParam2.value()* exp( (cfg_ClosestFarmProbParam1.value() / double( ch ))* farmdists[ i ].m_y );
2749  if (chance <= calc) return farmdists[ i ].m_x;
2750  }
2751  }
2752  g_msg->Warn( "FarmManager::FindClosestFarmProb", "- No suitable farm found" );
2753  exit( 0 );
2754 }
2755 
2756 int FarmManager::FindClosestFarmOpennessProbSmallIsBest( HunterInfo a_hunterinfo, vector<int> * a_farmlist, int a_openness, vector<int>* a_farmsizelist ) {
2765  typedef APoint AFarmDist;
2767  vector <AFarmDist> farmdists;
2769  struct FarmDistSort {
2770  bool operator()( AFarmDist a, AFarmDist b ) {
2771  return a.m_y < b.m_y;
2772  }
2773  };
2774  for (unsigned i = 0; i < m_farms.size(); i++) {
2775  int fnum = m_farms[ i ]->GetFarmNumber();
2776  if (!InIllegalList( fnum, a_farmlist )) {
2777  if (m_farms[ i ]->GetMaxOpenness() > a_openness) {
2778  if (!IsDuplicateRef( fnum, &a_hunterinfo )) {
2779  // Is possible to use this farm, so test it.
2780  APoint FPt = m_farms[ i ]->GetCentroids();
2781  int dist = int(sqrt( (double( FPt.m_x - a_hunterinfo.homeX ) * double( FPt.m_x - a_hunterinfo.homeX ) + double( FPt.m_y - a_hunterinfo.homeY ) * double( FPt.m_y - a_hunterinfo.homeY )) ));
2782  if (dist>40000) dist = 40000;
2783  AFarmDist fd( unsigned( fnum ), dist );
2784  farmdists.push_back( fd );
2785  }
2786  }
2787  }
2788  }
2789  // By here we have a list of farms and their distances - now we have the option to sort it or randomise it - one or other line below should be commented out.
2790  // sort(farmdists.begin(), farmdists.end(), FarmDistSort()); // Sort
2791  random_shuffle( farmdists.begin(), farmdists.end() ); // Randomise
2792  // Now the vector is sorted/randomised we loop through and test probabilities
2793  for (int ch = 1; ch < 100000; ch++) // This loop just makes sure small chances don't mess up the run by tripping out early
2794  {
2795  int sz = int( farmdists.size() );
2796  for (int i = 0; i < sz; i++) {
2797  double chance = g_rand_uni();
2798  // Uses ch from the outer loop to scale probabilities - tripping out here will occur often for farms a long way from the area otherwise
2799  double calc = cfg_ClosestFarmProbParam2.value()* exp( (cfg_ClosestFarmProbParam1.value() / double( ch ))* farmdists[ i ].m_y );
2800  if (chance <= calc) {
2801  // We passed the first test now take a second test based on farm size
2802  chance = g_rand_uni();
2803  calc = pow( double( (*a_farmsizelist)[ farmdists[ i ].m_x ] / 4000.0 ), cfg_FarmSizeProbParam1.value() );
2804  if (chance>calc) return farmdists[ i ].m_x;
2805  }
2806  }
2807  }
2808  g_msg->Warn( "FarmManager::FindClosestFarmProb", "- No suitable farm found" );
2809  exit( 0 );
2810 }
2811 
2812 int FarmManager::FindClosestFarmOpennessProbNearRoostIsBest( HunterInfo a_hunterinfo, vector<int> * a_farmlist, int a_openness, vector<APoint>* a_roostlist ) {
2821  typedef APoint AFarmDist;
2823  vector <AFarmDist> farmdists;
2825  struct FarmDistSort {
2826  bool operator()( AFarmDist a, AFarmDist b ) {
2827  return a.m_y < b.m_y;
2828  }
2829  };
2830  for (unsigned i = 0; i < m_farms.size(); i++) {
2831  int fnum = m_farms[ i ]->GetFarmNumber();
2832  if (!InIllegalList( fnum, a_farmlist )) {
2833  if (m_farms[ i ]->GetMaxOpenness() > a_openness) {
2834  if (!IsDuplicateRef( fnum, &a_hunterinfo )) {
2835  // Is possible to use this farm, so test it.
2836  APoint FPt = m_farms[ i ]->GetCentroids();
2837  int dist = int(sqrt( (double( FPt.m_x - a_hunterinfo.homeX ) * double( FPt.m_x - a_hunterinfo.homeX ) + double( FPt.m_y - a_hunterinfo.homeY ) * double( FPt.m_y - a_hunterinfo.homeY )) ));
2838  if (dist>40000) dist = 40000;
2839  AFarmDist fd( unsigned( fnum ), dist );
2840  farmdists.push_back( fd );
2841  }
2842  }
2843  }
2844  }
2845  // By here we have a list of farms and their distances - now we have the option to sort it or randomise it - one or other line below should be commented out.
2846  // sort(farmdists.begin(), farmdists.end(), FarmDistSort()); // Sort
2847  random_shuffle( farmdists.begin(), farmdists.end() ); // Randomise
2848  // Now the vector is sorted/randomised we loop through and test probabilities
2849  for (int ch = 1; ch < 100000; ch++) // This loop just makes sure small chances don't mess up the run by tripping out early
2850  {
2851  int sz = int( farmdists.size() );
2852  for (int i = 0; i < sz; i++) {
2853  double chance = g_rand_uni();
2854  // Uses ch from the outer loop to scale probabilities - tripping out here will occur often for farms a long way from the area otherwise
2855  double calc = cfg_ClosestFarmProbParam2.value()* exp( (cfg_ClosestFarmProbParam1.value() / double( ch ))* farmdists[ i ].m_y );
2856  if (chance <= calc) {
2857  // We passed the first test now take a second test based on roost distance
2858  chance = g_rand_uni();
2859  // Loop through each roost and find the closest to the farm - then do probability based on that distance.
2860  double dist = 10000;
2861  for (int r = 0; r < int( a_roostlist->size() ); r++) {
2862  double fdistroostx = farmdists[ i ].m_x - (*a_roostlist)[ r ].m_x;
2863  double fdistroosty = farmdists[ i ].m_y - (*a_roostlist)[ r ].m_y;
2864  double distf = sqrt( fdistroostx * fdistroostx + fdistroosty * fdistroostx );
2865  if (distf < dist) dist = distf;
2866  }
2867  calc = -0.01 + pow( dist / 10000.0, cfg_RoostDistProbParam1.value() );
2868  if (chance>calc) return farmdists[ i ].m_x;
2869  }
2870  }
2871  }
2872  g_msg->Warn( "FarmManager::FindClosestFarmProbNearRoostBest", "- No suitable farm found" );
2873  exit( 0 );
2874 }
2875 
2876 int FarmManager::FindFarmWithRandom( vector<int> * a_farmlist )
2877 {
2878  int sz= (int)m_farms.size();
2879  int f = random(sz);
2880  while (InIllegalList(m_farms[f]->GetFarmNumber(), a_farmlist))
2881  {
2882  f = random(sz);
2883  if (a_farmlist->size() >= m_farms.size())
2884  {
2885  g_msg->Warn("FarmManager::FindFarmWithRandom"," - farm density rule means all hunters cannot be placed");
2886  exit(0);
2887  }
2888  }
2889  return m_farms[f]->GetFarmNumber();
2890 
2891 }
2892 
2893 int FarmManager::FindFarmWithOpenness(vector<int> * a_farmlist, int a_openness)
2894 {
2895  // Centroid calculation on farms must be called before calling this method for the first time
2896  int sz = (int)m_farms.size();
2897  int seed = random( sz );
2898  for (unsigned i = 0; i < m_farms.size(); i++) {
2899  int index = (i + seed) % sz;
2900  if (m_farms[ index ]->GetMaxOpenness() > a_openness)
2901  {
2902  if (!InIllegalList( m_farms[ index ]->GetFarmNumber(), a_farmlist )) return m_farms[ index ]->GetFarmNumber();
2903  }
2904  else AddToIllegalList(m_farms[ index ]->GetFarmNumber(), a_farmlist );
2905  }
2906  g_msg->Warn("FarmManager::FindFarmWithOpenness", "- No suitable farm found");
2907  exit(0);
2908 }
2909 
2911 {
2912  int sz = (int) m_farms.size();
2913  int seed = random(sz);
2914  for (unsigned i = 0; i < m_farms.size(); i++)
2915  {
2916  int index = (i + seed) % sz;
2917  if (m_farms[index]->GetMaxOpenness() > a_openness) return m_farms[index]->GetFarmNumber();
2918  }
2919  return -1; // Should never happen but if it does we need to handle the -1 error code.
2920 }
2921 
2922 bool FarmManager::CheckOpenness( int a_openness, int a_ref ) {
2923  if (m_farms[ a_ref ]->GetMaxOpenness() > a_openness) return true;
2924  return false;
2925 }
2926 
2928 
2929  //get farms areas and save them
2930  totalOptFarmsArea=0;
2931  totalOptFarmsArea_plant=0;
2932  totalOptFarmsArea_pig=0;
2933  totalOptFarmsArea_cattle=0;
2934  totalOptFarmsArea_other=0;
2935  OptimisingFarm * opf;
2936  for(int j=0; j<(int)m_farms.size(); j++){
2937  if(m_farms[j]->GetType() == tof_OptimisingFarm){
2938  opf = dynamic_cast<OptimisingFarm*>(m_farms[j]);
2939  totalOptFarmsArea += opf->GetAreaDouble();
2940  if(opf->Get_farmType() == toof_Plant){
2941  totalOptFarmsArea_plant += opf->GetAreaDouble();
2942  }
2943  else if(opf->Get_farmType() == toof_Pig){
2944  totalOptFarmsArea_pig += opf->GetAreaDouble();
2945  }
2946  else if(opf->Get_farmType() == toof_Cattle){
2947  totalOptFarmsArea_cattle += opf->GetAreaDouble();
2948  }
2949  else if(opf->Get_farmType() == toof_Other){
2950  totalOptFarmsArea_other += opf->GetAreaDouble();
2951  }
2952  }
2953  }
2954 }
2955 
2957 
2958  for(int i=0; i<(int)m_farms.size(); i++){
2959  if(m_farms[i]->GetType() == tof_OptimisingFarm){ //take only optimising farms
2960  OptimisingFarm * opf;
2961  opf = dynamic_cast<OptimisingFarm*>(m_farms[i]);
2962  opf->ActualProfit();
2963  }
2964  }
2965 }
2966 
2968 
2969  for(int i=0; i<(int)m_farms.size(); i++){
2970  if(m_farms[i]->GetType() == tof_OptimisingFarm){ //take only optimising farms
2971  OptimisingFarm * opf;
2972  opf = dynamic_cast<OptimisingFarm*>(m_farms[i]);
2973  opf->ChooseDecisionMode();
2974 
2975  }
2976  }
2977 }
2978 
2980 
2981  for(int i=0; i<(int)m_farms.size(); i++){
2982  if(m_farms[i]->GetType() == tof_OptimisingFarm){ //take only optimising farms
2983  OptimisingFarm * opf;
2984  opf = dynamic_cast<OptimisingFarm*>(m_farms[i]);
2985  opf->Save_last_years_crops();
2986  }
2987  }
2988 }
2989 
2990 
2991 //void FarmManager::Switch_rotational_crops_for_farms(){
2992 //
2993 // for(int i=0; i<(int)m_farms.size(); i++){
2994 // if(m_farms[i]->GetType() == tof_OptimisingFarm){ //take only optimising farms
2995 // OptimisingFarm * opf;
2996 // opf = dynamic_cast<OptimisingFarm*>(m_farms[i]);
2997 // opf->Switch_rotational_crops();
2998 // }
2999 // }
3000 //}
3001 
3002 //--------------------------------------------------------------------------------------------
3003 //--------------------------------------------------------------------------------------------
3004 //--------------------------------------------------------------------------------------------
3005 
3006 
3008 
3009  int noFarms;
3010  int noParameters=6; //farm number, farm type, soil type, farm size, real ID, soil subtype
3011 
3012  //read the input file
3013  ifstream ifile("farms_data.txt", ios::in); //change it later - so that the nme can be set in the config file
3014 
3015  //check if there is an input file
3016  if ( !ifile.is_open() ) {
3017  cout << "Cannot open input file " << "farms_data.txt" << endl;
3018  char ch;
3019  cin >> ch; //so that it doesn't close immedietly
3020  exit(1);
3021  }
3022 
3023  //get the number of farms
3024  ifile>>noFarms;
3025  //get rid off the parameters' names
3026  string rubbish=""; //put here the names of the parameters;
3027  for(int i=0; i<noParameters; i++){
3028  ifile>>rubbish;
3029  }
3030  //read the data and assign values to the farm's variables
3031  for(int f=0; f<noFarms; f++){
3032  int almass_no, realID, soilSubType;
3033  string farm_type, soil_type, farm_size;
3034  ifile >> almass_no >> farm_type >> soil_type >> farm_size >> realID >> soilSubType;
3035  TTypesOfOptFarms farmType = TranslateFarmCodes (farm_type);
3036  TTypesOfSoils soilType = TranslateSoilCodes (soil_type);
3037  TTypesOfFarmSize farmSize = TranslateFarmSizeCodes (farm_size);
3038 
3041  pm_data->m_farm_data.push_back(fd);
3042  fd->md_almass_no=almass_no;
3043  fd->md_farmType=farmType;
3044  fd->md_soilType=soilType;
3045  fd->md_farmSize=farmSize;
3046  fd->md_farmRealID=realID;
3047  fd->md_soilSubType=soilSubType;
3048  }
3049 
3050  ifile.close();
3051 }
3052 
3054 
3055  int noFarms;
3056  //vector<TTypesOfAnimals>livestock_types; //vector of livestock types (enums)
3057 
3058  //read the input file
3059  ifstream ifile("livestock_numbers.txt", ios::in);
3060  //check if there is an input file
3061  if ( !ifile.is_open() ) {
3062  cout << "Cannot open input file " << "livestock_numbers.txt" << endl;
3063  char ch;
3064  cin >> ch; //so that it doesn't close immedietly
3065  exit(1);
3066  }
3067 
3068  //get the number of farms //and of types of livestock
3069  ifile>>noFarms; //>>noLivestockTypes;
3070 
3071  //put the names of the livestock types to the this vector;
3072  for(int l=0; l<toa_Foobar; l++){
3073  string type;
3074  ifile>>type;
3075  //livestock_types.push_back(TranslateAnimalsCodes(type));
3076  pm_data->Set_livestockTypes(TranslateAnimalsCodes(type));
3077  }
3078 
3079  //loop through the farms; create an instance of each livestock type
3080  for(int f=0; f<noFarms; f++){
3081  int almass_no; //in the first column of the input table
3082  ifile>>almass_no;
3083  pm_data->Set_livestockNumber(almass_no); //put it here so that you can search for the part of a vector - that contains numbers of a given farm
3084  for(int l=0; l<toa_Foobar; l++){
3085  int number;
3086  ifile >> number;
3087  pm_data->Set_livestockNumber(number);
3088  }
3089  }
3090  ifile.close();
3091 
3092 }
3093 
3095 
3096  int noFarms;
3097  //vector<TTypesOfCrops>crops_types; //vector of crops types (enums)
3098 
3099  //read the input file
3100  ifstream ifile("crop_areas.txt", ios::in);
3101  //check if there is an input file
3102  if ( !ifile.is_open() ) {
3103  cout << "Cannot open input file " << "crop_areas.txt" << endl;
3104  char ch;
3105  cin >> ch; //so that it doesn't close immedietly
3106  exit(1);
3107  }
3108 
3109  //get the number of farms /
3110  ifile>>noFarms;
3111 
3112  //put the names of the crop types to TWO vectors: one with strings, one with enums
3113  for(int c=0; c<toc_Foobar; c++){
3114  string type;
3115  ifile>>type;
3116  TTypesOfCrops type_enum = TranslateCropsCodes(type);
3117  pm_data->Set_cropTypes(type_enum);
3118  pm_data->Set_cropTypes_str(type);
3119  }
3120 
3121  //loop through the farms; create an instance of each crop type - also when the initial area is zero!
3122  for(int f=0; f<noFarms; f++){
3123  double almass_no; //in the first column of the input table
3124  ifile>>almass_no;
3125  pm_data->Set_cropArea(almass_no); //put it here so that you can search for the part of a vector - that contains numbers of a given farm
3126  for(int c=0; c<toc_Foobar; c++){
3127  double area;
3128  ifile >> area;
3129  pm_data->Set_cropArea(area);
3130  }
3131  }
3132  ifile.close();
3133 }
3134 
3136 
3137  int noFarms;
3138  int noCrops;
3139 
3140  //read the input file
3141  ifstream ifile("crop_areas.txt", ios::in);
3142  //check if there is an input file
3143  if ( !ifile.is_open() ) {
3144  cout << "Cannot open input file " << "crop_areas.txt" << endl;
3145  char ch;
3146  cin >> ch; //so that it doesn't close immedietly
3147  exit(1);
3148  }
3149 
3150  //get the number of crops
3151  ifile>>noCrops;
3152  //get the number of farms
3153  ifile>>noFarms;
3154  pm_data->Set_noCrops(noCrops);
3155 
3156  //put the names of the crop types to vector with enums and to the vector with strings - will be used for output
3157  for(int c=0; c<noCrops; c++){
3158  string type;
3159  ifile>>type;
3160  TTypesOfVegetation type_enum = TranslateCropCodes(type);
3161  pm_data->Set_cropTypes_almass(type_enum);
3162  pm_data->Set_cropTypes_almass_str(type);
3163  }
3164 
3165  //loop through the farms; create an instance of each crop type - also when the initial area is zero!
3166  for(int f=0; f<noFarms; f++){
3167  double almass_no; //in the first column of the input table
3168  ifile>>almass_no;
3169  pm_data->Set_cropArea(almass_no); //put it here so that you can search for the part of a vector - that contains numbers of a given far
3170  for(int c=0; c<noCrops; c++){
3171  double area;
3172  ifile >> area;
3173  pm_data->Set_cropArea(area);
3174  }
3175  }
3176  ifile.close();
3177 }
3178 
3180 
3181  //read the input file
3182  ifstream ifile("crop_parameters.txt", ios::in);
3183  //check if there is an input file
3184  if ( !ifile.is_open() ) {
3185  cout << "Cannot open input file " << "crop_parameters.txt" << endl;
3186  char ch;
3187  cin >> ch; //so that it doesn't close immedietly
3188  exit(1);
3189  }
3190 
3191  //get rid of the parameters names
3192  for(int p=0; p<top_Foobar; p++){
3193  string type;
3194  ifile>>type;
3195  }
3196 
3197  //loop through the crops - save values of the parameters in a vector of the DataForOptimisation class
3198  for(int c=0; c<toc_Foobar; c++){
3199  string crop; //in the first column of the input table
3200  ifile>>crop; //do nothing with it
3201  for(int p=0; p<top_Foobar; p++){
3202  double par_value;
3203  ifile>>par_value;
3204  int index=top_Foobar*c + p;
3205  pm_data->Set_cropParameter (par_value, index );
3206  }
3207  }
3208  ifile.close();
3209 }
3210 
3212 
3213  //read the input file
3214  ifstream ifile("crop_parameters.txt", ios::in);
3215  //check if there is an input file
3216  if ( !ifile.is_open() ) {
3217  cout << "Cannot open input file " << "crop_parameters.txt" << endl;
3218  char ch;
3219  cin >> ch; //so that it doesn't close immedietly
3220  exit(1);
3221  }
3222 
3223  int noCrops=0;
3224  ifile>>noCrops;
3225 
3226  //get rid of the parameters names
3227  for(int p=0; p<top_Foobar; p++){
3228  string type;
3229  ifile>>type;
3230  }
3231 
3232  //loop through the crops - save values of the parameters in a vector of the DataForOptimisation class
3233  for(int c=0; c<noCrops; c++){
3234  string crop; //in the first column of the input table
3235  ifile>>crop; //do nothing with it
3236  for(int p=0; p<top_Foobar; p++){
3237  double par_value;
3238  ifile>>par_value;
3239  int index=top_Foobar*(pm_data->Get_cropTypes_almass(c)) + p; //Get_cropTypes_almass(c) - gives as a tov type crop at position c
3240  pm_data->Set_cropParameter (par_value, index );
3241  }
3242  }
3243  ifile.close();
3244 
3245 }
3246 
3248 
3249  //read the input files
3250  ifstream ifile1("alfa.txt", ios::in);
3251  ifstream ifile2("beta1.txt", ios::in);
3252  ifstream ifile3("beta2.txt", ios::in);
3253  ifstream ifile4("Nnorm.txt", ios::in);
3254  //check if there are all input files
3255  if ( !ifile1.is_open() ) {
3256  cout << "Cannot open input file " << "alfa.txt" << endl;
3257  char ch;
3258  cin >> ch; //so that it doesn't close immedietly
3259  exit(1);
3260  } else if(!ifile2.is_open() ){
3261  cout << "Cannot open input file " << "beta1.txt" << endl;
3262  char ch;
3263  cin >> ch; //so that it doesn't close immedietly
3264  exit(1);
3265  }
3266  else if(!ifile3.is_open() ){
3267  cout << "Cannot open input file " << "beta2.txt" << endl;
3268  char ch;
3269  cin >> ch; //so that it doesn't close immedietly
3270  exit(1);
3271  }
3272  else if(!ifile4.is_open() ){
3273  cout << "Cannot open input file " << "Nnorm.txt" << endl;
3274  char ch;
3275  cin >> ch; //so that it doesn't close immedietly
3276  exit(1);
3277  }
3278  //get rid off the crops names;
3279  for(int c=0; c<toc_Foobar; c++){
3280  string type;
3281  ifile1>>type;
3282  ifile2>>type;
3283  ifile3>>type;
3284  ifile4>>type;
3285  }
3286 
3287  //loop through the soil types!
3288  for(int s=0; s<tos_Foobar; s++){
3289  string soil;
3290  ifile1>>soil; //get rid off the soil type name
3291  ifile2>>soil;
3292  ifile3>>soil;
3293  ifile4>>soil;
3294  for(int c=0; c<toc_Foobar; c++){
3295  double par_value;
3296  ifile1>>par_value;
3297  pm_data->Set_alfa(par_value, toc_Foobar*s + c);
3298  ifile2>>par_value;
3299  pm_data->Set_beta1(par_value, toc_Foobar*s + c);
3300  ifile3>>par_value;
3301  pm_data->Set_beta2(par_value, toc_Foobar*s + c);
3302  ifile4>>par_value;
3303  pm_data->Set_Nnorm(par_value, toc_Foobar*s + c);
3304 
3305  }
3306  }
3307  ifile1.close();
3308  ifile2.close();
3309  ifile3.close();
3310  ifile4.close();
3311 }
3312 
3314 
3315  //read the input files
3316  ifstream ifile1("alfa.txt", ios::in);
3317  ifstream ifile2("beta1.txt", ios::in);
3318  ifstream ifile3("beta2.txt", ios::in);
3319  ifstream ifile4("Nnorm.txt", ios::in);
3320  ifstream ifile5("biomass_factor_almass.txt", ios::in);
3321 
3322  //check if there are all input files
3323  if ( !ifile1.is_open() ) {
3324  cout << "Cannot open input file " << "alfa.txt" << endl;
3325  char ch;
3326  cin >> ch; //so that it doesn't close immedietly
3327  exit(1);
3328  } else if(!ifile2.is_open() ){
3329  cout << "Cannot open input file " << "beta1.txt" << endl;
3330  char ch;
3331  cin >> ch; //so that it doesn't close immedietly
3332  exit(1);
3333  }
3334  else if(!ifile3.is_open() ){
3335  cout << "Cannot open input file " << "beta2.txt" << endl;
3336  char ch;
3337  cin >> ch; //so that it doesn't close immedietly
3338  exit(1);
3339  }
3340  else if(!ifile4.is_open() ){
3341  cout << "Cannot open input file " << "Nnorm.txt" << endl;
3342  char ch;
3343  cin >> ch; //so that it doesn't close immedietly
3344  exit(1);
3345  }
3346  if (!ifile5.is_open() ) {
3347  cout << "Cannot open input file " << "biomass_factor_almass.txt" << endl;
3348  char ch;
3349  cin >> ch; //so that it doesn't close immedietly
3350  exit(1);
3351  }
3352 
3353  int noCrops, noCrops1, noCrops2, noCrops3, noCrops4=0;
3354  ifile1>>noCrops;
3355  ifile2>>noCrops1;
3356  ifile3>>noCrops2;
3357  ifile4>>noCrops3;
3358  ifile5>>noCrops4; //should be always same number!
3359  if(noCrops!=noCrops1 || noCrops!=noCrops2 || noCrops!=noCrops3 || noCrops!=noCrops4){
3360  g_msg->Warn( WARN_FILE, "FarmManager::ReadCropsData_perSoilType_almass():"" Numbers of crops differ between input files! ", " " );
3361  exit( 1 );
3362  }
3363 
3364  //get rid off the crops names;
3365  for(int c=0; c<noCrops; c++){
3366  string type;
3367  ifile1>>type;
3368  ifile2>>type;
3369  ifile3>>type;
3370  ifile4>>type;
3371  ifile5>>type;
3372  }
3373 
3374  //loop through the soil types!
3375  for(int s=0; s<tos_Foobar; s++){
3376  string soil;
3377  ifile1>>soil; //get rid off the soil type name
3378  ifile2>>soil;
3379  ifile3>>soil;
3380  ifile4>>soil;
3381  ifile5>>soil;
3382  for(int c=0; c<noCrops; c++){
3383  double par_value;
3384  ifile1>>par_value;
3385  pm_data->Set_alfa(par_value, tov_Undefined*s + pm_data->Get_cropTypes_almass(c)); //Get_cropTypes_almass(c) - gives as a tov type crop at position c
3386  ifile2>>par_value;
3387  pm_data->Set_beta1(par_value, tov_Undefined*s + pm_data->Get_cropTypes_almass(c));
3388  ifile3>>par_value;
3389  pm_data->Set_beta2(par_value, tov_Undefined*s + pm_data->Get_cropTypes_almass(c));
3390  ifile4>>par_value;
3391  pm_data->Set_Nnorm(par_value, tov_Undefined*s + pm_data->Get_cropTypes_almass(c));
3392  ifile5>>par_value;
3393  pm_data->Set_biomass_factor(par_value, tov_Undefined*s + pm_data->Get_cropTypes_almass(c));
3394 
3395  }
3396  }
3397  ifile1.close();
3398  ifile2.close();
3399  ifile3.close();
3400  ifile4.close();
3401  ifile5.close();
3402 }
3403 
3405 
3406  //read the input files
3407  ifstream ifile1("fixed.txt", ios::in);
3408  ifstream ifile2("fodder.txt", ios::in);
3409  ifstream ifile3("FUKey.txt", ios::in);
3410 
3411  //check if there are all input files
3412  if ( !ifile1.is_open() ) {
3413  cout << "Cannot open input file " << "fixed.txt" << endl;
3414  char ch;
3415  cin >> ch; //so that it doesn't close immedietly
3416  exit(1);
3417  } else if(!ifile2.is_open() ){
3418  cout << "Cannot open input file " << "fodder.txt" << endl;
3419  char ch;
3420  cin >> ch; //so that it doesn't close immedietly
3421  exit(1);
3422  }
3423  else if(!ifile3.is_open() ){
3424  cout << "Cannot open input file " << "FUKey.txt" << endl;
3425  char ch;
3426  cin >> ch; //so that it doesn't close immedietly
3427  exit(1);
3428  }
3429 
3430  //get rid off the crops names;
3431  for(int c=0; c<toc_Foobar; c++){
3432  string type;
3433  ifile1>>type;
3434  ifile2>>type;
3435  ifile3>>type;
3436  }
3437 
3438  //loop through the farm types!
3439  for(int f=0; f<toof_Foobar; f++){
3440  string farm_type;
3441  ifile1>>farm_type; //get rid off the farm type name
3442  ifile2>>farm_type;
3443  ifile3>>farm_type;
3444  for(int c=0; c<toc_Foobar; c++){
3445  string par;
3446  ifile1>>par;
3447  pm_data->Set_fixed(par, toc_Foobar*f + c);
3448  ifile2>>par;
3449  pm_data->Set_fodder(par, toc_Foobar*f + c);
3450  double par_value;
3451  ifile3>>par_value;
3452  pm_data->Set_FUKey(par_value, toc_Foobar*f + c);
3453  }
3454  }
3455  ifile1.close();
3456  ifile2.close();
3457  ifile3.close();
3458 }
3459 
3461 
3462  //read the input files
3463  ifstream ifile1("fixed.txt", ios::in);
3464  ifstream ifile2("fodder.txt", ios::in);
3465  ifstream ifile3("FUKey.txt", ios::in);
3466 
3467  //check if there are all input files
3468  if ( !ifile1.is_open() ) {
3469  cout << "Cannot open input file " << "fixed.txt" << endl;
3470  char ch;
3471  cin >> ch; //so that it doesn't close immedietly
3472  exit(1);
3473  } else if(!ifile2.is_open() ){
3474  cout << "Cannot open input file " << "fodder.txt" << endl;
3475  char ch;
3476  cin >> ch; //so that it doesn't close immedietly
3477  exit(1);
3478  }
3479  else if(!ifile3.is_open() ){
3480  cout << "Cannot open input file " << "FUKey.txt" << endl;
3481  char ch;
3482  cin >> ch; //so that it doesn't close immedietly
3483  exit(1);
3484  }
3485 
3486  int noCrops, noCrops1, noCrops2=0;
3487  ifile1>>noCrops;
3488  ifile2>>noCrops1;
3489  ifile3>>noCrops2; //should be always same number!
3490  if(noCrops!=noCrops1 || noCrops!=noCrops2){
3491  g_msg->Warn( WARN_FILE, "FarmManager::ReadCropsData_perSoilType_almass():"" Numbers of crops differ between input files! ", " " );
3492  exit( 1 );
3493  }
3494 
3495 
3496  //get rid off the crops names;
3497  for(int c=0; c<noCrops; c++){
3498  string type;
3499  ifile1>>type;
3500  ifile2>>type;
3501  ifile3>>type;
3502  }
3503 
3504  //loop through the farm types!
3505  for(int f=0; f<toof_Foobar; f++){
3506  string farm_type;
3507  ifile1>>farm_type; //get rid off the farm type name
3508  ifile2>>farm_type;
3509  ifile3>>farm_type;
3510  for(int c=0; c<noCrops; c++){
3511  string par;
3512  ifile1>>par;
3513  pm_data->Set_fixed(par, tov_Undefined*f + pm_data->Get_cropTypes_almass(c));
3514  ifile2>>par;
3515  pm_data->Set_fodder(par, tov_Undefined*f + pm_data->Get_cropTypes_almass(c));
3516  double par_value;
3517  ifile3>>par_value;
3518  pm_data->Set_FUKey(par_value, tov_Undefined*f + pm_data->Get_cropTypes_almass(c));
3519  }
3520  }
3521  ifile1.close();
3522  ifile2.close();
3523  ifile3.close();
3524 }
3525 
3527 
3528  //read the input files
3529  ifstream ifile1("sellingPrice.txt", ios::in);
3530 
3531  //check if there are all input files
3532  if ( !ifile1.is_open() ) {
3533  cout << "Cannot open input file " << "sellingPrice.txt" << endl;
3534  char ch;
3535  cin >> ch; //so that it doesn't close immedietly
3536  exit(1);
3537  }
3538 
3539  //get rid off the crops names;
3540  for(int c=0; c<toc_Foobar; c++){
3541  string type;
3542  ifile1>>type;
3543  }
3544 
3545  //loop through the farm and soil types!
3546  for(int f=0; f<(toof_Foobar * tos_Foobar); f++){
3547  string farm_type;
3548  string soil_type;
3549  ifile1>>farm_type>>soil_type; //get rid off the farm type and soil type names
3550  for(int c=0; c<toc_Foobar; c++){
3551  double par_value;
3552  ifile1>>par_value;
3553  pm_data->Set_sellingPrice(par_value, toc_Foobar*f + c);
3554  }
3555  }
3556  ifile1.close();
3557 }
3558 
3560 
3561  //read the input files
3562  ifstream ifile1("sellingPrice.txt", ios::in);
3563 
3564  //check if there are all input files
3565  if ( !ifile1.is_open() ) {
3566  cout << "Cannot open input file " << "sellingPrice.txt" << endl;
3567  char ch;
3568  cin >> ch; //so that it doesn't close immedietly
3569  exit(1);
3570  }
3571 
3572  int noCrops=0;
3573  ifile1>>noCrops;
3574 
3575  //get rid off the crops names;
3576  for(int c=0; c<noCrops; c++){
3577  string type;
3578  ifile1>>type;
3579  }
3580 
3581  //loop through the farm and soil types!
3582  for(int f=0; f<(toof_Foobar * tos_Foobar); f++){
3583  string farm_type;
3584  string soil_type;
3585  ifile1>>farm_type>>soil_type; //get rid off the farm type and soil type names
3586  for(int c=0; c<noCrops; c++){
3587  double par_value;
3588  ifile1>>par_value;
3589  pm_data->Set_sellingPrice(par_value, tov_Undefined*f + pm_data->Get_cropTypes_almass(c));
3590  }
3591  }
3592  ifile1.close();
3593 
3594 
3595  }
3596 
3598 
3599  //read the input files
3600  ifstream ifile1("rotationMax.txt", ios::in);
3601  ifstream ifile2("rotationMin.txt", ios::in);
3602 
3603  //check if there are all input files
3604  if ( !ifile1.is_open() ) {
3605  cout << "Cannot open input file " << "rotationMax.txt" << endl;
3606  char ch;
3607  cin >> ch; //so that it doesn't close immedietly
3608  exit(1);
3609  } else if(!ifile2.is_open() ){
3610  cout << "Cannot open input file " << "rotationMin.txt" << endl;
3611  char ch;
3612  cin >> ch; //so that it doesn't close immedietly
3613  exit(1);
3614  }
3615 
3616  //get rid off the crops names;
3617  for(int c=0; c<toc_Foobar; c++){
3618  string type;
3619  ifile1>>type;
3620  ifile2>>type;
3621  }
3622 
3623  //loop through the farm types, soil types and farm sizes!
3624  for(int f=0; f<(toof_Foobar *tos_Foobar * tofs_Foobar); f++){
3625  string farm_type, soil_type, farm_size;
3626  ifile1>>farm_type>>soil_type>>farm_size; //get rid off the farm type, soil type ad farm size names
3627  ifile2>>farm_type>>soil_type>>farm_size;
3628  for(int c=0; c<toc_Foobar; c++){
3629  double par_value;
3630  ifile1>>par_value;
3631  pm_data->Set_rotationMax(par_value, toc_Foobar*f + c);
3632  ifile2>>par_value;
3633  pm_data->Set_rotationMin(par_value, toc_Foobar*f + c);
3634  }
3635  }
3636  ifile1.close();
3637  ifile2.close();
3638 }
3639 
3641 
3642  //read the input files
3643 
3644  string rot_max;
3645  string rot_min;
3646 
3648  rot_max = "rotationMax_almass.txt";
3649  rot_min = "rotationMin_almass.txt";
3650  }
3651  else{ //rot max and min as specified in the Original Bedriftsmodel
3652  rot_max = "rotationMax.txt";
3653  rot_min = "rotationMin.txt";
3654  }
3655 
3656  ifstream ifile1(rot_max.c_str(), ios::in);
3657  ifstream ifile2(rot_min.c_str(), ios::in);
3658 
3659 
3660 
3661  //check if there are all input files
3662  if ( !ifile1.is_open() ) {
3663  cout << "Cannot open input file with rotation max" << endl;
3664  char ch;
3665  cin >> ch; //so that it doesn't close immedietly
3666  exit(1);
3667  } else if(!ifile2.is_open() ){
3668  cout << "Cannot open input file with rotation min" << endl;
3669  char ch;
3670  cin >> ch; //so that it doesn't close immedietly
3671  exit(1);
3672  }
3673 
3674  int noCrops, noCrops1=0;
3675  ifile1>>noCrops;
3676  ifile2>>noCrops1; //should be always same number!
3677  if(noCrops!=noCrops1){
3678  g_msg->Warn( WARN_FILE, "FarmManager::ReadCropsData_perSoilType_almass():"" Numbers of crops differ between input files! ", " " );
3679  exit( 1 );
3680  }
3681 
3682  //get rid off the crops names;
3683  for(int c=0; c<noCrops; c++){
3684  string type;
3685  ifile1>>type;
3686  ifile2>>type;
3687  }
3688 
3689  //loop through the farm types, soil types and farm sizes!
3690  for(int f=0; f<(toof_Foobar *tos_Foobar * tofs_Foobar); f++){
3691  string farm_type, soil_type, farm_size;
3692  ifile1>>farm_type>>soil_type>>farm_size; //get rid off the farm type, soil type ad farm size names
3693  ifile2>>farm_type>>soil_type>>farm_size;
3694  for(int c=0; c<noCrops; c++){
3695  double par_value;
3696  ifile1>>par_value;
3697  pm_data->Set_rotationMax(par_value, tov_Undefined*f + pm_data->Get_cropTypes_almass(c));
3698  ifile2>>par_value;
3699  pm_data->Set_rotationMin(par_value, tov_Undefined*f + pm_data->Get_cropTypes_almass(c));
3700  }
3701  }
3702  ifile1.close();
3703  ifile2.close();
3704 
3705 }
3706 
3708 
3709  //read the input files
3710  ifstream ifile1("winterMax.txt", ios::in);
3711 
3712  //check if there are all input files
3713  if ( !ifile1.is_open() ) {
3714  cout << "Cannot open input file " << "winterMax.txt" << endl;
3715  char ch;
3716  cin >> ch; //so that it doesn't close immedietly
3717  exit(1);
3718  }
3719 
3720  //get rid off the parameter name;
3721  string type;
3722  ifile1>>type;
3723 
3724  //loop through the farm types!
3725  for(int f=0; f<toof_Foobar; f++){
3726  string farm_type;
3727  ifile1>>farm_type; //get rid off the farm type name
3728  int par_value;
3729  ifile1>>par_value;
3730  pm_data->Set_winterMax(par_value, f);
3731  }
3732  ifile1.close();
3733 }
3734 
3736 
3737  //read the input file
3738  ifstream ifile("livestock_parameters.txt", ios::in);
3739  //check if there is an input file
3740  if ( !ifile.is_open() ) {
3741  cout << "Cannot open input file " << "livestock_parameters.txt" << endl;
3742  char ch;
3743  cin >> ch; //so that it doesn't close immedietly
3744  exit(1);
3745  }
3746 
3747  //get rid off the parameter names
3748  for(int p=0; p<tolp_Foobar; p++){
3749  string type;
3750  ifile>>type;
3751  }
3752 
3753  //loop through the livestock types - save values of the parameters in a vector of the DataForOptimisation class
3754  for(int l=0; l<toa_Foobar; l++){
3755  string livestock; //in the first column of the input table
3756  ifile>>livestock; //do nothing with it
3757  for(int p=0; p<tolp_Foobar; p++){
3758  double par_value;
3759  ifile>>par_value;
3760  pm_data->Set_livestockParameter(par_value, tolp_Foobar*l + p);
3761  }
3762  }
3763  ifile.close();
3764 }
3765 
3766 
3768 
3769 
3770  //read the input files
3771  ifstream ifile1(l_emaize_price_file.value(), ios::in);
3772 
3773  //check if there are all input files
3774  if ( !ifile1.is_open() ) {
3775  cout << "Cannot open input file " << l_emaize_price_file.value() << endl;
3776  char ch;
3777  cin >> ch; //so that it doesn't close immedietly
3778  exit(1);
3779  }
3780  //get th enumber of years he file has data for
3781  int no_years=0;
3782  ifile1>>no_years;
3783 
3784  //loop
3785  for(int i=0; i<no_years; i++){
3786  int year;
3787  ifile1>>year; //get rid off the year number
3788  double par_value;
3789  ifile1>>par_value;
3790  pm_data->Set_emaize_price(par_value);
3791  }
3792  ifile1.close();
3793 }
3794 
3795 
3797  // This simply checks through the list of legal farm types and returns
3798  // the correct farm type
3799  string str = astr;
3800  if ( str == "Other" ) return toof_Other;
3801  if ( str == "Cattle" ) return toof_Cattle;
3802  if ( str == "Plant" ) return toof_Plant;
3803  if ( str == "Pig" ) return toof_Pig;
3804  // No match so issue a warning and quit
3805  g_msg->Warn( WARN_FILE, "FarmManager::TranslateFarmCodes():"" Unknown Farm type Code ", str.c_str() );
3806  exit( 1 );
3807 }
3808 
3810  // This simply checks through the list of legal soil types and returns
3811  // the correct soil type
3812  string str = astr;
3813  if ( str == "Other" ) return tos_Other;
3814  if ( str == "Sand" ) return tos_Sand;
3815  if ( str == "Clay" ) return tos_Clay;
3816  // No match so issue a warning and quit
3817  g_msg->Warn( WARN_FILE, "FarmManager::TranslateSoilCodes():"" Unknown Soil type Code ", str.c_str() );
3818  exit( 1 );
3819 }
3820 
3822  // This simply checks through the list of legal farm sizes and returns
3823  // the correct farm size
3824  string str = astr;
3825  if ( str == "business" ) return tofs_Business;
3826  if ( str == "private" ) return tofs_Private;
3827  // No match so issue a warning and quit
3828  g_msg->Warn( WARN_FILE, "FarmManager::TranslateFarmSizeCodes():"" Unknown Farm Size Code ", str.c_str() );
3829  exit( 1 );
3830 }
3831 
3833  // This simply checks through the list of legal animal (livestock) types and returns
3834  // the correct animal type
3835  string str = astr;
3836  if ( str == "Horse") return toa_Horse;
3837  if ( str == "DCow") return toa_DCow;
3838  if ( str == "Suckler") return toa_Suckler;
3839  if ( str == "DCalf") return toa_DCalf;
3840  if ( str == "MCalf") return toa_MCalf;
3841  if ( str == "MCattle") return toa_MCattle;
3842  if ( str == "Sheep") return toa_Sheep;
3843  if ( str == "Goat") return toa_Goat;
3844  if ( str == "So") return toa_So;
3845  if ( str == "Finisher") return toa_Finisher;
3846  if ( str == "Piglet") return toa_Piglet;
3847  if ( str == "Deer") return toa_Deer;
3848  if ( str == "Mink") return toa_Mink;
3849  if ( str == "EHen") return toa_EHen;
3850  if ( str == "MHen") return toa_MHen;
3851  if ( str == "Turkey") return toa_Turkey;
3852  if ( str == "Goose") return toa_Goose;
3853  if ( str == "Duck") return toa_Duck;
3854  if ( str == "MDuck") return toa_MDuck;
3855  if ( str == "Ostrich") return toa_Ostrich;
3856  // No match so issue a warning and quit
3857  g_msg->Warn( WARN_FILE, "FarmManager::TranslateAnimalsCodes():"" Unknown Animal type Code ", str.c_str() );
3858  exit( 1 );
3859 }
3860 
3862 // This simply checks through the list of legal crops types and returns
3863 // the correct crop type
3864  string str = astr;
3865  if ( str == "SBarley") return toc_SBarley;
3866  if ( str == "Oats") return toc_Oats;
3867  if ( str == "OSCrops") return toc_OSCrops;
3868  if ( str == "WBarley") return toc_WBarley;
3869  if ( str == "WWheat") return toc_WWheat;
3870  if ( str == "WRye") return toc_WRye;
3871  if ( str == "Triticale") return toc_Triticale;
3872  if ( str == "SRape") return toc_SRape;
3873  if ( str == "WRape") return toc_WRape;
3874  if ( str == "OOilseed") return toc_OOilseed;
3875  if ( str == "Peas") return toc_Peas;
3876  if ( str == "OLSeed") return toc_OLSeed;
3877  if ( str == "GrassSeed") return toc_GrassSeed;
3878  if ( str == "Potato") return toc_Potato;
3879  if ( str == "PotatoFood") return toc_PotatoFood;
3880  if ( str == "SugarBeet") return toc_SugarBeet;
3881  if ( str == "GrassClover") return toc_GrassClover;
3882  if ( str == "OLSeedCut") return toc_OLSeedCut;
3883  if ( str == "SCerealSil") return toc_SCerealSil;
3884  if ( str == "PeasSil") return toc_PeasSil;
3885  if ( str == "MaizeSil") return toc_MaizeSil;
3886  if ( str == "WCerealSil") return toc_WCerealSil;
3887  if ( str == "SCerealG") return toc_SCerealG;
3888  if ( str == "PerGrassLow") return toc_PerGrassLow;
3889  if ( str == "PerGrassNorm") return toc_PerGrassNorm;
3890  if ( str == "GrassEnv1") return toc_GrassEnv1;
3891  if ( str == "GrassEnv2") return toc_GrassEnv2;
3892  if ( str == "GrassRot") return toc_GrassRot;
3893  if ( str == "Setaside") return toc_Setaside;
3894  if ( str == "Uncult") return toc_Uncult;
3895  if ( str == "OUncult") return toc_OUncult;
3896  if ( str == "OFodderBeet") return toc_OFodderBeet;
3897  if ( str == "CloverGrz") return toc_CloverGrz;
3898  if ( str == "Veg") return toc_Veg;
3899  if ( str == "Fruit") return toc_Fruit;
3900  if ( str == "FruitTree") return toc_FruitTree;
3901  if ( str == "OSpecCrops") return toc_OSpecCrops;
3902  if ( str == "ChrisTree") return toc_ChrisTree;
3903  if ( str == "EnergyFor") return toc_EnergyFor;
3904  if ( str == "Other") return toc_Other;
3905  // No match so issue a warning and quit
3906  g_msg->Warn( WARN_FILE, "FarmManager::TranslateCropCodes():"" Unknown Crop type Code ", str.c_str() );
3907  exit( 1 );
3908 }
3909 
3911  // This simply checks through the list of legal crop parameters (those not varying with farm type etc.)
3912  //and returns the correct enum
3913  string str = astr;
3914  if ( str == "Subsidy" ) return top_Subsidy;
3915  if ( str == "PriceLM" ) return top_PriceLM;
3916  if ( str == "PriceHerb" ) return top_PriceHerb;
3917  if ( str == "PriceFi" ) return top_PriceFi;
3918  if ( str == "PriceG" ) return top_PriceG;
3919  if ( str == "PriceH" ) return top_PriceH;
3920  if ( str == "PriceW" ) return top_PriceW;
3921  if ( str == "AlfaHerb" ) return top_AlfaHerb;
3922  if ( str == "BetaHerb" ) return top_BetaHerb;
3923  if ( str == "AlfaFi" ) return top_AlfaFi;
3924  if ( str == "BetaFi" ) return top_BetaFi;
3925  if ( str == "AlfaG" ) return top_AlfaG;
3926  if ( str == "BetaG" ) return top_BetaG;
3927  if ( str == "AlfaH" ) return top_AlfaH;
3928  if ( str == "BetaH" ) return top_BetaH;
3929  if ( str == "AlfaW" ) return top_AlfaW;
3930  if ( str == "BetaW" ) return top_BetaW;
3931 
3932  // No match so issue a warning and quit
3933  g_msg->Warn( WARN_FILE, "FarmManager::TranslateParametersCodes():"" Unknown Parameter Code ", str.c_str() );
3934  exit( 1 );
3935 }
3936 
3938  // This simply checks through the list of legal livestock parameters and returns the correct enum
3939  string str = astr;
3940  if ( str == "AUKey" ) return tolp_AUKey;
3941  if ( str == "Nusable" ) return tolp_Nusable;
3942  if ( str == "FUuKey" ) return tolp_FUuKey;
3943 
3944  // No match so issue a warning and quit
3945  g_msg->Warn( WARN_FILE, "FarmManager::TranslateLivestockParametersCodes():"" Unknown Livestock Parameter Code ", str.c_str() );
3946  exit( 1 );
3947 }
3948 
3950  // This simply checks through the list of legal crop variables and returns the correct enum
3951  string str = astr;
3952  if ( str == "m_areaPercent" ) return tocv_AreaPercent;
3953  if ( str == "m_area_ha" ) return tocv_AreaHa;
3954  if ( str == "m_n" ) return tocv_N;
3955  if ( str == "m_nt" ) return tocv_Nt;
3956  if ( str == "m_BIHerb" ) return tocv_BIHerb;
3957  if ( str == "m_BIFi" ) return tocv_BIFi;
3958  if ( str == "m_BI" ) return tocv_BI;
3959  if ( str == "m_grooming" ) return tocv_Grooming;
3960  if ( str == "m_hoeing" ) return tocv_Hoeing;
3961  if ( str == "m_weeding" ) return tocv_Weeding;
3962  if ( str == "m_totalLoss" ) return tocv_TotalLoss;
3963  if ( str == "m_resp" ) return tocv_Response;
3964  if ( str == "m_income" ) return tocv_Income;
3965  if ( str == "m_costs" ) return tocv_Costs;
3966  if ( str == "m_GM" ) return tocv_GM;
3967  if ( str == "m_savings" ) return tocv_Savings;
3968 
3969  // No match so issue a warning and quit
3970  g_msg->Warn( WARN_FILE, "FarmManager::TTypesOfCropVariables():"" Unknown crop variable Code ", str.c_str() );
3971  exit( 1 );
3972 }
3973 
3975 
3976 //1. crop variables
3977  PrintOutput(tocv_AreaPercent, "AreaPercent.txt");
3978  PrintOutput(tocv_AreaHa, "AreaHa.txt");
3979  PrintOutput(tocv_N, "N.txt");
3980  PrintOutput(tocv_Nt, "Nt.txt");
3981  PrintOutput(tocv_BIHerb, "BIHerb.txt");
3982  PrintOutput(tocv_BIFi, "BIFi.txt");
3983  PrintOutput(tocv_BI, "BI.txt");
3984  PrintOutput(tocv_Grooming, "Grooming.txt");
3985  PrintOutput(tocv_Hoeing, "Hoeing.txt");
3986  PrintOutput(tocv_Weeding, "Weeding.txt");
3987  PrintOutput(tocv_TotalLoss, "TotalLoss.txt");
3988  PrintOutput(tocv_Response, "Response.txt");
3989  PrintOutput(tocv_Income, "Income.txt");
3990  PrintOutput(tocv_Costs, "Costs.txt");
3991  PrintOutput(tocv_GM, "GM.txt");
3992  PrintOutput(tocv_Savings, "Savings.txt");
3993 
3994 //2. crop total areas in ha at the landscape level
3995 
3996  CropDistribution(); //now there are total area values for each crop in the m_cropTotals vector
3997  ofstream ofile("CropDistribution.txt", ios::out);
3998 
4000  //print crop names (using vector<string>m_cropTypes)
4001  for(int c=0; c<toc_Foobar; c++) ofile << pm_data->Get_cropTypes_str(c) << '\t';
4002  ofile << endl;
4003  //print the values (total areas in ha)
4004  for(int c=0; c<toc_Foobar; c++) ofile << m_cropTotals[c] << '\t';
4005  }
4006  else{
4007  //print 'year'
4008  ofile << "Year" << '\t';
4009  //print crop names
4010  for(int c=0; c<pm_data->Get_noCrops(); c++) ofile << pm_data->Get_cropTypes_almass_str(c) << '\t';
4011  ofile << endl;
4012  //it's the first optimisation, so say the year is zero
4013  ofile << "0" << '\t';
4014  //print the values (total areas in ha)
4015  for(int c=0; c<pm_data->Get_noCrops(); c++) ofile << m_cropTotals[c] << '\t';
4016  ofile << endl;
4017  }
4018 
4019  //restart the m_cropTotals:
4020  for(int i=0; i<(int)m_cropTotals.size(); i++){
4021  m_cropTotals[i]=0;
4022  }
4023 
4024  ofile.close();
4025 }
4026 
4027 void FarmManager::PrintOutput(TTypesOfCropVariables a_var, string a_fileName){
4028 
4029  ofstream ofile (a_fileName.c_str(), ios::out);
4030  ofile << "Farm no" << '\t';
4031  //print crop names (using vector<string>m_cropTypes)
4033  for(int c=0; c<toc_Foobar; c++) ofile << pm_data->Get_cropTypes_str(c) << '\t';
4034  }
4035  else{
4036  for(int c=0; c<pm_data->Get_noCrops(); c++) ofile << pm_data->Get_cropTypes_almass_str(c) << '\t';
4037  }
4038  ofile << endl;
4039 
4040  for (int i=0; i<(int)m_farms.size(); i++){
4041  if(m_farms[i]->GetType() == tof_OptimisingFarm){ //take only optimising farms
4042  OptimisingFarm * opf;
4043  opf = dynamic_cast<OptimisingFarm*>(m_farms[i]);
4044  int no = opf->Get_almass_no();
4045  ofile << no << '\t';
4046  int size = opf->Get_cropsSize();
4047  for(int j = 0; j < size; j++){
4048  double var_to_print = -1;
4049  CropOptimised* crop = opf->Get_crop(j);
4050  switch (a_var){
4051  case tocv_AreaPercent:
4052  var_to_print = crop ->m_areaPercent;
4053  break;
4054  case tocv_AreaHa:
4055  var_to_print = crop ->m_area_ha;
4056  break;
4057  case tocv_N:
4058  var_to_print = crop ->m_n;
4059  break;
4060  case tocv_Nt:
4061  var_to_print = crop ->m_nt;
4062  break;
4063  case tocv_BIHerb:
4064  var_to_print = crop ->m_BIHerb;
4065  break;
4066  case tocv_BIFi:
4067  var_to_print = crop ->m_BIFi;
4068  break;
4069  case tocv_BI:
4070  var_to_print = crop ->m_BI;
4071  break;
4072  case tocv_Grooming:
4073  var_to_print = crop ->m_grooming;
4074  break;
4075  case tocv_Hoeing:
4076  var_to_print = crop ->m_hoeing;
4077  break;
4078  case tocv_Weeding:
4079  var_to_print = crop ->m_weeding;
4080  break;
4081  case tocv_TotalLoss:
4082  var_to_print = crop ->m_totalLoss;
4083  break;
4084  case tocv_Response:
4085  var_to_print = crop ->m_resp;
4086  break;
4087  case tocv_Income:
4088  var_to_print = crop ->m_income_ha;
4089  break;
4090  case tocv_Costs:
4091  var_to_print = crop ->m_costs_ha;
4092  break;
4093  case tocv_GM:
4094  var_to_print = crop ->m_GM;
4095  break;
4096  case tocv_Savings:
4097  var_to_print = crop ->m_savings;
4098  break;
4099  default:
4100  g_msg->Warn( WARN_BUG, "FarmManager::PrintOutput(): ""Unknown crop variable type! ", "" );
4101  exit( 1 );
4102  }
4103  ofile << var_to_print << '\t';
4104  }
4105  ofile << endl;
4106  }
4107  }
4108  ofile.close();
4109 }
4110 
4112 
4113  int no_crops = (cfg_OptimiseBedriftsmodelCrops.value())? toc_Foobar : pm_data->Get_noCrops(); //bedriftsmodel crops/almass crops
4114  m_cropTotals.resize(no_crops); //no_crops is ok for both almass and bedriftsmodel crop mode; it is taken from the input file on initial crop areas
4115 
4116  for(int i=0; i<(int)m_farms.size(); i++){
4117 
4118  OptimisingFarm * opf;
4119  int size=0;
4120  if(m_farms[i]->GetType()==tof_OptimisingFarm) { //take only optimising farms
4121  opf = dynamic_cast<OptimisingFarm*>(m_farms[i]);
4122  size = opf->Get_cropsSize();
4123  for(int j=0; j<size; j++) {
4124  CropOptimised *crop = opf->Get_crop(j);
4125  double area = crop->m_area_ha;
4126  m_cropTotals[j] += area;
4127  }
4128  }
4129  }
4130 }
4131 
4133 
4134  pm_output_file = new ofstream ("FarmVariables.txt", ios::out);
4135 
4136  (*pm_output_file) << "Farm no \t";
4137 
4138  //print variables' names (18 variables, 09.05.12)
4139  (*pm_output_file) << "mainGoal \t" << "totalArea \t" << "totalIncome \t" << "totalCosts \t" << "totalProfit \t";
4140  (*pm_output_file) << "FodderDemand \t" << "FodderDemand_bef \t" << "FodderTrade \t" << "FodderGrown \t" ;
4141  (*pm_output_file) << "Nanim \t" << "totalNanim \t" << "totalNt \t" << "totalN \t" ;
4142  (*pm_output_file) << "totalBI \t" << "totalBIHerb \t" << "totalBIFi \t" ;
4143  (*pm_output_file) << "totalGrooming \t" << "totalHoeing \t" << "totalWeeding \t";
4144  (*pm_output_file) << endl;
4145 
4146 }
4147 
4149 
4150  //read the input file
4151  ifstream ifile("crops_lookup.txt", ios::in);
4152  //check if there is an input file
4153  if ( !ifile.is_open() ) {
4154  cout << "Cannot open input file " << "crops_lookup.txt" << endl;
4155  char ch;
4156  cin >> ch; //so that it doesn't close immedietly
4157  exit(1);
4158  }
4159 
4160  //get rid of the crop tov names - first line of the input file
4161  for(int p=0; p<tov_Undefined+1; p++){
4162  string tov_type;
4163  ifile>>tov_type;
4164  }
4165 
4166  //loop through the crops - save values (-1, 0 or 1) in the vector<int>m_crop_lookup_table;
4167  for(int r=0; r<tov_Undefined+1; r++){ //rows
4168  string tov_type; //in the first column of the input table
4169  ifile>>tov_type; //do nothing with it
4170  for(int c=0; c<tov_Undefined+1; c++){ //you are at row r, go through all the columns c
4171  int value;
4172  ifile >> value;
4173  m_crop_lookup_table.push_back(value);
4174  }
4175  }
4176  ifile.close();
4177 
4178 }
4179 
4181  //determine who is each farm's neighbour and save them in the farm's vector of its neighbours
4182  //and print the neighbours
4183 
4184  OptimisingFarm * opf_i;
4185  OptimisingFarm * opf_k;
4186 
4187  for(int i=0; i<(int)m_farms.size(); i++){
4188  if(m_farms[i]->GetType() == tof_OptimisingFarm){ //take only optimising farms
4189  opf_i = dynamic_cast<OptimisingFarm*>(m_farms[i]);
4190  opf_i->Centroids(); //finds each farm's centroid
4191  }
4192  }
4193 
4194  for(int i=0; i<(int)m_farms.size(); i++){
4195  if(m_farms[i]->GetType() == tof_OptimisingFarm){ //take only optimising farms
4196  opf_i = dynamic_cast<OptimisingFarm*>(m_farms[i]);
4197  int x = opf_i->GetFarmCentroidX();
4198  int y = opf_i->GetFarmCentroidY();
4199  int farm_no_i = opf_i->Get_almass_no();
4200 
4201  for(int k = 0; k<(int)m_farms.size(); k++) { //find neighbours of farm i
4202  if(m_farms[k]->GetType() == tof_OptimisingFarm){ //take only optimising farms
4203  opf_k = dynamic_cast<OptimisingFarm*>(m_farms[k]);
4204  int xb = opf_k->GetFarmCentroidX();
4205  int yb = opf_k->GetFarmCentroidY();
4206  double par = 1000 * cfg_Neighbor_dist.value(); //change km to m
4207  int farm_no_k = opf_k->Get_almass_no();
4208 
4209  if(abs(x - xb) <= par && abs(y - yb) <= par && farm_no_i!=farm_no_k){ //check neighbourship (make sure it is not the same farm)
4210  //this is a neighbour
4211  opf_i->Set_Neighbour(opf_k); //add farm k to the list of neighbours of farm i
4212  }
4213  }
4214  else break;
4215  }
4216  }
4217  else break; //break the for loop -there is no more optimising farms
4218  }
4219 
4220  PrintNeighbours();
4221 
4222 }
4223 
4225  //create a text file with the farms and their neighbours
4226  ofstream ofile ("Neighbours.txt", ios::out);
4227  ofile << "Farm no" << endl;
4228 
4229  //print each farms no and then the numbers of its neighbours
4230  for(int i=0; i<(int)m_farms.size(); i++){
4231  OptimisingFarm * opf_i;
4232  if(m_farms[i]->GetType() == tof_OptimisingFarm){ //take only optimising farms
4233  opf_i = dynamic_cast<OptimisingFarm*>(m_farms[i]);
4234  ofile << opf_i->Get_almass_no() << '\t';
4235  for(int j=0; j<opf_i->Get_NeighboursSize(); j++){
4236  ofile << opf_i->Get_Neighbour(j)->Get_almass_no() <<'\t'; //pointer to the current, i.e. 'i' farm, takes its neighbour (j) and retrieves his almass_no
4237  }
4238  ofile << endl;
4239  }
4240  }
4241 }
4242 
4244 
4245  //create a text file and make headers
4246  ofstream ofile ("Decision_modes_counts.txt", ios::out);
4247  ofile << "Farm_no\t" << "imitation\t" << "social comparison\t" << "repeat\t"<< "deliberation\t"<<endl;
4248 
4249  //print each farms no and then the content of the vector ...
4250  for(int i=0; i<(int)m_farms.size(); i++){
4251  OptimisingFarm * opf_i;
4252  if(m_farms[i]->GetType() == tof_OptimisingFarm){ //take only optimising farms
4253  opf_i = dynamic_cast<OptimisingFarm*>(m_farms[i]);
4254  ofile << opf_i->Get_almass_no() << '\t';
4255  for(int j=0; j<4; j++){
4256  ofile << opf_i->Get_decision_mode_counters(j) <<'\t';
4257  }
4258  ofile << endl;
4259  }
4260  }
4261 
4262 }
4263 
4265 
4266  PrintDecModes_counts();
4267 
4268  int no_years = g_date->GetYearNumber() - 21; //exclude first 9 years + one - the last one, which has just started now - it's Jan 1st//exclude first 20 (0-19) years for the wildlife runs
4269  double BIherb_sum=0;
4270  double BIfi_sum=0;
4271  double BI_sum=0;
4272  double fertilizer_sum=0;
4273  double fertilizer_trade_sum=0;
4274 
4275  totalOptFarmsArea *= 0.0001;//change to ha
4276  totalOptFarmsArea_plant *= 0.0001;
4277  totalOptFarmsArea_pig *= 0.0001;
4278  totalOptFarmsArea_cattle *= 0.0001;
4279  totalOptFarmsArea_other *= 0.0001;
4280 
4281  ofstream ofile ("CropAreasTotal_and_Average.txt", ios::out);
4282  // "This file includes summed (over all optimising farms) areas of each crop during the whole simulation, the average areas " ;
4283  //"(equal to the sum divided by the number of years the simulation was run) and areas as percentage of total optimising farms area.\t" ;
4284  ofile << "CropName\t" << "Total\t" << "Average\t" << "Area_%\t"<< endl;
4285  for(int i=0; i<(int)m_cropTotals_sum.size(); i++){
4286  ofile << pm_data->Get_cropTypes_almass_str(i) << '\t';
4287  ofile << m_cropTotals_sum[i] << '\t';
4288  ofile << m_cropTotals_sum[i]/no_years << '\t';
4289  ofile << m_cropTotals_sum[i]/no_years/totalOptFarmsArea * 100 << '%';
4290  ofile << endl;
4291  }
4292  ofile.close();
4293 
4294  //printing separate files for specific farm types - just areas in %.
4295  ofstream ofile5 ("CropAreas_plant_farms.txt", ios::out);
4296  ofile5 << "CropName\t" << "Area_%\t" << endl; //<< "Total\t" << "Average\t" <<
4297  for(int i=0; i<(int)m_cropTotals_plant_sum.size(); i++){
4298  ofile5 << pm_data->Get_cropTypes_almass_str(i) << '\t';
4299  ofile5 << m_cropTotals_plant_sum[i]/no_years/totalOptFarmsArea_plant * 100 << '%';
4300  ofile5 << endl;
4301  }
4302  ofile5.close();
4303 
4304  ofstream ofile6 ("CropAreas_pig_farms.txt", ios::out);
4305  ofile6 << "CropName\t" << "Area_%\t" << endl; //<< "Total\t" << "Average\t" <<
4306  for(int i=0; i<(int)m_cropTotals_pig_sum.size(); i++){
4307  ofile6 << pm_data->Get_cropTypes_almass_str(i) << '\t';
4308  ofile6 << m_cropTotals_pig_sum[i]/no_years/totalOptFarmsArea_pig * 100 << '%';
4309  ofile6 << endl;
4310  }
4311  ofile6.close();
4312 
4313  ofstream ofile7 ("CropAreas_cattle_farms.txt", ios::out);
4314  ofile7 << "CropName\t" << "Area_%\t" << endl; //<< "Total\t" << "Average\t" <<
4315  for(int i=0; i<(int)m_cropTotals_cattle_sum.size(); i++){
4316  ofile7 << pm_data->Get_cropTypes_almass_str(i) << '\t';
4317  ofile7 << m_cropTotals_cattle_sum[i]/no_years/totalOptFarmsArea_cattle * 100 << '%';
4318  ofile7 << endl;
4319  }
4320  ofile7.close();
4321 
4322  ofstream ofile8 ("CropAreas_other_farms.txt", ios::out);
4323  ofile8 << "CropName\t" << "Area_%\t" << endl; //<< "Total\t" << "Average\t" <<
4324  for(int i=0; i<(int)m_cropTotals_other_sum.size(); i++){
4325  ofile8 << pm_data->Get_cropTypes_almass_str(i) << '\t';
4326  ofile8 << m_cropTotals_other_sum[i]/no_years/totalOptFarmsArea_other * 100 << '%';
4327  ofile8 << endl;
4328  }
4329  ofile8.close();
4330 
4331 
4332 
4333 
4334  ofstream ofile1 ("PesticideTotals.txt", ios::out);
4335  ofile1 << "CropName\t" << "BIherb\t" << "BIfi\t" << "BI\t" ; //total values within a simulation
4336  ofile1 << "BIherb_yr\t" << "BIfi_yr\t" << "BI_yr\t"; //average values per year (total/no_years)
4337  ofile1 << "BIherb_ha\t" << "BIfi_ha\t" << "BI_ha\t"; //average values per ha (total BI/total area)
4338  ofile1 << endl;
4339  for(int i=0; i<(int)m_crops_summary_BIs.size(); i++){
4340  //ofile1 << m_crops_summary_BIs[i].Tov << '\t';
4341  ofile1 << pm_data->Get_cropTypes_almass_str(i) << '\t';
4342 
4343  ofile1 << m_crops_summary_BIs[i].BIherb << '\t';
4344  BIherb_sum += m_crops_summary_BIs[i].BIherb;
4345 
4346  ofile1 << m_crops_summary_BIs[i].BIfi << '\t';
4347  BIfi_sum += m_crops_summary_BIs[i].BIfi;
4348 
4349  ofile1 << m_crops_summary_BIs[i].BI << '\t';
4350  BI_sum += m_crops_summary_BIs[i].BI;
4351 
4352  ofile1 << m_crops_summary_BIs[i].BIherb/no_years << '\t';
4353  ofile1 << m_crops_summary_BIs[i].BIfi/no_years << '\t';
4354  ofile1 << m_crops_summary_BIs[i].BI/no_years << '\t';
4355  if(!m_cropTotals_sum[i]==0){
4356  ofile1 << m_crops_summary_BIs[i].BIherb/m_cropTotals_sum[i] << '\t';
4357  ofile1 << m_crops_summary_BIs[i].BIfi/m_cropTotals_sum[i] << '\t';
4358  ofile1 << m_crops_summary_BIs[i].BI/m_cropTotals_sum[i] << '\t';
4359  }
4360  else{
4361  ofile1 <<"0\t" << "0\t" << "0\t" ;
4362  }
4363  ofile1 << endl;
4364  }
4365  ofile1.close();
4366 
4367  ofstream ofile2 ("FertilizerTotals.txt", ios::out);
4368  ofile2 << "CropName\t" << "Fertilizer\t" << "Fertilizer_yr\t" << "Fertilizer_ha\t" << endl;
4369  for(int i=0; i<(int)m_crops_summary_BIs.size(); i++){
4370  ofile2 << pm_data->Get_cropTypes_almass_str(i) << '\t';
4371  ofile2 << m_crops_fertilizer[i] << '\t'; //total - all farms, all years
4372  fertilizer_sum += m_crops_fertilizer[i];
4373  fertilizer_trade_sum += m_crops_fertilizer_trade[i];
4374  ofile2 << m_crops_fertilizer[i]/no_years << '\t'; // average per year
4375  if(m_cropTotals_sum[i]!=0){
4376  ofile2 << m_crops_fertilizer[i]/m_cropTotals_sum[i] << '\t'; //average per ha
4377  }
4378  else{
4379  ofile2 << "0\t";
4380  }
4381  ofile2 << endl;
4382  }
4383  ofile2.close();
4384 
4385  //READ the inputs on crop areas in diff model stages
4386  ifstream ifile("crop_results_stages.txt", ios::in);
4387  //check if there is an input file
4388  if ( !ifile.is_open() ) {
4389  cout << "Cannot open input file " << "crop_results_stages.txt" << endl;
4390  char ch;
4391  cin >> ch; //so that it doesn't close immedietly
4392  exit(1);
4393  }
4394  int no_crops = pm_data->Get_noCrops();
4395  //get rid of the crop names
4396  for(int c=0; c<no_crops; c++){
4397  string type;
4398  ifile>>type;
4399  }
4400  for(int stage=0; stage<2; stage++){ //get just the results of the baseline and of the original model
4401  //stage name
4402  string stage_name;
4403  ifile>>stage_name;
4404  //save crop areas
4405  for(int a=0; a<no_crops; a++){
4406  ifile>>m_crop_areas_stages[stage * no_crops + a];
4407  }
4408  }
4409 
4410  //determine the sums of squared differences in crop areas (araes as percentages)
4411  vector<double>sums;
4412  sums.resize(2);
4413  for(int s=0; s<2; s++){
4414  sums[s]=0;
4415  }
4416 
4417  for(int st=0; st<2; st++){
4418  for(int b=0; b<no_crops; b++){
4419  double sq_diff = pow(m_cropTotals_sum[b]/no_years/totalOptFarmsArea * 100 - m_crop_areas_stages[st * no_crops + b]*100, 2);
4420  sums[st] += sq_diff;
4421  }
4422  }
4423 
4424  ofstream ofile3 ("Result_summary.txt", ios::out);
4425  ofile3 << "BIherb\t" << "BIfi\t" << "BI\t" << "Fert\t" << "Fert_trade\t" ; // sum for all crops/no_years/total_opt_farms_area
4426  ofile3 << "Sum of sq. diff: Baseline\t" << "Sum of sq. diff: Original\t"; // << "Sum of sq. diff: New opt.\t" << "Sum of sq. diff: Almass_f.area\t" << "Sum of sq. diff: Crop_choice_ev_yr\t";
4427  //ofile3 << "Sum of sq. diff: Dec.modes\t" << "Sum of sq. diff: Farmer types\t" << "Sum of sq. diff: Types+modes\t" << endl;
4428  ofile3 << BIherb_sum/totalOptFarmsArea/no_years <<'\t';
4429  ofile3 << BIfi_sum/totalOptFarmsArea/no_years <<'\t';
4430  ofile3 << BI_sum/totalOptFarmsArea/no_years <<'\t';
4431  ofile3 << fertilizer_sum/totalOptFarmsArea/no_years <<'\t';
4432  ofile3 << fertilizer_trade_sum/totalOptFarmsArea/no_years <<'\t';
4433  for(int sta=0; sta<2; sta++){
4434  ofile3 << sums[sta] << '\t';
4435  }
4436  ofile3.close();
4437 
4438  //for calibration/sensitivty analysis: comparison to baseline
4439  ofstream ofile4 ("Output.txt", ios::out);
4440  //order: 1.BI 2.BI diff%; 3. BI_abs_diff; 4.fert; 5.fert diff%; 6.fert_abs_diff 7.sum of sq. diff. compared to baseline; 8. weigthed measure
4441  double BIdiff_percent = ((BI_sum/totalOptFarmsArea/no_years/2.2) - 1) *100;//BI in the baseline = 2.2 and is the country level score!
4442  double BIdiffabs = abs(BIdiff_percent);
4443  double fert_diff_percent = ((fertilizer_sum/totalOptFarmsArea/no_years/140.07)-1) * 100;
4444  double fertdiffabs = abs(fert_diff_percent);
4445  //ofile4 << endl;
4446  ofile4 << '\t' << BI_sum/totalOptFarmsArea/no_years <<'\t' << BIdiff_percent << '\t'<< BIdiffabs <<'\t';
4447  ofile4 << fertilizer_sum/totalOptFarmsArea/no_years << '\t' << fert_diff_percent << '\t' << fertdiffabs <<'\t'; //fert in baseline = 140.07 kg/ha
4448  ofile4 << sums[0] << '\t';
4449  ofile4 << 0.2 * abs(BIdiff_percent) + 0.2 * abs(fert_diff_percent) + 0.6 * sums[0] << endl;
4450  ofile4.close();
4451 
4452  //print also areas of all crops...
4453  ofstream ofile9 ("Output_crop_areas_percent.txt", ios::out);
4454  ofile9 << '\t';
4455  for(int i=0; i<(int)m_cropTotals_sum.size(); i++){
4456  ofile9 << m_cropTotals_sum[i]/no_years/totalOptFarmsArea * 100 << '\t'; //print just areas (no crop names!)
4457  }
4458  ofile9 << endl;
4459  ofile9.close();
4460 
4461 
4462 }
4463 
4464 
4466 
4467  //1. make a new rotation: include all rotational crops
4468  vector<TTypesOfVegetation> new_rotation;
4469  TTypesOfVegetation tov;
4470  for(int i=0; i<pm_data->Get_cropTypes_almass_size(); i++){
4471  tov = pm_data->Get_cropTypes_almass(i);
4474  new_rotation.push_back(tov);
4475  }
4476  }
4477 
4478  //2. assign it to each farm's m_rotation
4479  for(int i=0; i<(int)m_farms.size(); i++){
4480  OptimisingFarm * opf;
4481  if(m_farms[i]->GetType() == tof_OptimisingFarm){ //take only optimising farms
4482  opf = dynamic_cast<OptimisingFarm*>(m_farms[i]);
4483  opf->Assign_rotation(new_rotation);
4484  }
4485  }
4486 }
4487 
4489 
4490  //get the shares of certain types. Parameters in the config file.
4491  double profit_proportion = cfg_Profit_max_proportion.value();
4492  double yield_proportion = cfg_Yield_max_proportion.value();
4493  double env_proportion = cfg_Environmentalist_proportion.value();
4494 
4495  //get the number of optimising farms (count them) and make a list of opt farms and its copy
4496  int number_opt_farms=0;
4497  vector <OptimisingFarm*> opt_farms;
4498  vector <OptimisingFarm*> opt_farms_copy;
4499  for(int i=0; i<(int)m_farms.size(); i++){
4500  if(m_farms[i]->GetType()==tof_OptimisingFarm){
4501  number_opt_farms++;
4502  OptimisingFarm * opf = dynamic_cast<OptimisingFarm*>(m_farms[i]);
4503  opt_farms.push_back(opf);
4504  }
4505  }
4506  opt_farms_copy = opt_farms;
4507 
4508  //find the number of farms that should be of a certain type
4509  int number_profit = (int) (profit_proportion/100 * number_opt_farms); // + 0.5); round down - to avoid having a total number of diff types higher than the number of farms
4510  int number_yield = (int) (yield_proportion/100 * number_opt_farms + 0.5);
4511  int number_env = (int) (env_proportion/100 * number_opt_farms + 0.5);
4512 
4513  //see: http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution
4514  random_device rd;
4515  mt19937 gen(rd());
4516 
4517  int jj=0;
4518  int index_for_farm=0;
4519 
4520  //set farms with profit as a main goal
4521  for(int j=jj; j<number_profit; j++){
4522  distribution_type2 dis(0, number_opt_farms - j - 1); //each time we remove one farm, so '-j' and '-1' casue the last element in the list is =size-1.
4523  index_for_farm = dis(gen);
4524  opt_farms_copy[index_for_farm]->Set_main_goal(tofg_profit);
4525  opt_farms_copy.erase(opt_farms_copy.begin() + index_for_farm); //remove the farm from the list after assignign the goal
4526  jj = j;
4527  }
4528  jj++; //need to increase by one here!
4529 
4530  //set farms with yield as a main goal
4531  for(int j = jj; j<number_yield + number_profit; j++){ //start with the value of 'i' as it was after leaving the last for loop!
4532  distribution_type2 dis1(0, number_opt_farms - j - 1); //each time we remove one farm, so '-j'
4533  index_for_farm = dis1(gen);
4534  opt_farms_copy[index_for_farm]->Set_main_goal(tofg_yield);
4535  opt_farms_copy.erase(opt_farms_copy.begin() + index_for_farm); //remove the farm from the list after assignign the goal
4536  jj = j;
4537  }
4538  jj++;
4539 
4540  //set farms with environment as a main goal
4541  int loop_limit = (number_env + number_profit + number_yield > number_opt_farms)? number_opt_farms : number_env + number_profit + number_yield;
4542  for(int j=jj; j<loop_limit; j++){
4543  distribution_type2 dis2(0, number_opt_farms - j - 1); //each time we remove one farm, so '-j'
4544  index_for_farm = dis2(gen);
4545  opt_farms_copy[index_for_farm]->Set_main_goal(tofg_environment);
4546  opt_farms_copy.erase(opt_farms_copy.begin() + index_for_farm); //remove the farm from the list after assignign the goal
4547  }
4548 
4549  //check if there are any farms left without assigned goal
4550  if((int)opt_farms_copy.size()>0){ //it should be not more than 1-2
4551  for(int p=(int)opt_farms_copy.size(); p>0; p--){
4552  opt_farms_copy[p-1]->Set_main_goal(tofg_profit);
4553  }
4554  }
4555 
4556 }
4557 //--------------------------------------------------------------------------------------------
4558 //--------------------------OptimisingFarm----------------------------------------------------
4559 //--------------------------------------------------------------------------------------------
4560 
4561 
4562 void DataForOptimisation::InitializeVector(vector<double>&vector){
4563 
4564  for(int i=0; i<(int)vector.size(); i++){
4565  vector[i] = -1;
4566  }
4567 }
4568 
4574 
4575  int foobar = (cfg_OptimiseBedriftsmodelCrops.value())? (int)toc_Foobar : (int)tov_Undefined; //bedriftsmodel crops/almass crops
4576 
4577  m_cropParameters.resize(foobar*top_Foobar);
4578  m_alfa.resize(foobar*tos_Foobar);
4579  m_beta1.resize(foobar*tos_Foobar);
4580  m_beta2.resize(foobar*tos_Foobar);
4581  m_Nnorm.resize(foobar*tos_Foobar);
4582  m_biomass_factors.resize(foobar*tos_Foobar);
4583  m_fixed.resize(foobar*toof_Foobar);
4584  m_fodder.resize(foobar*toof_Foobar);
4585  m_FUKey.resize(foobar*toof_Foobar);
4586  m_sellingPrice.resize(foobar*toof_Foobar*tos_Foobar);
4587  m_sellingPrice_lastyr.resize(foobar*toof_Foobar*tos_Foobar);
4588  m_rotationMax.resize(foobar*toof_Foobar*tos_Foobar*tofs_Foobar);
4589  m_rotationMin.resize(foobar*toof_Foobar*tos_Foobar*tofs_Foobar);
4590  m_winterMax.resize(toof_Foobar);
4591  m_livestockParameters.resize(toa_Foobar*tolp_Foobar);
4592 
4594  //fill them with -1
4595  InitializeVector (m_cropParameters);
4596  InitializeVector (m_alfa);
4597  InitializeVector (m_beta1);
4598  InitializeVector (m_beta2);
4599  InitializeVector (m_Nnorm);
4600  InitializeVector (m_biomass_factors);
4601  InitializeVector (m_FUKey);
4602  InitializeVector (m_sellingPrice);
4603  InitializeVector (m_rotationMax);
4604  InitializeVector (m_rotationMin);
4605  }
4606 }
4607 
4608 
4610  for(int i=0; i< (int) m_farm_data.size(); i++){
4611  if(m_farm_data[i]->md_almass_no == a_almass_no) return m_farm_data[i] -> md_farmType;
4612  }
4613  g_msg->Warn( WARN_BUG, "almass_no from farms_data doesn't match any of the numbers from farmrefs file", "" );
4614  exit(0);
4615 }
4616 
4617 Livestock::Livestock(TTypesOfAnimals a_animalType, int a_number){
4618  m_animalType=a_animalType;
4619  m_number=a_number;
4620  m_NanimUsable=0;
4621  m_FUdemand=0;
4622 
4623 }
4624 
4629 CropOptimised::CropOptimised(TTypesOfCrops a_cropType, double a_initialArea){
4630  m_cropType=a_cropType;
4631  m_cropType_almass = tov_Undefined; //just in case
4632  m_initialArea=a_initialArea;
4633 }
4634 
4635 CropOptimised::CropOptimised(TTypesOfVegetation a_cropType, double a_initialArea){
4636  m_cropType_almass = a_cropType;
4637  m_cropType = toc_Foobar; //just in case initialize it
4638  m_initialArea=a_initialArea;
4639 }
4640 
4642 
4643 }
4644 
4645 
4646 
4648 
4653  // First we need to assign the permanent crops if any.
4654  if (m_PermCrops.size()>0) {
4655  // We have something to do
4656  for (int i=0; i<(int)m_PermCrops.size(); i++) {
4658  }
4659 
4660  //check if in case there are no rotational crops - all fields have been assigned a perm crop
4661  if(m_area_rot ==0) { //so there's need to check
4662  for(int i=0; i<(int)m_fields.size(); i++){
4663  if(m_fields[i]->GetRotIndex() != -4){ //there is a field that is not assigned a perm crop!
4664  m_fields[i]->SetRotIndex(-4);
4665  TTypesOfVegetation tov = m_PermCrops[0].Tov; //just take the first perm crop?
4666  m_fields[i]->SetVegType(tov, tov_Undefined); //need a tov of one of the assigned perm crops
4667  }
4668  }
4669  }
4670 
4671  }
4672 
4674 }
4675 
4676 OptimisingFarm::OptimisingFarm(FarmManager* a_myfarmmanager, int a_No) : Farm(a_myfarmmanager)
4677 {
4678 
4679 
4680  m_farmtype = tof_OptimisingFarm; //this is almass farm type (and not the optimising farm type - see OptimisingFarm::Initialize)
4681  m_almass_no = a_No;
4682  force_deliberation = false;
4684 
4685  //assign goals - DEFAULT values. Later FarmManager assigns main goals again.
4687  //m_pest_goal = tofg_profit;
4688  //m_fert_goal = tofg_profit;
4689 
4690  //initialize the actual and expected values
4691  m_actual_profit=0;
4692  m_actual_income=0;
4693  m_actual_costs=0;
4695  m_exp_profit=0;
4696  m_exp_income=0;
4697  m_exp_costs=0;
4699 
4700  //initialize the dec. mode counters
4701  m_decision_mode_counters.resize(4);
4703 
4704  m_animals_numbers.resize(0);
4705  animals_no = 0;
4706 
4707 }
4708 
4709 
4711 
4712  //assign to each farm: farm type, farm size, real ID and soil type + soil subtype
4713  int size=(int)a_pfm->pm_data->m_farm_data.size();
4714  for(int i=0; i<size; i++){
4715  if(m_almass_no==a_pfm->pm_data->m_farm_data[i]->md_almass_no){
4716  m_farmType=a_pfm->pm_data->m_farm_data[i]->md_farmType;
4717  m_farmSize=a_pfm->pm_data->m_farm_data[i]->md_farmSize;
4718  m_farmRealID=a_pfm->pm_data->m_farm_data[i]->md_farmRealID;
4719  m_soilType=a_pfm->pm_data->m_farm_data[i]->md_soilType;
4720  m_soilSubType=a_pfm->pm_data->m_farm_data[i]->md_soilSubType;
4721  }
4722  }
4723 
4724  //create livestock
4725  for(int i=0; i<toa_Foobar; i++){
4726  int index=-1;
4727  int size=a_pfm->pm_data->Get_livestockNumbersSize();
4728  int j;
4729  for(j=0; j<size; j += (toa_Foobar+1)){
4730  if((a_pfm->pm_data->Get_livestockNumber(j))==m_almass_no){
4731  index=j;
4732  }
4733  }
4734  //test for index!!
4735  if(index==-1){
4736  g_msg->Warn( WARN_BUG, "Farm's almass_no doesn't match any of the numbers within the livestock numbers vector", "" );
4737  exit(0);
4738  }
4739  int index2 = index + 1 + i;
4740  int number = a_pfm->pm_data->Get_livestockNumber(index2);
4741  if (number!=0){
4742  Livestock * p_lvs;
4743  TTypesOfAnimals livestock_type = a_pfm->pm_data->Get_livestockTypes(i);
4744  p_lvs = new Livestock(livestock_type, number);
4745  Set_Livestock(p_lvs);
4746  }
4747  }
4748 
4749  //create crops
4750  int no_crops = (cfg_OptimiseBedriftsmodelCrops.value())? toc_Foobar : a_pfm->pm_data->Get_noCrops(); //bedriftsmodel crops/almass crops
4751 
4752  for(int i=0; i<no_crops; i++){ //crop areas vector contains only the crops that are used, not all tov types!
4753  int index=-1;
4754  int size=a_pfm->pm_data->Get_cropAreasSize();
4755  int j;
4756  for(j=0; j<size; j+=(no_crops+1)){ //+1 becuase in the vector we store also farm numbers
4757  if((a_pfm->pm_data->Get_cropArea(j))==m_almass_no){
4758  index=j;
4759  break;
4760  }
4761  }
4762  //test for index!!
4763  if(index==-1){
4764  g_msg->Warn( WARN_BUG, "Farm's almass_no doesn't match any of the numbers within the crop areas vector", "" );
4765  exit(0);
4766  }
4767  int index2= index + 1 + i;
4768  double area=a_pfm->pm_data->Get_cropArea(index2);
4769 
4770  int foobar = (cfg_OptimiseBedriftsmodelCrops.value())? (int)toc_Foobar : (int)tov_Undefined; //bedriftsmodel crops/almass crops
4771 
4772  CropOptimised *p_crop;
4773  int index3 = -1;
4775  TTypesOfCrops crop_type = a_pfm->pm_data->Get_cropTypes(i);
4776  p_crop = new CropOptimised(crop_type, area);
4777  index3 = foobar*tofs_Foobar*tos_Foobar*m_farmType + foobar*tofs_Foobar*m_soilType + foobar*m_farmSize + crop_type; //crop_type is TTypesOfCrops
4778  }
4779  else{
4780  TTypesOfVegetation crop_type = a_pfm->pm_data->Get_cropTypes_almass(i);
4781  p_crop = new CropOptimised(crop_type, area);
4782  index3 = foobar*tofs_Foobar*tos_Foobar*m_farmType + foobar*tofs_Foobar*m_soilType + foobar*m_farmSize + crop_type; //crop_type is TTypesOfVegetation
4783  }
4784  //added 01.05: save the rot max ad min
4785  p_crop->m_rotationMax = m_OurManager->pm_data->Get_rotationMax(index3);
4786  p_crop->m_rotationMin = m_OurManager->pm_data->Get_rotationMin(index3);
4787 
4788  //add crop to the list of crops
4789  Set_Crop(p_crop);
4790  }
4791 }
4792 
4793 AnimalFarm::AnimalFarm (FarmManager* a_fred, int a_No): OptimisingFarm(a_fred, a_No)
4794 {
4795  m_fakeCrop = new CropOptimised(); //("FakeCrop", 0)
4796  cash_crops_allowed = true;
4797 }
4798 
4799 NonAnimalFarm::NonAnimalFarm (FarmManager* a_myfarmmanager, int a_No): OptimisingFarm(a_myfarmmanager, a_No){
4800  ;
4801 }
4802 
4803 OptimisingPigFarm::OptimisingPigFarm(FarmManager* a_myfarmmanager, int a_No):AnimalFarm(a_myfarmmanager, a_No){
4804 
4805 }
4806 
4807 OptimisingCattleFarm::OptimisingCattleFarm(FarmManager* a_myfarmmanager, int a_No):AnimalFarm(a_myfarmmanager, a_No){
4808 }
4809 
4810 OptimisingPlantFarm::OptimisingPlantFarm(FarmManager* a_myfarmmanager, int a_No):NonAnimalFarm(a_myfarmmanager, a_No){
4811 
4812 }
4813 
4814 OptimisingOtherFarm::OptimisingOtherFarm(FarmManager* a_myfarmmanager, int a_No):NonAnimalFarm(a_myfarmmanager, a_No){
4815 }
4816 
4817 void OptimisingFarm::Init(ofstream * ap_output_file){
4818 
4819  int foobar = (cfg_OptimiseBedriftsmodelCrops.value())? (int)toc_Foobar : (int)tov_Undefined;
4820 
4821  FarmLevelCalculation(); //could stay in the constructor, but for clarity should be here
4822  createCropsLists(foobar);
4823  OptimiseFarm(foobar);
4824  Print_FarmVariables(ap_output_file);
4825 
4828  Make_rotations();
4829  }
4830  else{ //need to create almass crop vector and do all the things that are done otherwise in Make_rotations
4833  m_rotation.push_back(tov_SpringBarley); //put there one crop for the hidden year - m_rotation is used to initialize
4834 
4835  //deal with perm crops (copied from make rotations):
4836  int area_perm = 0; //sum of areas of permanent crops
4837  int no_perm=0;
4838  for(int i = 0; i < (int)m_crops_almass.size(); i++){
4839  TTypesOfVegetation tov = m_crops_almass[i].Tov;
4840 
4842  tov==tov_PermanentGrassLowYield || tov==tov_YoungForest || tov==tov_OrchardCrop) { //|| tov==tov_Orchard
4843  int pct = (int)(m_crops_almass[i].Number + 0.5); //round a double to int
4844  PermCropData pcd = {tov, pct};
4845  m_PermCrops.push_back(pcd);
4846  no_perm++;
4847  area_perm += pct;
4848  }
4849  }
4850  }
4852  Print_rotations(ap_output_file);
4853  }
4854 
4855 }
4856 
4860  int sum_centroidx = 0;
4861  int sum_centroidy = 0;
4862  int no_fields = (int)m_fields.size();
4863  for (int i=0; i<no_fields; i++){
4864  sum_centroidx += m_fields[i]->GetCentroidX();
4865  sum_centroidy += m_fields[i]->GetCentroidY();
4866  }
4867  m_farm_centroidx = sum_centroidx/no_fields;
4868  m_farm_centroidy = sum_centroidy/no_fields;
4869 }
4870 
4872 
4874  return true;
4875  }
4876  else{
4877  double BIherb = findCropByName_almass (a_tov_type)->m_BIHerb;
4878  if (BIherb > 0) return true;
4879  else return false;
4880  }
4881 }
4882 
4884 
4886  return true;
4887  }
4888  else{
4889  double BIfi = findCropByName_almass (a_tov_type)->m_BIFi;
4890  if (BIfi > 0) return true;
4891  else return false;
4892  }
4893 }
4894 
4896 
4897  if(m_main_goal==tofg_yield){ // || m_pest_goal == tofg_yield){ //in case we give farmers different goals - include also the pest_goal
4899  }
4900  else return 1; //for other farmer types
4901 }
4902 
4904 
4908  int no_farmers = (int)m_neighbours.size();
4909 
4910  if(no_farmers!=0){ //if the list is empty - no neighbours
4911  bool ok=false;
4912  vector<OptimisingFarm*>neighbours_copy = m_neighbours;
4913  for(int a=0; ok==false && neighbours_copy.size()>0; a++){
4914  srand ((unsigned)time(NULL)); //warning?
4915  int neighbour = rand() % (no_farmers-a); //returns a random int number from the range: <0, no_farmers-1-a> - need to subtract those remved from the list-there is 'a' removed neighbours
4916  m_previously_imitated_neighbour = neighbours_copy[neighbour];
4917  if(m_farmSize==tofs_Private){ //then look just at the soil type
4918  if(m_soilType!=tos_Clay){ //private with sand or other soil
4921  ok=true; //found somebody to imitate
4922  }
4923  else{
4924  neighbours_copy.erase(neighbours_copy.begin() + neighbour);
4925  }
4926  }
4927  else{ //private with clay
4930  ok=true; //found somebody to imitate
4931  }
4932  else{
4933  neighbours_copy.erase(neighbours_copy.begin() + neighbour);
4934  }
4935  }
4936  }
4937  else if(m_soilType!=tos_Clay){ //business farm with sand or other soil
4940  ok=true; //found somebody to imitate
4941  }
4942  else{
4943  neighbours_copy.erase(neighbours_copy.begin() + neighbour);
4944  }
4945  }
4946  else{ //business farm with clay soil
4949  ok=true; //found somebody to imitate
4950  }
4951  else{
4952  neighbours_copy.erase(neighbours_copy.begin() + neighbour);
4953  }
4954  }
4955 
4956  }
4957  if(ok==true){ //found a neighbouring farmer to imitate
4959  }
4960  else{ //try to find a neighbour with at least the same farm type
4961  neighbours_copy = m_neighbours; //first restart the neighbours copy!
4962  for(int a=0; ok==false && neighbours_copy.size()>0; a++){ //040713 - do not accept a farm with empty rot crops
4963  srand ((unsigned)time(NULL)); //warning?
4964  int neighbour = rand() % (no_farmers-a); //returns a random int number from the range: <0, no_farmers-1-a> - need to subtract those remved from the list-there is 'a' removed neighbours
4965  m_previously_imitated_neighbour = neighbours_copy[neighbour];
4967  ok=true;
4968  }
4969  else{
4970  neighbours_copy.erase(neighbours_copy.begin() + neighbour);
4971  }
4972  }
4973  if(ok==true){
4975  }
4976  else{
4977  m_previously_imitated_neighbour = this; //no neighbour that fits - copy yourself
4978  #ifdef _DEBUG
4979  char errornum[ 20 ];
4980  sprintf( errornum, "%d", m_almass_no );
4981  g_msg->Warn( WARN_BUG, "No farm with a matching farm type to imitate: ", errornum );
4982  #endif
4984  }
4985  }
4986  }
4987 
4988 
4989  else{ //no neighboring farmers //just set yourself
4992  }
4993 }
4994 
4996 
4998 
4999 }
5000 
5006  //pick a farmer to copy (imitation startegy)/ or compare with and possibly copy (social comparison strategy) if this is the first time this function is called: year 8
5007  if(g_date->GetYearNumber() == 8){
5009  }
5010 
5011  //1. get the values of parameters
5012  double min_certainty = cfg_Min_certainty.value();
5013  if(cfg_OnlyDeliberation.value()) min_certainty = 0;
5014 
5015  //2. determine the satisfaction level: already done in the ActualProfit()
5016 
5017  //3. determine the certainty level
5018  double sum_of_sat_levels=0;
5019  for(int i=0; i<5; i++){
5020  sum_of_sat_levels += m_previous_satisfaction_levels[i];
5021  }
5022  m_certainty_level = sum_of_sat_levels/5.0; // i.e. take 5 years into account
5023 
5024  //4. choose the decision mode
5025  //'if' for forcing deliberation:
5026  if(force_deliberation){ //do the same as when deliberation is chosen normally
5028  m_totalFUdemand=m_totalFUdemandBefore; //restart the fodder demand to the original value
5029  m_totalFUgrown = 0; //restart
5031  Make_almass_crops_vector(); //makes m_crops_almass
5032  Make_rotational_crops(); //makes new m_rotational_crops - based on m_crops_almass
5034  force_deliberation=false;
5035  }
5036  else{
5037  if(m_certainty_level < min_certainty){
5038  if(m_need_satisfaction_level == 1 ){ //IMITATION (high sat., low cert.)
5040  //now imitate:
5042  m_rotational_crops_copy = m_rotational_crops; //m_rotational_crops_copy is used for finding a crop for a given field - in Match_crop_to_field function.
5043  } //imitation over
5044 
5045  else{ //SOCIAL COMPARISON - similar to imitation, but includes comparison (low sat., low cert.)
5047  //compare yourself to the neighbour: this depends on your goal
5048  bool imitate=false;
5049  if(m_main_goal == tofg_profit){
5050  if(m_actual_profit < m_previously_imitated_neighbour->Get_actual_profit()){
5051  imitate=true;
5052  }
5053  }
5054  else if (m_main_goal == tofg_yield){
5055  if(m_actual_aggregated_yield < m_previously_imitated_neighbour->Get_actual_aggregated_yield()){
5056  imitate=true;
5057  }
5058  }
5059  else if (m_main_goal == tofg_environment) {
5060  if(m_actual_aggregated_yield < m_previously_imitated_neighbour->Get_actual_aggregated_yield() && m_actual_profit < m_previously_imitated_neighbour->Get_actual_profit()){//compare both
5061  imitate=true;
5062  }
5063  }
5064 
5065  if(imitate){
5067  }
5068  //else: just continue
5069  m_rotational_crops_copy = m_rotational_crops; //this happens for both cases - imitate or not
5070  } //social comparison over
5071  } //high uncertainty
5072 
5073  else{ //low uncertainty (= high certainty)
5074  int value_for_satisfaction = 1; //1 for a simulation with not only deliberation
5075  if(cfg_OnlyDeliberation.value()) value_for_satisfaction = 10; //10 - then everybody deliberates
5076  if(m_need_satisfaction_level == value_for_satisfaction){ //REPETITION (high sat., high cert.)
5078  //continue with the same set of crops - see line after else!
5079  }
5080  else{ //DELIBERATION - i.e. optimise to make a new m_rotational_crops (low sat., high cert.)
5082  m_totalFUdemand=m_totalFUdemandBefore; //restart the fodder demand to the original value
5083  m_totalFUgrown = 0; //restart
5085  Make_almass_crops_vector(); //makes m_crops_almass
5086  Make_rotational_crops(); //makes new m_rotational_crops - based on m_crops_almass
5087  }
5088  m_rotational_crops_copy = m_rotational_crops; //do this for both cases
5089  }
5090  }
5091 }
5092 
5094  createVariableCrops(a_foobar);
5095 }
5096 
5097 void AnimalFarm::createCropsLists(int a_foobar){
5099  createFodderCrops(a_foobar);
5100 }
5101 
5105  int n = (int)m_crops.size();
5106  for (int i=0; i < n; ++i) {
5107  int crop_type=(cfg_OptimiseBedriftsmodelCrops.value())? (int)m_crops[i]->m_cropType : (int)m_crops[i]->m_cropType_almass;
5108  int index=a_foobar*m_farmType + crop_type;
5109  if (m_OurManager->pm_data->Get_fixed(index)){ //if the crop is fixed, attach it to the list fixedCrops
5110  m_fixedCrops.push_back(m_crops[i]);
5111  }
5112  else{
5113  CropSort cs = {0., m_crops[i]}; //an object with a key and a pointer to crop
5114  m_variableCrops.push_back(cs);
5115  }
5116  }
5117 }
5118 
5122  int n = (int)m_crops.size();
5123  for (int i=0; i < n; ++i) {
5124  int crop_type=(cfg_OptimiseBedriftsmodelCrops.value())? (int)m_crops[i]->m_cropType : (int)m_crops[i]->m_cropType_almass;
5125  int index = a_foobar*m_farmType + crop_type;
5126  if(m_OurManager->pm_data->Get_fodder(index)){ //if the crop is a fodder crop...
5127  if(!(m_OurManager->pm_data->Get_fixed(index))){ //check if it is not fixed and attach it to the list
5128  CropSort cs={0., m_crops[i]};
5129  m_fodderCrops.push_back(cs);
5130  }
5131  }
5132  }
5133 }
5134 
5137 
5138  findTotalArea();
5139  findTotalNanim();
5140  findNanim();
5141  findFodderDemand(); //this function cannot be called in the constructor!
5143  preventCashCrops();
5144  }
5145 }
5146 
5152  m_totalArea=0.;
5153  for (int i=0; i< (int) m_crops.size(); i++) {
5154  m_totalArea+=m_crops[i]->m_initialArea;
5155  }
5157 
5158  if(!cfg_UseBedriftsmodelFarmAreas.value()){ //almass farm areas used: just sum the fields area
5159  double area_copy = m_totalArea; //ha
5160  m_totalArea = GetAreaDouble()/10000; //change from sq m to ha
5161  m_area_scaling_factor = m_totalArea/area_copy;
5162  }
5163  //otherwise do nothing: total area = sum of initial crop areas (see the for loop)
5164 }
5165 
5169  m_totalNanim = 0;
5170  for (int i=0; i< (int) m_livestock.size(); i++){
5171  string str_AUKey="AUKey";
5172  string str_Nusable="Nusable";
5173  TTypesOfAnimals index=m_livestock[i]->m_animalType;
5174  double AUKey = m_OurManager->pm_data->Get_livestockParameter(tolp_Foobar*index + m_OurManager->TranslateLivestockParametersCodes(str_AUKey)); //Number of animal units (AU, DE-dyreenheder) -> hkg N per year
5175  double Nusable = m_OurManager->pm_data->Get_livestockParameter(tolp_Foobar*index + m_OurManager->TranslateLivestockParametersCodes(str_Nusable)); // [%] Usable fertilizer from livestock
5176  double number = m_livestock[i]->m_number;
5177 
5178  if(!cfg_UseBedriftsmodelFarmAreas.value()){ //almass farm areas - need to scale the livestock numbers; we don't even have to take integer...
5179  number *= m_area_scaling_factor;
5180  }
5181 
5182  double NanimUsable = number*AUKey*Nusable*100; // [1*hkg/yr*1*100 = kg/yr] Usable fertilizer from livestock
5183  m_livestock[i]->m_NanimUsable = NanimUsable;
5184  m_totalNanim += NanimUsable;
5185  }
5186 }
5187 
5191  }
5192 
5196  m_totalFUdemand=0;
5197  for(int i=0; i< (int) m_livestock.size(); i++){
5198  string str_FUuKey="FUuKey";
5199  TTypesOfAnimals index=m_livestock[i]->m_animalType;
5200  double FUuKey=m_OurManager->pm_data->Get_livestockParameter(tolp_Foobar*index + m_OurManager->TranslateLivestockParametersCodes(str_FUuKey)); //number of fodder units needed per one animal per year
5201  double number = m_livestock[i]->m_number;
5202 
5203  if(!cfg_UseBedriftsmodelFarmAreas.value()){ //almass farm areas - need to scale the livestock numbers; we don't even have to take integer...
5204  number *= m_area_scaling_factor;
5205  }
5206 
5207  if(number>0){
5208  double FUdemand=FUuKey*number;
5209  m_livestock[i]->m_FUdemand = FUdemand;
5210  m_totalFUdemand+=FUdemand;
5211  }
5212  }
5213  m_totalFUdemandBefore=m_totalFUdemand; //just to know afterwards the total demand
5214 }
5215 
5217 
5223  m_totalFUdemand=0;
5224  m_totalFUgrown=0;
5225 }
5226 
5228 
5233  CropOptimised *ms = findCropByName_almass ("MaizeSilage");
5234  if(m_totalArea_original < 30){ //cattle farms with area < 30 ha do not have maize silage!
5235  ms->m_rotationMax = 0;
5236  }
5237 
5238  CropOptimised *wwheat = findCropByName_almass ("WinterWheat");
5239  CropOptimised *wrye = findCropByName_almass ("WinterRye");
5240  CropOptimised *srape = findCropByName_almass ("SpringRape");
5241  CropOptimised *wrape = findCropByName_almass ("WinterRape");
5242  CropOptimised *fpeas = findCropByName_almass ("FieldPeas");
5243  CropOptimised *potatoes = findCropByName_almass ("Potatoes");
5244  CropOptimised *potind = findCropByName_almass ("PotatoesIndustry");
5245  CropOptimised *seedg1 = findCropByName_almass ("SeedGrass1");
5246  CropOptimised *seedg2 = findCropByName_almass ("SeedGrass2");
5247 
5249 
5250  wwheat->m_rotationMax = 0;
5251  wrye->m_rotationMax = 0;
5252  srape->m_rotationMax = 0;
5253  wrape->m_rotationMax = 0;
5254  fpeas->m_rotationMax = 0;
5255  potatoes->m_rotationMax = 0;
5256  potind->m_rotationMax = 0;
5257  seedg1->m_rotationMax = 0;
5258  seedg2->m_rotationMax = 0;
5259 
5260  cash_crops_allowed=false;
5261  }
5262  else if(m_soilType==tos_Sand && m_totalArea_original >= 15 && m_soilSubType == 0){ //v. small prob. of having cash crops
5263 
5264  //see: http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution
5265  std::random_device rd;
5266  std::mt19937 gen(rd());
5267  distribution_type2 dis(0, 1);
5268  double random_no = dis(gen);
5269 
5270  if(random_no > 0.1){ //so in 90% of cases
5271  wwheat->m_rotationMax = 0;
5272  wrye->m_rotationMax = 0;
5273  srape->m_rotationMax = 0;
5274  wrape->m_rotationMax = 0;
5275  fpeas->m_rotationMax = 0;
5276  potatoes->m_rotationMax = 0;
5277  potind->m_rotationMax = 0;
5278  seedg1->m_rotationMax = 0;
5279  seedg2->m_rotationMax = 0;
5280 
5281  cash_crops_allowed=false;
5282  }
5283  }
5284  //else nothing - allow cash crops
5285 
5286 }
5287 
5288 void OptimisingFarm::OptimiseFarm(int a_foobar){
5289 
5290  optimizeCrops(a_foobar);
5291  sortCrops(m_variableCrops, "GM" );//ORDER OPTIMISED CROPS WRT HIGHEST GM
5292  randomizeCropList(m_variableCrops, "GM"); //shuffles elements of the list with equal GMs
5293  assignFixed();
5294  sumMinAreas();
5295  determineAreas(a_foobar);
5296 
5297  if(m_farmSize == tofs_Business){
5299  }
5300 
5302 
5304 
5306  m_totalNt=total(tocv_Nt); //total amount of Nt at a farm - summed for all crops
5316  else m_totalProfit = total(tocv_GM);
5317 }
5318 
5320 
5324  for (int i=0; i< (int) m_crops.size(); i++){
5325 
5326  //1. define the benefit; for non-fodder crops it is simply a selling price ;
5327  double benefit;
5328  int crop_type=(cfg_OptimiseBedriftsmodelCrops.value())? (int)m_crops[i]->m_cropType : (int)m_crops[i]->m_cropType_almass;
5329  int index = a_foobar*m_farmType + crop_type;
5330  bool fodder = m_OurManager->pm_data->Get_fodder(index);
5331  if(fodder){
5332  double FUKey = m_OurManager->pm_data->Get_FUKey(index);
5333  benefit = FUKey * cfg_Price_FU.value();
5334  }
5335  else {benefit = m_OurManager->pm_data->Get_sellingPrice(a_foobar*tos_Foobar*m_farmType + a_foobar*m_soilType + crop_type);}
5336 
5337  CropOptimised * crop = m_crops[i]; //define a pointer which is passed in the functions below
5338 
5339  crop->m_benefit = benefit; //added 090114
5340 
5341  //for SA: modify the prices of crops included in the analysis
5342  if(cfg_Sensitivity_analysis.value()){ //modify the prices only if this is a sensitivity analysis/calibration run
5344  if(crop_type==toc_Oats){
5345  if(m_farmType != toof_Pig && m_farmType != toof_Cattle){//don't modify for these farms - for them the price is zero for this crop - becasue it is a fodder crop!
5346  benefit = cfg_Price_Oats.value();
5347  }
5348  }
5349  else if(crop_type==toc_WWheat){ //not fodder
5350  benefit = cfg_Price_WWheat.value();
5351  }
5352  }
5353  else{//almass crop set
5354  if(crop_type==tov_SpringBarley){ //fodder for cattle and pig farms: price is zero if crop is a fodder crop. so changing price will affect only non-animal farms.
5355  if(m_farmType != toof_Pig && m_farmType != toof_Cattle){//don't modify for these farms - for them the price is zero for this crop - becasue it is a fodder crop!
5356  benefit = cfg_Price_SBarley.value();
5357  }
5358  }
5359  else if(crop_type==tov_Oats){ //f for c and p
5360  if(m_farmType != toof_Pig && m_farmType != toof_Cattle){//don't modify for these farms - for them the price is zero for this crop - becasue it is a fodder crop!
5361  benefit = cfg_Price_Oats.value();
5362  }
5363  }
5364  else if(crop_type==tov_WinterBarley){ //f for c and p
5365  if(m_farmType != toof_Pig && m_farmType != toof_Cattle){//don't modify for these farms - for them the price is zero for this crop - becasue it is a fodder crop!
5366  benefit = cfg_Price_WBarley.value();
5367  }
5368  }
5369  else if(crop_type==tov_WinterWheat){ //not fodder
5370  benefit = cfg_Price_WWheat.value();
5371  }
5372  else if(crop_type==tov_Triticale){
5373  if(m_farmType != toof_Cattle){//don't modify for these farms - for them the price is zero for this crop - becasue it is a fodder crop!
5374  benefit = cfg_Price_Triticale.value();
5375  }
5376  }
5377  else if(crop_type==tov_WinterRape){ //not fodder
5378  benefit = cfg_Price_WRape.value();
5379  }
5380  else if(crop_type==tov_SpringRape){ //not fodder
5381  benefit = cfg_Price_SRape.value();
5382  }
5383  }
5384  }
5385 
5386 
5387  //2. optimize the crop
5388  findFertilizer(crop, a_foobar, benefit);
5389  findResponse(crop, a_foobar);
5390  findBIs(crop, benefit);
5391  fixBI(); //added 22.03.13
5392  findMWeedControl(crop);
5393  findYieldLoss(crop);
5394  findGrossMargin(crop, a_foobar, benefit);
5395 
5396  }
5397 }
5398 
5399 
5401 
5402  CropOptimised *CGG1 = findCropByName_almass("CloverGrassGrazed1");
5403  CropOptimised *CGG2 = findCropByName_almass("CloverGrassGrazed2");
5404  CropOptimised *GS1 = findCropByName_almass("SeedGrass1");
5405  CropOptimised *GS2 = findCropByName_almass("SeedGrass2");
5406 
5407  double CGG1area = CGG1->m_areaPercent;
5408  double CGG2area = CGG2->m_areaPercent;
5409  double GS1area = GS1->m_areaPercent;
5410  double GS2area = GS2->m_areaPercent;
5411  if(CGG1area!= CGG2area){ //even if this is a cattle farm - where CGG are fodder - it won't have any effect here since the areas are zero or at min, so there won't be any change.
5412  double area_sum = CGG1area + CGG2area;
5413  double CGG1min = CGG1->m_rotationMin; double CGG2min = CGG2->m_rotationMin;
5414  CGG1->m_areaPercent = area_sum/2; CGG2->m_areaPercent = area_sum/2;
5415  CGG1->m_areaVariable = area_sum/2 - CGG1min; CGG2->m_areaVariable = area_sum/2 - CGG2min;
5416  }
5417  if(GS1area!=GS2area){
5418  double area_sum = GS1area + GS2area;
5419  double GS1min = GS1->m_rotationMin; double GS2min = GS2->m_rotationMin;
5420  GS1->m_areaPercent = area_sum/2; GS2->m_areaPercent = area_sum/2;
5421  GS1->m_areaVariable = area_sum/2 - GS1min; GS2->m_areaVariable = area_sum/2 - GS2min;
5422  }
5423 }
5424 
5425 //-------------------------------------------------------------------------------------
5426 //------------------OPTIMISATION - THE SIMPLIFIED METHOD-------------------------------
5427 //-------------------------------------------------------------------------------------
5428 
5429 void OptimisingFarm::findFertilizer(CropOptimised * a_crop, int a_foobar, double benefit){
5430 
5434  int index = (cfg_OptimiseBedriftsmodelCrops.value())? a_foobar * m_soilType + a_crop->m_cropType : a_foobar * m_soilType + a_crop->m_cropType_almass;
5435 
5436  double beta1=m_OurManager->pm_data->Get_beta1(index);
5437  double beta2=m_OurManager->pm_data->Get_beta2(index);
5438  double nNorm=m_OurManager->pm_data->Get_Nnorm(index);
5439  double priceNt=cfg_Price_Nt.value();
5440 
5441  if(!beta2==0){
5442  a_crop->m_optimalN = -(beta1/beta2)*0.5; //01.03.12 save the optimal free fertilizer
5443  }
5444  else{ //if beta2 is =0, beta1 is also =0 -> so optimum is at 0.
5445  a_crop->m_optimalN = 0;
5446  }
5447 
5448  if(m_main_goal == tofg_profit){
5449 
5450  if(!beta2==0){ //beta2 is not 0
5451  double n1=-(beta1/beta2)*0.5; //optimal fertilizer supposing it's for free
5452  if(m_Nanim >= n1){ //there is more than you need, so check the norm:
5453  if (n1<nNorm){
5454  a_crop->m_n = n1; //apply optimal amount
5455  }
5456  else {
5457  a_crop->m_n = nNorm; //apply max allowed amount
5458  }
5459  a_crop->m_nt = 0; //don't buy fertilizer
5460  }
5461  else { //the optimal amount is larger than Nanim
5462  double nt1= 0.5*(priceNt/(benefit*beta2) - beta1/beta2) - m_Nanim; //optimal fertilizer Nt
5463  if (nt1>0){
5464  double n2=nt1+m_Nanim; //optimal total N
5465  if (n2<nNorm){
5466  a_crop->m_nt = nt1;
5467  a_crop->m_n = n2;
5468  }
5469  else {
5470  double p=nNorm-m_Nanim;
5471  if(p>=0){a_crop->m_nt = p;} //buy the diff between what you have (Nanim) and what is the max allowed
5472  else{a_crop->m_nt = 0;}// your Nanim is higher than the norm!
5473  a_crop->m_n = nNorm; //total amount is the max allowed, Nanim+(nNorm-Nanim)=nNorm
5474  }
5475  }
5476  else { //it doesn't pay off to buy fertilizer, so just use Nanim
5477  if(m_Nanim<=nNorm){a_crop->m_n = m_Nanim;} //apply fertilizer
5478  else {a_crop->m_n = nNorm;}
5479  a_crop->m_nt = 0;
5480  }
5481  }
5482  }
5483  else{ //beta2=0, so don't apply fertilizer, but in this model - apply Nanim if there is any
5484  if(m_Nanim<=nNorm){a_crop->m_n = m_Nanim;} //apply fertilizer
5485  else {a_crop->m_n = nNorm;}
5486  a_crop->m_nt = 0;
5487  }
5488 
5489  }
5490 
5491  else if (m_main_goal == tofg_yield) { //modified profit optimization algorithm
5492  if(!beta2==0){ //beta2 is not 0
5493  double n1=-(beta1/beta2)*0.5; //optimal fertilizer supposing it's for free
5494  if(m_Nanim >= n1){ //there is more than you need, so check the norm:
5495  if (n1<nNorm){
5496  a_crop->m_n = n1; //apply optimal amount
5497  }
5498  else {
5499  a_crop->m_n = nNorm; //apply max allowed amount
5500  }
5501  a_crop->m_nt = 0; //don't buy fertilizer
5502  }
5503  else { //the optimal amount is larger than Nanim
5504  if(n1>=nNorm){
5505  if(m_Nanim > nNorm){a_crop->m_nt = 0;}
5506  else{a_crop->m_nt = nNorm - m_Nanim;}//buy the diff between what you have (Nanim) and what is the max allowed
5507  a_crop->m_n = nNorm; //total amount is the max allowed
5508  }
5509  else{
5510  a_crop->m_nt = n1 - m_Nanim;
5511  a_crop->m_n = n1;
5512  }
5513  }
5514  }
5515  else{ //beta2=0, so don't apply fertilizer, but in this model - apply Nanim if there is any
5516  if(m_Nanim<=nNorm){a_crop->m_n = m_Nanim;} //apply fertilizer
5517  else {a_crop->m_n = nNorm;}
5518  a_crop->m_nt = 0;
5519  }
5520 
5521  }
5522  else if (m_main_goal == tofg_environment) { //apply less than a norm: the code copied from yield max - the only change is in calculation of n1 - mulitplied by 0.8.
5523  if(!beta2==0){ //beta2 is not 0
5524  double n1=-(beta1/beta2)*0.5 * cfg_Env_fert_multiplier.value(); //optimal fertilizer supposing it's for free; multiplier - to make this type use less fertilizer
5525  if(m_Nanim >= n1){ //there is more than you need, so check the norm:
5526  if (n1<nNorm){
5527  a_crop->m_n = n1; //apply optimal amount
5528  }
5529  else {
5530  a_crop->m_n = nNorm; //apply max allowed amount
5531  }
5532  a_crop->m_nt = 0; //don't buy fertilizer
5533  }
5534  else { //the optimal amount is larger than Nanim
5535  if(n1>=nNorm){
5536  if(m_Nanim > nNorm){a_crop->m_nt = 0;}
5537  else{a_crop->m_nt = nNorm - m_Nanim;}//buy the diff between what you have (Nanim) and what is the max allowed
5538  a_crop->m_n = nNorm; //total amount is the max allowed
5539  }
5540  else{
5541  a_crop->m_nt = n1 - m_Nanim;
5542  a_crop->m_n = n1;
5543  }
5544  }
5545  }
5546  else{ //beta2=0, so don't apply fertilizer, but in this model - apply Nanim if there is any
5547  if(m_Nanim<=nNorm){a_crop->m_n = m_Nanim;} //apply fertilizer
5548  else {a_crop->m_n = nNorm;}
5549  a_crop->m_nt = 0;
5550  }
5551  }
5552 }
5553 
5554 void OptimisingFarm::findResponse (CropOptimised * a_crop, int a_foobar){
5555 
5559  int index = (cfg_OptimiseBedriftsmodelCrops.value())? a_foobar * m_soilType + a_crop->m_cropType : a_foobar * m_soilType + a_crop->m_cropType_almass;
5560 
5561  double beta1=m_OurManager->pm_data->Get_beta1(index);
5562  double beta2=m_OurManager->pm_data->Get_beta2(index);
5563  double alfa=m_OurManager->pm_data->Get_alfa(index);
5564 
5565  double ntotal=a_crop->m_n;
5566  double resp1=alfa + beta1*ntotal + beta2*pow(ntotal,2);
5567  a_crop->m_resp = resp1;
5568 }
5569 
5570 void OptimisingFarm::findBIs(CropOptimised * a_crop, double benefit){
5576  int index = (cfg_OptimiseBedriftsmodelCrops.value())? (int)a_crop->m_cropType : (int)a_crop->m_cropType_almass;
5577 
5578  double alfaFi = crop_parameter(index, "AlfaFi");
5579  double alfaHerb = crop_parameter(index, "AlfaHerb");
5580  double alfaG = crop_parameter(index, "AlfaG");
5581  double alfaH = crop_parameter(index, "AlfaH");
5582  double alfaW = crop_parameter(index, "AlfaW");
5583  double betaFi = crop_parameter(index, "BetaFi");
5584  double betaHerb = crop_parameter(index, "BetaHerb");
5585 
5586  double priceFi = crop_parameter(index, "PriceFi");
5587  double priceHerb = crop_parameter(index, "PriceHerb");
5588  double priceG = crop_parameter(index, "PriceG");
5589  double priceH = crop_parameter(index, "PriceH");
5590  double priceW = crop_parameter(index, "PriceW");
5591 
5592  double resp1=a_crop->m_resp;
5593 
5594  if(alfaHerb>0){//make sure it is not zero!it is for Fodder beet
5595  double BIHerbMax = betaHerb/alfaHerb;
5596  double gainHerb = 0;
5597  double BIHerb = 0;
5598 
5599  if(m_main_goal == tofg_profit){
5600  gainHerb = benefit*resp1*alfaHerb/100 + priceG*alfaG + priceH*alfaH + priceW*alfaW;
5601  BIHerb = (gainHerb>priceHerb)? BIHerbMax : 0;
5602  a_crop->m_BIHerb = BIHerb;
5603  }
5604  else if (m_main_goal == tofg_yield){
5605  a_crop->m_BIHerb = BIHerbMax; //12.12.12
5606  }
5607  else if (m_main_goal == tofg_environment){
5608  gainHerb = benefit*resp1*alfaHerb/100 + priceG*alfaG + priceH*alfaH + priceW*alfaW;
5609  BIHerb = (gainHerb> (priceHerb * cfg_Env_pest_multiplier.value()))? BIHerbMax : 0;
5610  a_crop->m_BIHerb = BIHerb;
5611  }
5612  }
5613  else a_crop->m_BIHerb = 0; //BI for fodder beet in the original model (Bedriftsmodel)
5614 
5615  if(alfaFi>0){
5616  double BIFiMax = betaFi/alfaFi;
5617  double gainFi = 0;
5618  double BIFi = 0;
5619  if(m_main_goal == tofg_profit){
5620  gainFi = benefit*resp1*alfaFi/100;
5621  BIFi = (gainFi > priceFi) ? BIFiMax : 0;
5622  a_crop->m_BIFi = BIFi;
5623  }
5624  else if (m_main_goal == tofg_yield){
5625  a_crop->m_BIFi = BIFiMax;
5626  }
5627  else if (m_main_goal == tofg_environment){
5628  gainFi = benefit*resp1*alfaFi/100;
5629  if (gainFi > (priceFi * cfg_Env_pest_multiplier.value())){
5630  BIFi = BIFiMax;
5631  }
5632  else{
5633  BIFi = 0;
5634  }
5635  a_crop->m_BIFi = BIFi;
5636  }
5637  }
5638  else a_crop->m_BIFi = 0;
5639 
5640  double BIFi = a_crop->m_BIFi;
5641  double BIHerb = a_crop->m_BIHerb;
5642  double BI = BIFi+BIHerb;
5643  a_crop->m_BI = BI;
5644 }
5645 
5647 
5648  if(cfg_OptimiseBedriftsmodelCrops.value()){ //b. crops
5649  CropOptimised *fodderBeet = findCropByName ("FodderBeet");
5650  CropOptimised *sugarBeet = findCropByName ("SugarBeet");
5651  CropOptimised *potato = findCropByName ("Potato");
5652  CropOptimised *potatoFood = findCropByName ("PotatoFood");
5653 
5654  fodderBeet->m_BIHerb = 2.28; //seems it's constant - in the results of Bedriftsmodel, but herbicide parameters are = zero!
5655  sugarBeet->m_BIHerb = 2.28;
5656  fodderBeet->m_BI = fodderBeet->m_BIFi + fodderBeet->m_BIHerb;
5657  sugarBeet->m_BI = sugarBeet->m_BIFi + sugarBeet->m_BIHerb;
5658 
5659  //potatoes - everything fixed
5660  potato->m_BIHerb = 1.41; potato->m_BIFi = 9.28; potato->m_BI = 10.69;
5661  potatoFood->m_BIHerb = 1.41; potatoFood->m_BIFi = 9.28; potatoFood->m_BI = 10.69;
5662  }
5663  else{ //almass crops
5664  CropOptimised *FodderBeet = findCropByName_almass ("FodderBeet");
5665  CropOptimised *PotatoesIndustry = findCropByName_almass ("PotatoesIndustry");
5666  CropOptimised *Potatoes = findCropByName_almass ("Potatoes");
5667 
5668  FodderBeet->m_BIHerb = 2.28; //the values have to be now like in the bedriftsmodel //modified probability
5669  FodderBeet->m_BI = FodderBeet->m_BIHerb + FodderBeet->m_BIFi;
5670  PotatoesIndustry->m_BIHerb = 1.41; PotatoesIndustry->m_BIFi = 9.28; PotatoesIndustry->m_BI = 10.69;
5671  Potatoes->m_BIHerb = 1.41; Potatoes->m_BIFi = 9.28; Potatoes->m_BI = 10.69;
5672  }
5673 
5674 }
5675 
5680  int index = (cfg_OptimiseBedriftsmodelCrops.value())? (int) a_crop->m_cropType : (int) a_crop->m_cropType_almass;
5681 
5682  double betaG = crop_parameter(index, "BetaG");
5683  double betaH = crop_parameter(index, "BetaH");
5684  double betaW = crop_parameter(index, "BetaW");
5685  double alfaG = crop_parameter(index, "AlfaG");
5686  double alfaH = crop_parameter(index, "AlfaH");
5687  double alfaW = crop_parameter(index, "AlfaW");
5688  double BIHerb = a_crop->m_BIHerb;
5689 
5690  double grooming, hoeing, weeding =0;
5691  double g = betaG - BIHerb*alfaG;
5692  double h = betaH - BIHerb*alfaH;
5693  double w = betaW - BIHerb*alfaW;
5694  double BIHerbCorr = BIHerb;
5695 
5696  if(g <= 0){
5697  grooming=0;
5698  if(alfaG!=0) BIHerbCorr=betaG/alfaG;
5699  }
5700  else{grooming=g;}
5701  if(h <= 0){
5702  hoeing=0;
5703  if(betaH/alfaH < BIHerbCorr) BIHerbCorr=betaH/alfaH;
5704  }
5705  else{hoeing=h;}
5706  if(w <= 0){
5707  weeding=0;
5708  if(betaW/alfaW < BIHerbCorr) BIHerbCorr = betaW/alfaW;
5709  }
5710  else{weeding=w;}
5711 
5712 
5713  a_crop->m_grooming = grooming;
5714  a_crop->m_hoeing = hoeing;
5715  a_crop->m_weeding = weeding;
5716  if(BIHerbCorr < BIHerb){
5717  a_crop->m_BIHerb = BIHerbCorr;
5718  a_crop->m_BI = a_crop->m_BIHerb + a_crop->m_BIFi;
5719  }
5720 
5721 }
5722 
5728  int index = (cfg_OptimiseBedriftsmodelCrops.value())? (int) a_crop->m_cropType : (int) a_crop->m_cropType_almass;
5729 
5730  double alfaFi = crop_parameter(index, "AlfaFi");
5731  double alfaHerb = crop_parameter(index, "AlfaHerb");
5732  double betaFi = crop_parameter(index, "BetaFi");
5733  double betaHerb = crop_parameter(index, "BetaHerb");
5734 
5735  double BIHerb=a_crop->m_BIHerb;
5736  double BIFi=a_crop->m_BIFi;
5737 
5738  double lossHerb = betaHerb - alfaHerb*BIHerb;
5739  a_crop->m_lossHerb = lossHerb;
5740 
5741  double lossFi = betaFi - alfaFi*BIFi;
5742  a_crop->m_lossFi = lossFi;
5743 
5744  double totalLoss = lossHerb + lossFi;// [%]
5745  a_crop->m_totalLoss = totalLoss;
5746 }
5747 
5748 void OptimisingFarm::findGrossMargin(CropOptimised * a_crop, int a_foobar, double benefit){
5752  int index = (cfg_OptimiseBedriftsmodelCrops.value())? (int) a_crop->m_cropType : (int) a_crop->m_cropType_almass;
5753 
5754  double priceFi = crop_parameter(index, "PriceFi");
5755  double priceHerb =crop_parameter(index, "PriceHerb");
5756  double priceG =crop_parameter(index, "PriceG");
5757  double priceH =crop_parameter(index, "PriceH");
5758  double priceW =crop_parameter(index, "PriceW");
5759  double priceLM =crop_parameter(index, "PriceLM");
5760  double subsidy =crop_parameter(index, "Subsidy");
5761 
5762  double resp = a_crop->m_resp;
5763  double BIHerb = a_crop->m_BIHerb;
5764  double BIFi = a_crop->m_BIFi;
5765  double grooming = a_crop->m_grooming;
5766  double hoeing = a_crop->m_hoeing;
5767  double weeding = a_crop->m_weeding;
5768  double totalLoss = a_crop->m_totalLoss;
5769  double nt = a_crop->m_nt;
5770  double priceNt = cfg_Price_Nt.value();
5771 
5772  double income_ha = benefit*resp*(1-totalLoss/100)+subsidy;
5773  double costs_ha = BIHerb*priceHerb + BIFi*priceFi + grooming*priceG + hoeing*priceH + weeding*priceW + nt*priceNt + priceLM;
5774  double profit = income_ha - costs_ha;
5775 
5776  a_crop->m_costs_ha = costs_ha;
5777  a_crop->m_GM_Savings = profit;
5778 
5779  //29.02.12
5780  int index1 = (cfg_OptimiseBedriftsmodelCrops.value())? a_foobar * m_farmType + a_crop->m_cropType : a_foobar * m_farmType + a_crop->m_cropType_almass;
5781  bool fodder = m_OurManager->pm_data->Get_fodder(index1);
5782  if (fodder){
5783  a_crop->m_income_ha = subsidy; //because fodder crops can't be sold
5784  a_crop->m_GM = subsidy-costs_ha; //because fodder crops can't be sold
5785  a_crop->m_savings = profit;
5786  }
5787  else{
5788  a_crop->m_income_ha = income_ha;
5789  a_crop->m_GM = profit;
5790  a_crop->m_savings = 0; //this is not a fodder crop!
5791  }
5792 }
5793 
5794 //------------------------------------------------------------------------------//
5795 //-----------------FUNCTIONS RELATED TO CROPS AREA------------------------------//
5796 //------------------------------------------------------------------------------//
5797 
5799 
5803  m_assigned = 0;
5804  for (int i=0; i<(int)m_fixedCrops.size(); i++){//take only crops that are fixed
5805  double area = m_fixedCrops[i]->m_initialArea;
5806 
5807  if(!cfg_UseBedriftsmodelFarmAreas.value()){ //almass farm areas are in use, so scale the fixed crop area
5808  area *= m_area_scaling_factor;
5809  }
5810 
5811  double areaPercent= area/m_totalArea*100;
5812  m_fixedCrops[i]->m_areaPercent = areaPercent; //assign initial area in % for fixed crops
5813  m_assigned += areaPercent;//add areaPercent of a fixed crop to assigned
5814  }//now assigned is a number <0, 100> - excluded from the optimisation
5815 }
5816 
5821  for(int i=0; i<(int)m_variableCrops.size(); i++){
5822  double rotationMin = m_variableCrops[i].crop->m_rotationMin;
5823  m_assigned+=rotationMin; //the min area added to the area already assigned
5824  }
5825 }
5826 
5836  m_grownVariableCrops.clear();
5837 
5838  for(int i=0; i<(int)m_variableCrops.size(); i++){
5839  double areaPercent=0;
5840  double minArea=m_variableCrops[i].crop->m_rotationMin;
5841 
5842  int index1 = (cfg_OptimiseBedriftsmodelCrops.value())? a_foobar*m_farmType + m_variableCrops[i].crop->m_cropType : a_foobar*m_farmType + m_variableCrops[i].crop->m_cropType_almass;
5843 
5844  //next two lines necessary for animal farms' function version
5845  bool fodder = m_OurManager->pm_data->Get_fodder(index1);
5846  if (!fodder){ //this should be checked for animal farms, for other and plant - will always be false
5847  if (m_assigned<100){ //check if there is any area left at a farm
5848  double rotationMax = m_variableCrops[i].crop->m_rotationMax; //same as in else
5849 
5850  if(cfg_Areas_Based_on_Distribution.value()){ //added 170713
5851 
5852  double GMsum = 0;
5853  for(int k=i; k<(int)m_variableCrops.size(); k++){ //do it for each crop (calculate prob) to avoid getting area without any crop. Start with the current crop (k=i), i.e. exclude the crops that are already assigned area.
5854  if(m_variableCrops[k].crop->m_GM > 0 && m_variableCrops[k].crop->m_rotationMax>0){ //make sure you dont include crops that have rot max set to zero! then the area won't sum up to 100%
5855  GMsum += pow (m_variableCrops[k].crop->m_GM, 1);
5856  }
5857  }
5858  double base_prob = 0;
5859  if(m_variableCrops[i].crop->m_GM > 0){
5860  base_prob = pow(m_variableCrops[i].crop->m_GM, 1)/GMsum;
5861  }
5862  else base_prob = 0;
5863 
5864  //draw a random number
5865  std::random_device rd;
5866  distribution_type3 dis(-1.0, 1.0);
5867  std::mt19937 engine(rd());
5868  double random_number = dis(engine);
5869  if(base_prob == 1) random_number = 0; // this is the last crop on the list - don't manipulate the area
5870  double area_1 = base_prob * (1 + 0.2 * random_number) * (100 - m_assigned); //take only a percent of the remaining area!
5871  areaPercent = ( area_1 <= rotationMax)? area_1 : rotationMax;
5872  if (areaPercent > 100 - m_assigned) areaPercent = 100 - m_assigned; //added 280813
5873 
5874  }
5875  else{ //standard area assignment
5876  areaPercent = (rotationMax-minArea <= 100-m_assigned)? rotationMax : (100 - m_assigned+minArea); //check if the remaining area (100-assigned) is enough to assign max allowed area for a crop (max-min, which was already assigned, if not - assign the remaining area+min area
5877  }
5878 
5879  m_assigned += areaPercent - minArea; //add the assigned area (final area percent minus minimum; minimum was assigned before) to the total assigned area
5880  if(areaPercent>minArea){m_grownVariableCrops.push_back(m_variableCrops[i].crop);} //this might not be used for other than animal farms...but maybe - it would be nice to have such a list anyway
5881 
5882  }//m_assigned < 100
5883 
5884  else {areaPercent = minArea;}
5885 
5886  m_variableCrops[i].crop->m_areaPercent = areaPercent;
5887  double areaVar=areaPercent-minArea;
5888  m_variableCrops[i].crop->m_areaVariable = areaVar; //save the value of the area that can be changed! For farms other than animal this maybe could be used just in restrictions functions...
5889  }
5890  else{ //it is a fodder crop, so just save its min area under areaPercent
5891  m_variableCrops[i].crop->m_areaPercent = minArea;
5892  }
5893  }
5894 }
5895 
5896 void AnimalFarm::determineAreas(int a_foobar){
5902 
5903 /*If after this loop area assigned is < 100%, this means that the sum of the maximum allowed areas of non-fodder crops doesn't reach 100%;
5904 in such case introduce a fake crop to fill up the space till 100% (temporarily - until the determineFodderAreas function is called).*/
5905 
5906  m_fakeCropTest=false;
5907  if(m_assigned<100){ //use virtual 'fake crop'
5908  m_fakeCropTest = true;
5909  m_grownVariableCrops.push_back(m_fakeCrop); //append at the end (it is - it must be - the least profitable crop); this list is used in the determineFodderAreas function
5910  double areaP = 100-m_assigned;
5911  m_fakeCrop->m_GM = -1000000;
5912  m_fakeCrop->m_rotationMax = 100;
5913  m_fakeCrop->m_rotationMin = 0;
5914  m_fakeCrop->m_areaPercent = areaP;
5915  m_fakeCrop->m_areaVariable = areaP;
5916  m_assigned += areaP;
5917  }
5918 
5919  sortCrops(m_fodderCrops, "Savings"); //order fodder crops from the highest to the lowest savings resulting from growing a fodder crop - in relation to purchased fodder
5920  randomizeCropList(m_fodderCrops, "Savings"); //shuffles elements of the list with equal Savings
5921 
5922  sortCrops(m_variableCrops, "GM_Savings"); //has to be done before restrictions, but only for animal farms.
5923  randomizeCropList(m_variableCrops, "GM_Savings"); //shuffles elements of the list with equal GM_Savings. Fodder crops have their savings saved under GM_Savings, non-fodder - GM.
5924 
5925  correctFodderDemand(a_foobar); //correct demand for min areas and fixed crops
5926  determineFodderAreas(a_foobar);
5927 }
5928 
5929 //------------------------------------------------------------------------------//
5930 //---------FUNCTIONS RELATED TO RESTRICTIONS ON RELATIVE CROP AREAS-------------//
5931 //------------------------------------------------------------------------------//
5932 
5952  //1st restriction: winter rotation
5953  if(!cfg_Areas_Based_on_Distribution.value()){ //if this is true, skip this restriction
5955  }
5956 
5957  //2nd restriction: max share of winter crops area
5958  checkWinterCrops();
5959 
5960  if (!cfg_OptimiseBedriftsmodelCrops.value()){ //just for almass crop mode: make sure cgg1 and cgg2, sgg1 and sgg2 - have equal areas. added 26.03.13 -function since 110613
5961  Check_SG_and_CGG();
5962  }
5963 }
5964 
5969 
5970  //3rd restriction: cattle crops
5972  checkCattleRotation();
5973  }
5974  else{
5975  checkCattleRotation_almass();
5976  }
5977 
5978 }
5979 
5984 
5985  //restriction - grow winter barley if you have winter rape. Just in Almass crops mode when crops assignement is based on GM distribution:
5987  check_WRape_WBarley();
5988  }
5989 
5990 }
5991 
5993 
5998  CropOptimised *wWheat;
5999  CropOptimised *wRape;
6000  CropOptimised *sRape;
6001  CropOptimised *oats;
6002  CropOptimised *peas;
6003 
6005  wWheat = findCropByName("WWheat");
6006  wRape = findCropByName("WRape");
6007  sRape = findCropByName("SRape");
6008  oats = findCropByName("Oats");
6009  peas = findCropByName("Peas"); //fixed
6010  }
6011  else{
6012  wWheat = findCropByName_almass("WinterWheat");
6013  wRape = findCropByName_almass("WinterRape");
6014  sRape = findCropByName_almass("SpringRape");
6015  oats = findCropByName_almass("Oats");
6016  peas = findCropByName_almass("FieldPeas"); //fixed
6017  }
6018 
6019  double areaWWheat = wWheat->m_areaPercent;
6020  double areaWRape = wRape->m_areaPercent;
6021  double areaSRape = sRape->m_areaPercent;
6022  double areaOats = oats->m_areaPercent;
6023  double areaPeas = peas->m_areaPercent;
6024 
6025  double diff = areaWWheat - (areaWRape + areaSRape + areaOats + areaPeas); //difference;
6026  if (diff > 0){ //restriction is not fulfilled
6027  CropSort cs1 = {0., wRape}; //an object with a key for sorting and a pointer to crop
6028  CropSort cs2 = {0., sRape};
6029  CropSort cs3 = {0., oats};
6030  m_rotationCrops.clear();
6031  m_rotationCrops.push_back(cs1);
6032  m_rotationCrops.push_back(cs2);
6033  m_rotationCrops.push_back(cs3);
6034 
6035  sortCrops(m_rotationCrops, "GM"); //sorting the rotation crops wrt GM
6036 
6037  m_variableCrops2 = m_variableCrops; //initialize the new list and remove all 'winter rotation' crops:
6038  for(int s =(int)m_variableCrops2.size()-1; s>=0; s--){
6039  if(m_variableCrops2[s].crop==wWheat || m_variableCrops2[s].crop==wRape || m_variableCrops2[s].crop==sRape || m_variableCrops2[s].crop==oats){
6040  m_variableCrops2.erase(m_variableCrops2.begin() + s);
6041  }
6042  }
6043 
6044  double GM_WWheat = wWheat->m_GM;
6045  double areaMin = wWheat->m_rotationMin;
6046 
6047  for(int i=0; i<(int)m_rotationCrops.size() && diff!=0; i++){
6048  double areaRC = m_rotationCrops[i].crop->m_areaPercent;
6049  double rotationMaxRC = m_rotationCrops[i].crop->m_rotationMax;
6050  if(areaRC < rotationMaxRC){
6051  double GM_RC = m_rotationCrops[i].crop->m_GM;
6052  bool stopInnerLoop = false;
6053 
6054  for(int j=0; j<(int)m_variableCrops2.size() && stopInnerLoop==false; j++){
6055 
6056  double GM_var = m_variableCrops2[j].crop->m_GM;
6057 
6058  if(GM_RC + GM_WWheat < 2*GM_var){
6059  //add the variable crop
6060  double areaVC = m_variableCrops2[j].crop->m_areaPercent;
6061  double rotationMaxVC = m_variableCrops2[j].crop->m_rotationMax;
6062  if(areaWWheat - areaMin >= diff){
6063  if(rotationMaxVC - areaVC >= diff){
6064  areaVC += diff;
6065  areaWWheat -= diff;
6066  diff = 0; //finito
6067  stopInnerLoop = true;
6068  }
6069  else{
6070  areaWWheat -= rotationMaxVC - areaVC;
6071  diff -= (rotationMaxVC - areaVC);
6072  areaVC = rotationMaxVC;
6073  }
6074  }
6075  else{
6076  if(rotationMaxVC - areaVC >= areaWWheat - areaMin){
6077  areaVC += areaWWheat - areaMin;
6078  diff -= (areaWWheat - areaMin);
6079  areaWWheat = areaMin; // now you can only add rot crops! so stop the inner loop
6080  stopInnerLoop = true;
6081  }
6082  else{
6083  areaWWheat -= rotationMaxVC - areaVC;
6084  diff -= (rotationMaxVC - areaVC);
6085  areaVC = rotationMaxVC;
6086  }
6087  }
6088  m_variableCrops2[j].crop->m_areaPercent = areaVC;
6089  }
6090 
6091  else{
6092  //add rotational crop
6093 
6094  if(areaWWheat - areaMin >= diff/2){
6095  if(rotationMaxRC - areaRC >= diff/2){
6096  areaRC += diff/2;
6097  areaWWheat -= diff/2;
6098  diff = 0; //finito
6099  stopInnerLoop = true;
6100  }
6101  else{
6102  areaWWheat -= rotationMaxRC - areaRC;
6103  diff -= 2 * (rotationMaxRC - areaRC);
6104  areaRC = rotationMaxRC;
6105  stopInnerLoop = true; //take next rotation crop
6106  }
6107  }
6108  else{
6109  if(rotationMaxRC - areaRC >= areaWWheat - areaMin){
6110  areaRC += areaWWheat - areaMin;
6111  diff -= 2 * (areaWWheat - areaMin);
6112  areaWWheat = areaMin; //now you can only add rot crops!//so stop the inner loop:
6113  stopInnerLoop = true;
6114  }
6115  else{
6116  areaWWheat -= rotationMaxRC - areaRC;
6117  diff -= 2 * (rotationMaxRC - areaRC);
6118  areaRC = rotationMaxRC;
6119  stopInnerLoop = true; //take the next rotation crop
6120  }
6121  }
6122  }
6123  }//inner for-loop
6124  m_rotationCrops[i].crop->m_areaPercent = areaRC;
6125  }//if rot crop<rotmax //else - take the next rot crop, i++
6126  }//outer for
6127 
6128  //now the diff can be positive in two cases:
6129 
6130  //1. wwheat area is at zero - need to increase rotation crops - if possible
6131  if(areaWWheat==areaMin && diff > 0){
6132  double diff1=diff;
6134  if(diff1==0) {decreaseCrops(m_variableCrops2, diff);} //do it only if we actually managed to add the diff (=diff1)
6135  //to the rotation crops,i.e. diff1=0; if it's >0, then we added smth, but not enough and restriction can't be fulfilled.Then:
6136  else{
6137  double toCut = diff - diff1;
6139  diff = diff1; //restriction will be broken by diff1
6140  ofstream ofile("Restrictions.txt",ios::app);
6141  ofile << m_almass_no << '\t' << "winter rotation1 restriction broken, WWheat area at 0. Diff is: " << diff << endl;
6142  ofile.close();
6143  }
6144  }
6145 
6146  //2. it was always more profitable to grow rotation crops, but they were not
6147  //enough (maybe at max from the beginning) - increase variable crops, cut wwheat
6148 
6149  if(diff > 0 && areaWWheat - areaMin >= diff){
6150  areaWWheat -= diff;
6152  }
6153 
6154  wWheat->m_areaPercent = areaWWheat;
6155 
6156  }//if
6157 }//end of the function
6158 
6160 
6165  CropOptimised *wWheat;
6166  CropOptimised *wRape;
6167  CropOptimised *sRape;
6168  CropOptimised *oats;
6169  CropOptimised *peas;
6170 
6172  wWheat = findCropByName("WWheat");
6173  wRape = findCropByName("WRape");
6174  sRape = findCropByName("SRape");
6175  oats = findCropByName("Oats");//fodder
6176  peas = findCropByName("Peas"); //fixed
6177  }
6178  else{
6179  wWheat = findCropByName_almass("WinterWheat");
6180  wRape = findCropByName_almass("WinterRape");
6181  sRape = findCropByName_almass("SpringRape");
6182  oats = findCropByName_almass("Oats");//fodder
6183  peas = findCropByName_almass("FieldPeas"); //fixed
6184  }
6185 
6186  double areaWWheat = wWheat->m_areaPercent;
6187  double areaWRape = wRape->m_areaPercent;
6188  double areaSRape = sRape->m_areaPercent;
6189  double areaOats = oats->m_areaPercent;
6190  double areaPeas = peas->m_areaPercent;
6191 
6192  double diff = areaWWheat - (areaWRape + areaSRape + areaOats + areaPeas); //difference;
6193  if (diff > 0){ //restriction is not fulfilled
6194  CropSort cs1 = {0., wRape}; //an object with a key for sorting and a pointer to crop
6195  CropSort cs2 = {0., sRape};
6196  CropSort cs3 = {0., oats};
6197  m_rotationCrops.clear();
6198  m_rotationCrops.push_back(cs1);
6199  m_rotationCrops.push_back(cs2);
6200  m_rotationCrops.push_back(cs3);
6201 
6202  sortCrops(m_rotationCrops, "GM_Savings"); //sorting the rotation crops wrt GM
6203 
6204 
6205  m_variableCrops2 = m_variableCrops; //initiate the new list and remove all 'winter rotation' crops:
6206  for(int s=(int)m_variableCrops2.size()-1; s>=0; s--){
6207  if(m_variableCrops2[s].crop==wWheat || m_variableCrops2[s].crop==wRape || m_variableCrops2[s].crop==sRape || m_variableCrops2[s].crop==oats){
6208  m_variableCrops2.erase(m_variableCrops2.begin() + s);
6209  }
6210  }
6211 
6212  double GM_WWheat = wWheat->m_GM;
6213  double areaMin = wWheat->m_rotationMin;
6214 
6215  for(int i=0; i<(int)m_rotationCrops.size() && diff!=0; i++){
6216  double areaRC = m_rotationCrops[i].crop->m_areaPercent;
6217  double rotationMaxRC = m_rotationCrops[i].crop->m_rotationMax;
6218  double areaBeforeRC = areaRC;
6219  if(areaRC < rotationMaxRC){
6220  double GM_RC = m_rotationCrops[i].crop->m_GM_Savings;
6221  bool stopInnerLoop = false;
6222 
6223  for(int j=0; j<(int)m_variableCrops2.size() && stopInnerLoop==false; j++){
6224 
6225  double GM_var = m_variableCrops2[j].crop->m_GM_Savings;
6226 
6227  if(GM_RC + GM_WWheat < 2 * GM_var){
6228  //add variable
6229  double areaVC = m_variableCrops2[j].crop->m_areaPercent;
6230  double rotationMaxVC = m_variableCrops2[j].crop->m_rotationMax;
6231  double areaBefore = areaVC;
6232  if(areaWWheat - areaMin >= diff){
6233  if(rotationMaxVC - areaVC >= diff){
6234  areaVC += diff;
6235  areaWWheat -= diff;
6236  diff = 0; //finished
6237  stopInnerLoop = true;
6238  }
6239  else{
6240  areaWWheat -= rotationMaxVC - areaVC;
6241  diff -= (rotationMaxVC - areaVC);
6242  areaVC = rotationMaxVC;
6243  }
6244  }
6245  else{
6246  if(rotationMaxVC - areaVC >= areaWWheat - areaMin){
6247  areaVC += (areaWWheat - areaMin);
6248  diff -= (areaWWheat - areaMin);
6249  areaWWheat = areaMin; //now you can only add rot crops! so stop the inner loop
6250  stopInnerLoop=true;
6251  }
6252  else{
6253  areaWWheat -= rotationMaxVC - areaVC;
6254  diff -= (rotationMaxVC - areaVC);
6255  areaVC = rotationMaxVC;
6256  }
6257  }
6258  m_variableCrops2[j].crop->m_areaPercent = areaVC;
6259  //this just in an animal version, add if - checking if area has changed
6260  if(areaVC > areaBefore){
6261  int index = (cfg_OptimiseBedriftsmodelCrops.value())? toc_Foobar*m_farmType + m_variableCrops2[j].crop->m_cropType : tov_Undefined*m_farmType + m_variableCrops2[j].crop->m_cropType_almass;
6262  bool fodder = m_OurManager->pm_data->Get_fodder(index);
6263  if(fodder){ //this is a fodder crop - so you need to buy less fodder - totalFUt
6264  double resp = m_variableCrops2[j].crop->m_resp;
6265  double loss = m_variableCrops2[j].crop->m_totalLoss;
6266  double FUKey = m_OurManager->pm_data->Get_FUKey(index);
6267  double FUha = resp * (1-loss/100) * FUKey; //[ha * hkg/ha * FU/hkg = FU]
6268  double changeFU = (areaVC - areaBefore) * m_totalArea/100 * FUha; //positive
6269  m_totalFUt -= changeFU;
6270  m_totalFUgrown+=changeFU;
6271  }
6272  }
6273  }
6274  else{
6275  //add rotational
6276 
6277  if(areaWWheat - areaMin >= diff/2){
6278  if(rotationMaxRC - areaRC >= diff/2){
6279  areaRC += diff/2;
6280  areaWWheat -= diff/2;
6281  diff = 0; //finito
6282  stopInnerLoop = true;
6283  }
6284  else{
6285  areaWWheat -= rotationMaxRC - areaRC;
6286  diff -= 2 * (rotationMaxRC - areaRC);
6287  areaRC = rotationMaxRC;
6288  stopInnerLoop = true; //take next rotation crop
6289  }
6290  }
6291  else{
6292  if(rotationMaxRC - areaRC >= areaWWheat - areaMin){
6293  areaRC += areaWWheat - areaMin;
6294  diff -= 2 * (areaWWheat - areaMin);
6295  areaWWheat = areaMin; //now you can only add rot crops! so stop the inner loop:
6296  stopInnerLoop = true;
6297  }
6298  else{
6299  areaWWheat -= rotationMaxRC - areaRC;
6300  diff -= 2 * (rotationMaxRC - areaRC);
6301  areaRC = rotationMaxRC;
6302  stopInnerLoop = true; //take the next rotation crop
6303  }
6304  }
6305  }
6306  }//inner for-loop
6307 
6308  m_rotationCrops[i].crop->m_areaPercent = areaRC;
6309  //this just in an animal version, add if - checking if area has changed
6310  if(areaRC>areaBeforeRC){
6311  int index = (cfg_OptimiseBedriftsmodelCrops.value())? toc_Foobar*m_farmType + m_rotationCrops[i].crop->m_cropType : tov_Undefined*m_farmType + m_rotationCrops[i].crop->m_cropType_almass;
6312  bool fodder = m_OurManager->pm_data->Get_fodder(index);
6313  if(fodder){ //this is a fodder crop - so you need to buy less fodder - totalFUt
6314  double resp = m_rotationCrops[i].crop->m_resp;
6315  double loss = m_rotationCrops[i].crop->m_totalLoss;
6316  double FUKey = m_OurManager->pm_data->Get_FUKey(index);
6317  double FUha = resp * (1-loss/100) * FUKey; //[ha * hkg/ha * FU/hkg = FU]
6318  double changeFU = (areaRC - areaBeforeRC) * m_totalArea/100 * FUha; //positive
6319  m_totalFUt -= changeFU;
6320  m_totalFUgrown += changeFU;
6321  }
6322  }
6323  }//if rot crop<rotmax//else - take the next rot crop, i++
6324  }//outer for
6325 
6326  //now the diff can be positive in two cases:
6327 
6328  //1. wwheat area is at zero - need to increase rotation crops - if possible
6329  if(areaWWheat==areaMin && diff>0){
6330  double diff1 = diff;
6332  if(diff1==0) {decreaseCrops(m_variableCrops2, diff);} //do it only if we actually
6333  //managed to diff (=diff1) to the rotation crops,so diff1=0; if it's (0, diff)-then
6334  //we added smth, but not enough and restriction can't be fulfilled...- then...
6335  else{
6336  double toCut = diff-diff1;
6338  diff = diff1; //restriction will be broken by diff1
6339  ofstream ofile("Restrictions.txt",ios::app);
6340  ofile << m_almass_no << '\t' << "winter rotation1 restriction broken. Animal farm. WWheat area at 0. Diff is: " << diff << endl;
6341  ofile.close();
6342  }
6343  }
6344 
6345  //2. it was always more profitable to grow rotation crops, but they were not
6346  //enough (maybe at max from the beginning) - increase variable crops, cut wwheat
6347 
6348  if(diff>0 && areaWWheat-areaMin >= diff){
6349  areaWWheat -= diff;
6351  }
6352 
6353  wWheat->m_areaPercent = areaWWheat;
6354 
6355  }//if
6356 
6357 }//end of the function
6358 
6360 
6366  CropOptimised *wBarley;
6367  CropOptimised *wWheat;
6368  CropOptimised *wRye;
6369  CropOptimised *wRape;
6370  CropOptimised *wCerealSil = NULL; // Prevents warning
6371 
6373  wBarley = findCropByName("WBarley");
6374  wWheat = findCropByName("WWheat");
6375  wRye = findCropByName("WRye");
6376  wRape = findCropByName("WRape"); //should not be decreased - might cause violation of winterRotation restriction
6377  wCerealSil = findCropByName("WCerealSil");
6378  }
6379  else{
6380  wBarley = findCropByName_almass("WinterBarley");
6381  wWheat = findCropByName_almass("WinterWheat");
6382  wRye = findCropByName_almass("WinterRye");
6383  wRape = findCropByName_almass("WinterRape"); //should not be decreased - might cause violation of winterRotation restriction
6384  }
6385 
6386 
6387  double areaWBarley = wBarley->m_areaPercent;
6388  double areaWWheat = wWheat->m_areaPercent;
6389  double areaWRye = wRye->m_areaPercent;
6390  double areaWRape = wRape->m_areaPercent;
6391  double areaWCerealSil = 0;
6392 
6394  areaWCerealSil = wCerealSil->m_areaPercent; //it is used here only if it was initilized - in the bedriftsmodel crop mode
6395  }
6396 
6397  double sum = areaWBarley + areaWWheat + areaWRye + areaWRape + areaWCerealSil;
6398 
6399  int winterMax = m_OurManager->pm_data->Get_winterMax(m_farmType);
6400  if(sum > winterMax){
6401 
6402  m_variableCrops2 = m_variableCrops; //initiate the new list and remove all winter crops:
6403 
6405  for(int s=(int)m_variableCrops2.size()-1; s>=0; s--){
6406  if(m_variableCrops2[s].crop==wBarley || m_variableCrops2[s].crop==wWheat || m_variableCrops2[s].crop==wRye || m_variableCrops2[s].crop==wRape || m_variableCrops2[s].crop==wCerealSil){
6407  m_variableCrops2.erase(m_variableCrops2.begin() + s);
6408  }
6409  }
6410  }
6411  else{
6412  for(int s=(int)m_variableCrops2.size()-1; s>=0; s--){
6413  if(m_variableCrops2[s].crop==wBarley || m_variableCrops2[s].crop==wWheat || m_variableCrops2[s].crop==wRye || m_variableCrops2[s].crop==wRape){
6414  m_variableCrops2.erase(m_variableCrops2.begin() + s);
6415  }
6416  }
6417  }
6418 
6419  double diff = sum - winterMax;
6420  double diffBefore = diff;
6421 
6422  CropSort cs1 = {0., wBarley}; //an object with a key for sorting and a pointer to crop
6423  CropSort cs2 = {0., wWheat};
6424  CropSort cs3 = {0., wRye}; //CropSort cs4 = {0., wRape};
6425  m_winterCrops.clear();
6426  m_winterCrops.push_back(cs1);
6427  m_winterCrops.push_back(cs2);
6428  m_winterCrops.push_back(cs3);
6429 
6431  CropSort cs5 = {0., wCerealSil};
6432  m_winterCrops.push_back(cs5);
6433  }
6434 
6435  sortCrops(m_winterCrops, "GM");
6436 
6437  //decrease area of one or more winter crops by diff
6439 
6440  if(diff > 0){ //loop in decreaseCrops was stopped by the other condition: impossible to cut more
6441  //violation of the restriction; do not exit, print warning
6442  ofstream ofile("Restrictions.txt",ios::app);
6443  ofile << m_almass_no << '\t' << "winter crops restriction broken, non-animal farm. Diff is: " << diff << endl;
6444  ofile.close();
6445  }
6446 
6447  //assign area cut from winter crops to one or more variable crops (that haven't reached the max yet)
6448  double toIncrease = diffBefore - diff;
6449  increaseCrops(m_variableCrops2, toIncrease);
6450 
6451  }//else nothing!:) it's ok
6452 
6453 }//end of checkWinterCrops
6454 
6456 
6462  CropOptimised *wBarley;
6463  CropOptimised *wWheat;
6464  CropOptimised *wRye;
6465  CropOptimised *wRape;
6466  CropOptimised *wCerealSil = NULL; // To prevent the annoying warning
6467 
6469  wBarley = findCropByName("WBarley");
6470  wWheat = findCropByName("WWheat");
6471  wRye = findCropByName("WRye");
6472  wRape = findCropByName("WRape"); //should not be decreased - might cause violation of winterRotation restriction
6473  wCerealSil = findCropByName("WCerealSil");
6474  }
6475  else{
6476  wBarley = findCropByName_almass("WinterBarley");
6477  wWheat = findCropByName_almass("WinterWheat");
6478  wRye = findCropByName_almass("WinterRye");
6479  wRape = findCropByName_almass("WinterRape"); //should not be decreased - might cause violation of winterRotation restriction
6480  }
6481 
6482  double areaWBarley = wBarley->m_areaPercent;
6483  double areaWWheat = wWheat->m_areaPercent;
6484  double areaWRye = wRye->m_areaPercent;
6485  double areaWRape = wRape->m_areaPercent;
6486  double areaWCerealSil = 0;
6487 
6489  areaWCerealSil = wCerealSil->m_areaPercent;
6490  }
6491 
6492  double sum = areaWBarley + areaWWheat + areaWRye + areaWRape + areaWCerealSil;
6493 
6494  int winterMax = m_OurManager->pm_data->Get_winterMax(m_farmType);
6495  if(sum > winterMax){
6496  double diff = sum - winterMax;
6497  double diffBefore = diff;
6498 
6499  m_variableCrops2 = m_variableCrops; //initiate the new list and remove all winter crops:
6501  for(int s=(int)m_variableCrops2.size()-1; s>=0; s--){
6502  if(m_variableCrops2[s].crop==wBarley || m_variableCrops2[s].crop==wWheat || m_variableCrops2[s].crop==wRye || m_variableCrops2[s].crop==wRape || m_variableCrops2[s].crop==wCerealSil){
6503  m_variableCrops2.erase(m_variableCrops2.begin() + s);
6504  }
6505  }
6506  }
6507  else{
6508  for(int s=(int)m_variableCrops2.size()-1; s>=0; s--){
6509  if(m_variableCrops2[s].crop==wBarley || m_variableCrops2[s].crop==wWheat || m_variableCrops2[s].crop==wRye || m_variableCrops2[s].crop==wRape){
6510  m_variableCrops2.erase(m_variableCrops2.begin() + s);
6511  }
6512  }
6513  }
6514 
6515  //assign keys for sorting - for fodder crops these will be Savings!
6516  CropSort cs1 = {0., wBarley}; //an object with a key for sorting and a pointer to crop
6517  CropSort cs2 = {0., wWheat};
6518  CropSort cs3 = {0., wRye};//CropSort cs4 = {wRape->pullVariable<double>("GM"), wRape};
6519 
6520  m_winterCrops.clear();
6521  m_winterCrops.push_back(cs1);
6522  m_winterCrops.push_back(cs2);
6523  m_winterCrops.push_back(cs3);
6524 
6526  CropSort cs5 = {0., wCerealSil};
6527  m_winterCrops.push_back(cs5);
6528  }
6529 
6530  sortCrops(m_winterCrops, "GM_Savings");
6531 
6532  //decrease area of one or more winter crops by diff
6534 
6535  if(diff>0){ //loop stopped by the other condition: impossible to cut more
6536  //violation of the restriction; do not exit, just print a warning
6537  ofstream ofile("Restrictions.txt",ios::app);
6538  ofile << m_almass_no << '\t' << "winter crops restriction broken, Animal farm. Diff is: " << diff << endl;
6539  ofile.close();
6540  }
6541 
6542  //assign the area cut from winter crops to one or more variable crops (that haven't reached the max yet)
6543  double toIncrease = diffBefore - diff;
6544  increaseCrops(m_variableCrops2, toIncrease);
6545 
6546  }//else nothing!:) it's ok
6547 
6548 }//end of checkWinterCropsAnimal
6549 
6553  for(int i=0; i<(int)m_cattleCrops.size(); i++){ //just go through all 2 of them:)
6554  double area = m_cattleCrops[i].crop->m_areaPercent;
6555  double areaBefore = area;
6556  double rotationMin = m_cattleCrops[i].crop->m_rotationMin;
6557  area = rotationMin; //set all at min
6558  m_cattleCrops[i].crop->m_areaPercent = area;
6559 
6560  if(areaBefore > area){
6561  int index = (cfg_OptimiseBedriftsmodelCrops.value())? toc_Foobar*m_farmType + m_cattleCrops[i].crop->m_cropType : tov_Undefined*m_farmType + m_cattleCrops[i].crop->m_cropType_almass;
6562  bool fodder = m_OurManager->pm_data->Get_fodder(index);
6563  if(fodder){
6564  double resp = m_cattleCrops[i].crop->m_resp;
6565  double loss = m_cattleCrops[i].crop->m_totalLoss;
6566  double FUKey = m_OurManager->pm_data->Get_FUKey(index);
6567  double FUha = resp * (1-loss/100) * FUKey; //[ha * hkg/ha * FU/hkg = FU]
6568  double changeFU = (areaBefore - area) * m_totalArea/100 * FUha; //positive number
6569  m_totalFUt += changeFU; //so you buy more
6570  m_totalFUgrown -= changeFU; //and grow less:)
6571  }
6572  }
6573  }
6574 }
6575 
6584 //This function can be called only after fodder crops were assigned areas because two of them are fodder crops! So before assiging the fodder crops, their areas will be zero!
6585 
6586 
6587  CropOptimised *sBarley = findCropByName("SBarley"); //fodder
6588  CropOptimised *gClover = findCropByName("GrassClover"); //fodder
6589  CropOptimised *gSeed = findCropByName("GrassSeed");
6590 
6591  CropOptimised *wWheat = findCropByName("WWheat");
6592 
6593  double areaSBarley = sBarley->m_areaPercent;
6594  double areaGClover = gClover->m_areaPercent;
6595  double areaGSeed = gSeed->m_areaPercent;
6596 
6597  double diff = areaGClover + areaGSeed - areaSBarley;
6598 
6599  if(diff > 0){ //restriction is not fulfilled
6600 
6601  //1. Make a vector of (two) cattle crops and sort them from highest to lowest GM/Savings
6602  CropSort cs1 = {0., gClover}; //an object with a key for sorting and a pointer to crop
6603  CropSort cs2 = {0., gSeed};
6604  m_cattleCrops.push_back(cs1);
6605  m_cattleCrops.push_back(cs2);
6606 
6607  sortCrops(m_cattleCrops, "GM_Savings"); //sorting the two crops
6608 
6609  //2. Make a new list of variable crops - excluding all crops forming the condition
6610  m_variableCrops2 = m_variableCrops; //initiate the new list and remove all three crops:
6611  for(int s=(int)m_variableCrops2.size()-1; s>=0; s--){
6612  if(m_variableCrops2[s].crop==sBarley || m_variableCrops2[s].crop==gClover || m_variableCrops2[s].crop==gSeed || m_variableCrops2[s].crop==wWheat){ //14.02 - added winter wheat - do not increase it!maybe i should even add here all winter crops...
6613  m_variableCrops2.erase(m_variableCrops2.begin() + s);
6614  }
6615  }
6616 
6617  //3. check if it pays off to substitute one of the two cattle crops with variable crops other than SBarley; if so - change the areas
6618  for(int i=(int)m_cattleCrops.size()-1; i>=0 && diff>0; i--){ //start with the worse one
6619  double areaCC = m_cattleCrops[i].crop->m_areaPercent; //don't know which of the two it is, so have to get the values this way
6620  double areaMinCC = m_cattleCrops[i].crop->m_rotationMin;
6621  double areaCCBefore = areaCC;
6622  if(areaCC > areaMinCC){
6623  bool cCropAtMin = false;
6624  for(int j=0; j<(int)m_variableCrops2.size() && cCropAtMin==false; j++){ //start with the best variable crop
6625  double GM_SBarley = sBarley->m_GM_Savings;
6626  double GM_CC = m_cattleCrops[i].crop->m_GM_Savings; //in case it is a fodder crop - then it takes savings, as now, after findFodderCropSavings() - savings are saved under GM_Savings for fodder crops
6627  double GM_var = m_variableCrops2[j].crop->m_GM_Savings;
6628  if(GM_SBarley + GM_CC > 2*GM_var){
6629  //yes: it doesn't pay off to remove this cattle crop; go to the next part of the cattle rot. function: increase SBarley, cut one of the cattle crops
6630  }
6631  else{
6632  double areaVar = m_variableCrops2[j].crop->m_areaPercent;
6633  double areaMaxVar = m_variableCrops2[j].crop->m_rotationMax;
6634  double areaVarBefore = areaVar;
6635 
6636  if(areaCC - areaMinCC >= diff){
6637  if(areaMaxVar - areaVar >= diff){
6638  areaCC -= diff;
6639  areaVar += diff;
6640  diff = 0; //finished -> cattle rotation fulfilled
6641  cCropAtMin = true; //stop the inner loop!!!
6642  }
6643  else{
6644  diff -= (areaMaxVar - areaVar);
6645  areaCC -= (areaMaxVar - areaVar);
6646  areaVar = areaMaxVar; //go to the next var. crop (j++)
6647  }
6648  }
6649  else{
6650  if(areaMaxVar - areaVar >= areaCC - areaMinCC){
6651  diff -= areaCC - areaMinCC;
6652  areaVar += areaCC - areaMinCC;
6653  areaCC = areaMinCC;
6654  cCropAtMin = true; //stop the inner loop - take the next cattle crop(i--)
6655  }
6656  else{
6657  diff -= areaMaxVar - areaVar;
6658  areaCC -= areaMaxVar - areaVar;
6659  areaVar = areaMaxVar; //go to the next var crop (j++)
6660  }
6661  }
6662 
6663  //save the areas
6664  m_variableCrops2[j].crop->m_areaPercent = areaVar;
6665  m_cattleCrops[i].crop->m_areaPercent = areaCC;
6666 
6667  //correct fodder variables for the changes - both for cattle and var crop
6668 
6669  if(areaVar > areaVarBefore){
6670  int index = toc_Foobar*m_farmType + m_variableCrops[j].crop->m_cropType;
6671  bool fodder = m_OurManager->pm_data->Get_fodder(index);
6672  if(fodder){ //this is a fodder crop - so you need to buy less fodder - totalFUt
6673  double resp = m_variableCrops[j].crop->m_resp;
6674  double loss = m_variableCrops[j].crop->m_totalLoss;
6675  double FUKey = m_OurManager->pm_data->Get_FUKey(index);
6676  double FUha = resp * (1-loss/100) * FUKey; //[ha * hkg/ha * FU/hkg = FU]
6677  double changeFU = (areaVar - areaVarBefore) * m_totalArea/100 * FUha; //positive
6678  m_totalFUt -= changeFU;
6679  m_totalFUgrown += changeFU;
6680  }
6681  }
6682 
6683  if(areaCC < areaCCBefore){
6684  int index = toc_Foobar*m_farmType + m_cattleCrops[i].crop->m_cropType;
6685  bool fodder = m_OurManager->pm_data->Get_fodder(index);
6686  if(fodder){ //this is a fodder crop - so you need to buy less fodder - totalFUt
6687  double resp = m_cattleCrops[i].crop->m_resp;
6688  double loss = m_cattleCrops[i].crop->m_totalLoss;
6689  double FUKey = m_OurManager->pm_data->Get_FUKey(index);
6690  double FUha = resp * (1-loss/100) * FUKey; //[ha * hkg/ha * FU/hkg = FU]
6691  double changeFU = (areaCCBefore - areaCC) * m_totalArea/100 * FUha; //positive
6692  m_totalFUt += changeFU;
6693  m_totalFUgrown -= changeFU;
6694  }
6695  }
6696  }
6697 
6698  }//inner for
6699  }
6700  else{
6701  //nothing - go to the next cattle crop; if there's no more - then the diff must be zero - so the loop will stop
6702  }
6703 
6704  }//outer for
6705 
6706  //4. Check if diff is still > 0 (after point 3.), if so - substitute some area of one of the cattle crops with SBarley
6707 
6708  if(diff>0){
6709 
6710  double areaSBarleyMax = sBarley->m_rotationMax;
6711  double SBarleyAvailableArea = areaSBarleyMax-areaSBarley;
6712  double areaSBarleyBefore = areaSBarley;
6713 
6714  double available = 0; //available to cut from GClover and GSeed
6715  for(int i=0; i<(int)m_cattleCrops.size(); i++){ //or simply: i<2
6716  double areaMin = m_cattleCrops[i].crop->m_rotationMin;
6717  double area = m_cattleCrops[i].crop->m_areaPercent;
6718  available += (area - areaMin);
6719  }
6720 
6721  if(areaSBarley < areaSBarleyMax){ //Y1
6722  if(SBarleyAvailableArea >= diff/2){ //Y2
6723  if(available >= diff/2){ //Y 3.2
6724  areaSBarley += diff/2; //increase Sbarley by diff/2
6725  diff /= 2; //updating diff
6726  decreaseCrops(m_cattleCrops, diff);//decrease the two crops by diff/2 (now=to diff)
6727  }
6728 
6729  else{ //N 3.2
6730  areaSBarley += available;
6731  diff -= 2 * available;//update diff
6732  setCattleCropsAtMin(); //decrease the two crops to min each (by available<diff/2),
6733 
6734  if(SBarleyAvailableArea >= diff){//if possible:
6735  areaSBarley += diff;//increase Sbarley by diff
6736  decreaseCrops(m_variableCrops2, diff);//& decrease the worst (available) normal crop by diff
6737  }
6738  else{
6739  //do as much as possible
6740  double toDecrease = areaSBarleyMax - areaSBarley; //neccesary -area has changed
6741  areaSBarley = areaSBarleyMax; //increase Sbarley to max
6742  diff-=toDecrease; //update diff
6743  decreaseCrops(m_variableCrops2, toDecrease);//decrease normal crops
6744  //and throw an exception! restriction must be violated
6745  ofstream ofile("Restrictions.txt",ios::app); //changed 06.06 out to app
6746  ofile << m_almass_no << '\t' << "cattle restriction: broken after N 3.2" << endl;
6747  ofile.close();
6748  }
6749  }
6750  }
6751  else{ //N2
6752  //increase SBarley to max in both cases
6753  if(available >= SBarleyAvailableArea){ //Y 3.1
6754  areaSBarley = areaSBarleyMax; //increase Sbarley to max
6755  diff -= 2 * SBarleyAvailableArea; //update diff
6756  available -= SBarleyAvailableArea; //decrease by what you add in the next line
6757  decreaseCrops(m_cattleCrops, SBarleyAvailableArea);//increase needed by
6758 
6759  double diffBefore = diff;
6760  if(available >= diff){
6761  decreaseCrops(m_cattleCrops, diff);//decrease the two crops by diff
6762  increaseCrops(m_variableCrops2, diffBefore);//increase normal crops by diff
6763  }
6764  else{
6765  //do as much as possible
6766  setCattleCropsAtMin();
6767  diff -= available; //update diff
6768  double toDecrease = available;
6769  increaseCrops(m_variableCrops2, toDecrease); //add some normal crops!
6770  //and throw exception - restriction must be violated!
6771  ofstream ofile("Restrictions.txt",ios::out);
6772  ofile << m_almass_no << '\t' << "cattle restriction: broken after Y 3.1" << endl;
6773  ofile.close();
6774  }
6775  }
6776  else{ //N 3.1 - restriction violated, but try to do as much as possible
6777  areaSBarley += available;
6778  setCattleCropsAtMin();
6779  diff -= 2 * available; //update diff
6780  double toDecrease = areaSBarleyMax - areaSBarley; //here it is necessary! because the area has changed
6781  areaSBarley = areaSBarleyMax;//
6782  diff -= toDecrease; //update diff
6783  decreaseCrops(m_variableCrops2, toDecrease);//add normal crops-but still-violation!
6784  //AND !!! throw an exception - violation
6785  ofstream ofile("Restrictions.txt",ios::out);
6786  ofile << m_almass_no << '\t' << "cattle restriction: broken after N 3.1" << endl;
6787  ofile.close();
6788  }
6789  }
6790 
6791  sBarley->m_areaPercent = areaSBarley;
6792 
6793  //this is a fodder crop - so you need to buy less fodder - totalFUt
6794  double resp = sBarley->m_resp;
6795  double loss = sBarley->m_totalLoss;
6796  double FUKey = m_OurManager->pm_data->Get_FUKey (toc_SBarley);
6797  double FUha = resp * (1-loss/100) * FUKey; //[ha * hkg/ha * FU/hkg = FU]
6798  double changeFU = (areaSBarley - areaSBarleyBefore) * m_totalArea/100 * FUha; //positive
6799  m_totalFUt -= changeFU;
6800  m_totalFUgrown += changeFU;
6801  }
6802 
6803  else{ // N 1
6804  if(available >= diff){
6805  double diffBefore = diff;
6806  decreaseCrops(m_cattleCrops, diff); //cover the diff
6807  increaseCrops(m_variableCrops2, diffBefore); //increase some normal crops
6808  }
6809  else{//restr must be violated
6810  setCattleCropsAtMin(); //set the two crops at min
6811  diff -= available;
6812  double toIncrease = available;
6813  increaseCrops(m_variableCrops2, toIncrease);
6814  //throw an exception - restriction must be violated!
6815  ofstream ofile("Restrictions.txt",ios::out);
6816  ofile << m_almass_no << '\t' << "cattle restriction: broken after N 1" << endl;
6817  ofile.close();
6818  }
6819  }
6820 
6821  }//end of the second if(diff>0)
6822 
6823  }//end of the if(diff>0)?
6824 
6825 }//end of check CattleRotation
6826 
6831  CropOptimised *sBarley = findCropByName_almass("SpringBarley"); //fodder
6832  CropOptimised *CGG1 = findCropByName_almass("CloverGrassGrazed1"); //fodder
6833  CropOptimised *CGG2 = findCropByName_almass("CloverGrassGrazed2"); //fodder
6834 
6835  double areaSBarley = sBarley->m_areaPercent;
6836  double areaCGG = 2*(CGG1->m_areaPercent); //cgg1 and 2 have equal areas - it waa checked in Check_sg_and_cgg (called in check restrictions)
6837 
6838  double diff = areaCGG/2 - areaSBarley; //SpringBarley has to have an area at least as big as CGG1 = CGG2 = areaCGG/2.
6839 
6840  if(diff > 0){ //restriction is not fulfilled
6841 
6842  //need to make new variableCrops2 - without the grasses and sbarley!
6843  m_variableCrops2 = m_variableCrops; //initiate the new list and remove crops:
6844  for(int s=(int)m_variableCrops2.size()-1; s>=0; s--){
6845  if(m_variableCrops2[s].crop==sBarley || m_variableCrops2[s].crop==CGG1 || m_variableCrops2[s].crop==CGG2){
6846  m_variableCrops2.erase(m_variableCrops2.begin() + s);
6847  }
6848  }
6849 
6850  double new_area_sbarley = areaSBarley;
6851  double new_area_cgg = areaCGG;
6852 
6853  double available=0; //all area except for fixed crops and min. areas of variable crops
6854  for(int i=0; i<(int)m_variableCrops.size(); i++){ //can't use m_grownVariableCrops - it doesn't include fodder crops!
6855  double areaVariableCrop = m_variableCrops[i].crop->m_areaPercent - m_variableCrops[i].crop->m_rotationMin;
6856  available += areaVariableCrop;
6857  }
6858 
6859  if(areaCGG/2 *3 <= available){ //then Sbarley can get as much as each CGG1; cgg area doesn't change
6860  new_area_sbarley = areaCGG/2;
6861  double area_to_decrease = new_area_sbarley - areaSBarley; // must be > 0 if this code is executed
6862  decreaseCrops(m_variableCrops2, area_to_decrease);
6863  }
6864  else{ //need to also cut grass, not just increase sbarley
6865  new_area_cgg = available/3 * 2; // = new area for sbarley = cgg1 = cgg2 (these 3 crops take all available area)
6866  new_area_sbarley = available/3;
6867  double current_sbarley_and_grasses = areaSBarley + areaCGG; // so other crops area (variable area) = 100 - current_sbarley_and_grasses
6868  double other_crops_area = available - current_sbarley_and_grasses;
6869  if(current_sbarley_and_grasses < available){ //there are other crops - and we're now substituting them with sbarley
6870  decreaseCrops(m_variableCrops2, other_crops_area);
6871  }
6872  //else - just these 3 crops - do nothing - grass is already cut :), sbarley area is increased
6873  }
6874 
6875  //correct fodder....
6876  double resp = sBarley->m_resp;
6877  double loss = sBarley->m_totalLoss;
6879  double FUKey = m_OurManager->pm_data->Get_FUKey(index);
6880  double FUha = resp * (1-loss/100) * FUKey; //[ha * hkg/ha * FU/hkg = FU]
6881  double changeFU = (new_area_sbarley - areaSBarley) * m_totalArea/100 * FUha; //positive
6882  m_totalFUt -= changeFU;
6883  m_totalFUgrown += changeFU;
6884 
6885  resp = CGG1->m_resp;
6886  loss = CGG1->m_totalLoss;
6888  FUKey = m_OurManager->pm_data->Get_FUKey(index);
6889  FUha = resp * (1-loss/100) * FUKey; //[ha * hkg/ha * FU/hkg = FU]
6890  changeFU = (areaCGG - new_area_cgg) * m_totalArea/100 * FUha; //positive
6891  m_totalFUt += changeFU;
6892  m_totalFUgrown -= changeFU;
6893 
6894  //and change the areas
6895  CGG1->m_areaPercent = new_area_cgg/2; //areaCGG is a summary area for both CGG
6896  CGG2->m_areaPercent = new_area_cgg/2;
6897  sBarley->m_areaPercent = new_area_sbarley;
6898 
6899  }
6900 
6901 }//end of check CattleRotation for almass crops
6902 
6910  CropOptimised *wBarley;
6911  CropOptimised *wRape;
6912  wBarley = findCropByName_almass("WinterBarley");
6913  wRape = findCropByName_almass("WinterRape");
6914  double area_WB = wBarley->m_areaPercent;
6915  double area_WR = wRape->m_areaPercent;
6916 
6917  if(area_WB < area_WR){ //then need to make changes!
6918 
6919  //1. need to make new variableCrops2 - without wrape and wbarley
6920  m_variableCrops2 = m_variableCrops; //initiate the new list and remove crops:
6921  for(int s=(int)m_variableCrops2.size()-1; s>=0; s--){
6922  if(m_variableCrops2[s].crop==wBarley || m_variableCrops2[s].crop==wRape){
6923  m_variableCrops2.erase(m_variableCrops2.begin() + s);
6924  }
6925  }
6926 
6927  //check how much area available is there:
6928  double available=0;
6929  for(int i=0; i<(int)m_variableCrops2.size(); i++){ //can't use m_grownVariableCrops - it doesn't include fodder crops!
6930  double areaVariableCrop = m_variableCrops2[i].crop->m_areaPercent - m_variableCrops2[i].crop->m_rotationMin;
6931  available += areaVariableCrop;
6932  }
6933 
6934  double new_area_wbarley = area_WB;
6935  double new_area_wrape = area_WR;
6936 
6937  if(2 * area_WR <= available){ //then WBarley can get area equal to the current WRape's area; WRape's area doesn't change
6938  new_area_wbarley = area_WR;
6939  double area_to_decrease = new_area_wbarley - area_WB; // must be > 0 if this code is executed
6940  decreaseCrops(m_variableCrops2, area_to_decrease); //increased the WBarley's area, so need to cut the same amount in other crops
6941  }
6942  else{ //need to cut wrape, not just increase wbarley
6943  new_area_wrape = available/2; // these 2 crops take the whole available area
6944  new_area_wbarley = available/2;
6945  double current_wbarley_and_wrape = area_WB + area_WR; // so other crops area (variable area) = 100 - current_wbarley_and_wrape
6946  double other_crops_area = available - current_wbarley_and_wrape;
6947  if(current_wbarley_and_wrape < available){ //there are other crops - and we're now substituting them with wbarley
6948  decreaseCrops(m_variableCrops2, other_crops_area);
6949  }
6950  //else nothing
6951  }
6952 
6953  //check how much winter crops is there now - before changes:
6954  double winter_crops=0;
6955  for(unsigned j=0; j<m_crops.size(); j++){
6956  if(m_crops[j]->m_cropType_almass == tov_WinterRape || m_crops[j]->m_cropType_almass == tov_WinterBarley ||
6957  m_crops[j]->m_cropType_almass == tov_WinterWheat || m_crops[j]->m_cropType_almass == tov_WinterRye){
6958  winter_crops += m_crops[j]->m_areaPercent;
6959  }
6960  }
6961  int winterMax = m_OurManager->pm_data->Get_winterMax(m_farmType);
6962 
6963  //now save the changes in the areas
6964  wRape->m_areaPercent = new_area_wrape;
6965  wBarley->m_areaPercent = new_area_wbarley;
6966 
6967  //check how much winter crops there is now:
6968  winter_crops=0;
6969  for(unsigned j=0; j<m_crops.size(); j++){
6970  if(m_crops[j]->m_cropType_almass == tov_WinterRape || m_crops[j]->m_cropType_almass == tov_WinterBarley ||
6971  m_crops[j]->m_cropType_almass == tov_WinterWheat || m_crops[j]->m_cropType_almass == tov_WinterRye){
6972  winter_crops += m_crops[j]->m_areaPercent;
6973  }
6974  }
6975 
6976  //need to check if the winter crops restriction is still fine:
6977  if(winter_crops > winterMax){ //problem
6978  double diff = winter_crops - winterMax;
6979  //need to make new variableCrops2 - without all winter crops!
6980  m_variableCrops2 = m_variableCrops; //initiate the new list and remove crops:
6981  for(int s=(int)m_variableCrops2.size()-1; s>=0; s--){
6982  if(m_variableCrops2[s].crop==wBarley || m_variableCrops2[s].crop==wRape || m_variableCrops2[s].crop->m_cropType_almass==tov_WinterWheat || m_variableCrops2[s].crop->m_cropType_almass == tov_WinterRye){
6983  m_variableCrops2.erase(m_variableCrops2.begin() + s);
6984  }
6985  }
6986  new_area_wrape -= diff/2;
6987  new_area_wbarley -= diff/2;
6989 
6990  //and change the areas again
6991  wRape->m_areaPercent = new_area_wrape;
6992  wBarley->m_areaPercent = new_area_wbarley;
6993  }
6994 
6995  //correct fodder. only winter barley is a fodder crop for pig farms
6996  double resp = wBarley->m_resp;
6997  double loss = wBarley->m_totalLoss;
6999  double FUKey = m_OurManager->pm_data->Get_FUKey(index);
7000  double FUha = resp * (1-loss/100) * FUKey; //[ha * hkg/ha * FU/hkg = FU]
7001  double changeFU = (new_area_wbarley - area_WB) * m_totalArea/100 * FUha; //positive
7002  m_totalFUt -= changeFU;
7003  m_totalFUgrown += changeFU;
7004  }
7005 }
7006 
7007 //------------------------------------------------------------------------------//
7008 //------------------------FUNCTIONS RELATED TO FODDER---------------------------//
7009 //------------------------------------------------------------------------------//
7010 
7016  m_totalFUgrown=0; //initialize
7017 
7018  double min_fodder = (m_farmType == toof_Pig) ? cfg_Min_fodder_prod_pig.value() : cfg_Min_fodder_prod_cattle.value(); //there are only two types of animal farms
7019  m_totalFodderToProduce = (min_fodder/100)*m_totalFUdemand; //[FU]
7020 
7021  double fodderFromFixed=0;
7022  for (int i=0; i<(int)m_fixedCrops.size(); i++){
7023  double area_percent = m_fixedCrops[i]->m_areaPercent;
7024  if(area_percent!=0){
7025  double area = area_percent/100* m_totalArea;
7026  double resp = m_fixedCrops[i]->m_resp;
7027  double loss = m_fixedCrops[i]->m_totalLoss;
7028 
7029  int index = (cfg_OptimiseBedriftsmodelCrops.value())? a_foobar*m_farmType + m_fixedCrops[i]->m_cropType : a_foobar*m_farmType + m_fixedCrops[i]->m_cropType_almass;
7030  double FUKey = m_OurManager->pm_data->Get_FUKey(index);//if it is not a fodder crop, key=0
7031  double FU = area*resp*(1-loss/100)*FUKey; //[ha * hkg/ha * FU/hkg = FU]
7032  fodderFromFixed += FU;//0 will be added in case of non-fodder crops
7033  m_totalFUgrown += FU;
7034  }
7035  }
7036  double fodderFromMinAreas=0;
7037  for (int i=0; i<(int)m_variableCrops.size(); i++){
7038  double areaMinPercent = m_variableCrops[i].crop->m_rotationMin;
7039  if(areaMinPercent!=0){ //150713
7040  double area = areaMinPercent/100*m_totalArea; //min area in ha
7041  double resp = m_variableCrops[i].crop->m_resp;
7042  double loss = m_variableCrops[i].crop->m_totalLoss;
7043 
7044  int index = (cfg_OptimiseBedriftsmodelCrops.value())? a_foobar*m_farmType + m_variableCrops[i].crop->m_cropType : a_foobar*m_farmType + m_variableCrops[i].crop->m_cropType_almass;
7045  double FUKey = m_OurManager->pm_data->Get_FUKey(index);//if it is not a fodder crop, key=0
7046  double FU = area*resp*(1-loss/100)*FUKey; //[ha * hkg/ha * FU/hkg = FU]
7047  fodderFromMinAreas += FU;
7048  m_totalFUgrown += FU;
7049  }
7050  }
7051  //this much fodder HAS to be obtained from self-production IF the requirment
7052  //on min fodder production holds; might be negative!
7053 
7054  m_fodderToProduce = m_totalFodderToProduce - (fodderFromFixed + fodderFromMinAreas);
7055  m_fodderToProduceBefore = m_fodderToProduce;
7056 
7057  //decrease the fodder demand by the amount obtained from growing fixed crops and from
7058  //min areas of variable crops; could be also negative now;
7059  m_totalFUdemand -= (fodderFromFixed + fodderFromMinAreas);
7060 
7061 }
7062 
7063 
7067  double areaAssignedToFodder=0; //holds the value of area that has to be grown to cover the min fodder production requirement
7068  if(m_fodderToProduce > 0){
7069  double available=0; //area of normal (non-fodder) crops available to substitute with fodder crops
7070  for(int i=0; i<(int)m_grownVariableCrops.size(); i++){
7071  double areaVariableCrop = m_grownVariableCrops[i]->m_areaVariable;
7072  available += areaVariableCrop;
7073  }
7074 
7075  for(int i=0; available>0 && i<(int)m_fodderCrops.size() && m_fodderToProduce > 0 ; i++){// if so, more has to be produced (than it is already-from min areas and fixed crops)
7076  int index = (cfg_OptimiseBedriftsmodelCrops.value())? a_foobar*m_farmType + + m_fodderCrops[i].crop->m_cropType : a_foobar*m_farmType + + m_fodderCrops[i].crop->m_cropType_almass;
7077  double rotationMax = m_fodderCrops[i].crop->m_rotationMax;
7078  double area = m_fodderCrops[i].crop->m_areaPercent; //fodder crop's area
7079  double areaBefore = area; //this is positive if areaMin>0, so save it
7080  double FUKey = m_OurManager->pm_data->Get_FUKey(index); //if it is not a fodder crop, key=0; number of FU per hkg of a crop
7081  double resp = m_fodderCrops[i].crop->m_resp;
7082  double loss = m_fodderCrops[i].crop->m_totalLoss;
7083  double FUha = resp * (1-loss/100) * FUKey;
7084  double haNeeded = m_fodderToProduce/FUha;
7085  double percNeeded = haNeeded*100/m_totalArea;
7086  if(percNeeded <= rotationMax - area){ //area might be positive! (min area)
7087  if(percNeeded <= available){
7088  area += percNeeded; //the end, fodderToProduce will be 0.
7089  available -= percNeeded;
7090  }
7091  else{
7092  area+=available; //so we can't grow any more fodder - no space left!
7093  available=0;
7094  }
7095  }
7096  else{
7097  if(rotationMax-area >= available){
7098  area += available;
7099  available=0; //no space left
7100  }
7101  else{
7102  available -= rotationMax-area;
7103  area = rotationMax;
7104  }
7105  }
7106  m_fodderCrops[i].crop->m_areaPercent = area;
7107  double Funits = FUha * (area-areaBefore) * m_totalArea/100;
7108  m_fodderToProduce -= Funits; //update fodderToProduce; in 1st case - it's now = 0.
7109  m_totalFUdemand -= Funits; //update the total demand as well!
7110  m_totalFUgrown += Funits; //update the amount of grown fodder units
7111  areaAssignedToFodder += (area-areaBefore);
7112 
7113  }
7114  if(m_fodderToProduce>0.1){
7115  //restriction broken! impossible to produce the min amount of fodder - send a message, but don't stop.
7116  char index[ 20 ];
7117  sprintf( index, "%d", m_almass_no);
7118  g_msg->Warn( WARN_BUG, "AnimalFarm::determineMinFodder(): impossible to cover the min. fodder prod., farm no: ", index );
7119  //exit( 1 );
7120  }
7121  //decreasing area of variable crops that has just been assigned to fodder crops
7122  //need to create a vector of type CropSort
7123  vector<CropSort>grownVarCrops_key;
7124  for(int g=0; g < (int)m_grownVariableCrops.size(); g++){
7125  CropSort gc = {0., m_grownVariableCrops[g]};
7126  grownVarCrops_key.push_back(gc);
7127  }
7128 
7129  OptimisingFarm::decreaseCrops(grownVarCrops_key, areaAssignedToFodder); //m_grownVariableCrops does not contain fodder crops-call optimising farms version. there might be here a fake crop; here use grownVarCrops_key - need CropSort type vector to use decreaseCrops;
7130  if(areaAssignedToFodder>0){
7131  //there is not enough space to grow fodder to cover the min required.
7132  char index[ 20 ];
7133  sprintf( index, "%d", m_almass_no);
7134  g_msg->Warn( WARN_BUG, "AnimalFarm::determineMinFodder(): not enough space to grow the min. fodder, farm no.: ", index );
7135  //exit( 1 );
7136 
7137  }
7138  }
7139 } //determineMinFodder
7140 
7141 
7143 
7165 //1. assigning area to fodder crops in order to cover the min fodder production
7166  if(!cash_crops_allowed) determineMinFodder(a_foobar);
7167 
7168 //2. now the choice - produce or purchase fodder
7169 
7170  m_totalFUt=0;
7171 
7172 
7173  //go through fodder crops - start with the one with max savings. Check if it reached its max area (could have happened in the previous step)
7174 
7175 for(int p=0; m_totalFUdemand>0 && p<(int)m_fodderCrops.size(); p++){ //outer for loop - fodder crops;
7176 
7177  double rotationMax = m_fodderCrops[p].crop->m_rotationMax;
7178  double areaFodder = m_fodderCrops[p].crop->m_areaPercent;
7179  if(areaFodder < rotationMax){ //if not -> go to the next fodder crop
7180  double savings = m_fodderCrops[p].crop->m_savings;
7181  bool assigningFinished = false; //changed to true when a fodder crop reaches rotationMax
7182 
7183  int v = (int)m_grownVariableCrops.size()-1;
7184  double minGM = 1000000; //set it high so that if there are no grown var crops - we go directly to the fodder trade code (as savings are not > minGM)
7185  do{ //inner loop; normal crops; starts with the crop with the lowest GM;
7186  if(v>=0){
7187  minGM = m_grownVariableCrops[v]->m_GM;
7188  }
7189  if(savings > minGM){ //compare savings to GM of the worst 'available' normal crop - which is currently planted and have areaVariable>0
7190  double areaVariable = m_grownVariableCrops[v]->m_areaVariable;
7191  int index = (cfg_OptimiseBedriftsmodelCrops.value())? a_foobar*m_farmType + m_fodderCrops[p].crop->m_cropType : a_foobar*m_farmType + m_fodderCrops[p].crop->m_cropType_almass;
7192  double FUKey = m_OurManager->pm_data->Get_FUKey(index);//if it is not a fodder crop, key=0
7193  double resp = m_fodderCrops[p].crop->m_resp;
7194  double loss = m_fodderCrops[p].crop->m_totalLoss;
7195  double FUha = resp*(1-loss/100)*FUKey;
7196  double haNeeded = m_totalFUdemand/FUha;
7197  double percNeeded = haNeeded*100/m_totalArea;
7198 
7199  if(percNeeded <= rotationMax - areaFodder){//you can plant as much as need of fodder crop, but check if there is enough space in the normal crop
7200  if(percNeeded <= areaVariable){//if so, just plant as much as you need of this one fodder crop and cut the normal crop by percNeeded
7201  areaFodder += percNeeded; //increase the area (not just assign!)
7202  m_totalFUdemand = 0; //finish outer loop
7203  m_totalFUgrown += percNeeded*FUha*m_totalArea/100;
7204  areaVariable -= percNeeded;
7205  assigningFinished = true; //finish inner loop
7206  }
7207  else{//you can plant fodder crop on an area of a normal crop and then check with the next normal crop
7208  areaFodder += areaVariable; //increase by the whole 'available' area of a normal crop
7209  m_totalFUdemand -= FUha*areaVariable*m_totalArea/100; //update fodder demand
7210  m_totalFUgrown += areaVariable*FUha*m_totalArea/100;
7211  areaVariable = 0;
7212  }
7213  }
7214  else{//this fodder crop will not cover all the needs; will have to check the next one
7215  if(rotationMax - areaFodder <= areaVariable){//if so, just plant as much as you need of this one fodder crop and cut the normal crop by...
7216  areaVariable -= rotationMax-areaFodder;
7217  m_totalFUgrown += (rotationMax-areaFodder)*FUha*m_totalArea/100;
7218  m_totalFUdemand -= FUha*(rotationMax-areaFodder)*m_totalArea/100;
7219  areaFodder = rotationMax; //max
7220  assigningFinished = true;
7221  //finish inner loop-you have to take the next fodder crop
7222  }
7223  else{//you can plant fodder crop on an area of a normal crop and then check with the next normal crop
7224  areaFodder += areaVariable; //increase by the whole 'available' area of a normal crop
7225  m_totalFUdemand -= FUha*areaVariable*m_totalArea/100;
7226  m_totalFUgrown += areaVariable*FUha*m_totalArea/100;
7227  areaVariable = 0;
7228  //whole replaced by a fodder crop
7229  }
7230  }
7231  double areaMin = m_grownVariableCrops[v]->m_rotationMin;
7232  double areaPer = areaMin + areaVariable;
7233  m_grownVariableCrops[v]->m_areaPercent = areaPer;
7234  m_grownVariableCrops[v]->m_areaVariable = areaVariable;
7235 
7236  }
7237  else{//buy all the remaining fodder demand
7238  m_totalFUt = m_totalFUdemand; //demand is already updated for fodder from fixed crops and min areas
7239  m_totalFUdemand = 0; //finish outer loop
7240  assigningFinished = true; //finish inner loop
7241  }
7242  v--;
7243  }while (assigningFinished==false && v>=0);//inner loop (normal crops)
7244 
7245  m_fodderCrops[p].crop->m_areaPercent = areaFodder;//update fodder crop - after the inner loop
7246 
7247  if(assigningFinished==false){ //loop was stopped by the condition->no more space on normal crops available
7248  //there's no more space on normal crops-have to buy the remaining totalFUdemand
7250  }
7251  }
7252 }//outer for-loop (fodder crops)
7253 
7254 
7255 if(m_totalFUdemand > 0){ //added 30.01 - for some farms the condition 'if(areaFodder<rotationMax)' is never fulfilled, so the inner loop will never run
7257  m_totalFUdemand = 0;
7258 }
7259 
7260 if(m_fakeCropTest==true){ //only if it was used in determineAreas - check if it is >0
7261  //check if the fake crop is still there - if so, substitute it with fodder crops
7262  int s = (int)m_grownVariableCrops.size()-1;
7263  double areaFakeCrop = m_grownVariableCrops[s]->m_areaPercent;
7264  if(areaFakeCrop > 0){
7265  increaseCrops(m_fodderCrops, areaFakeCrop);
7266  m_grownVariableCrops[s]->m_areaPercent = areaFakeCrop; //sets fake crop's area at 0.
7267  }
7268  //remove the fake crop from the grownVariable crops vector
7269  m_grownVariableCrops.erase(m_grownVariableCrops.begin() + s);
7270 }
7271 
7272 }// end of determineFodderAreas
7273 
7274 
7275 //------------------------------------------------------------------------------//
7276 //-----------------------OTHER FUNCTIONS----------------------------------------//
7277 //------------------------------------------------------------------------------//
7278 
7279 double OptimisingFarm::crop_parameter(int index, string par_name){
7280  double par_value;
7282  return par_value;
7283 }
7284 
7286  for(int c=0; c< (int)m_crops.size(); c++){
7287  if(m_crops[c]->m_cropType==m_OurManager->TranslateCropsCodes(crop_name)) return m_crops[c];
7288  }
7289  g_msg->Warn( WARN_FILE, "OptimisingFarm::findCropByName():" "Unknown Code Identificator", crop_name.c_str() );
7290  exit(0);
7291 }
7292 
7294  for(int c=0; c< (int)m_crops.size(); c++){
7295  if(m_crops[c]->m_cropType_almass == m_OurManager->TranslateCropCodes(crop_name)) return m_crops[c];
7296  }
7297  g_msg->Warn( WARN_FILE, "OptimisingFarm::findCropByName_almass():" "Unknown Code Identificator", crop_name.c_str() );
7298  exit(0);
7299 }
7300 
7302  for(int c=0; c< (int)m_crops.size(); c++){
7303  if(m_crops[c]->m_cropType_almass == a_tov_type) return m_crops[c];
7304  }
7305  char error_num[ 20 ];
7306  sprintf( error_num, "%d", a_tov_type);
7307  g_msg->Warn( WARN_BUG, "OptimisingFarm::findCropByName_almass():" "Unknown Code Identificator", error_num );
7308  exit(0);
7309 }
7310 
7311 void OptimisingFarm::sortCrops(vector<CropSort> &cropsToSort, string sortKey){
7315  if(sortKey=="GM"){
7316  for (int i=0; i<(int)cropsToSort.size(); i++){//define the key to sorting
7317  cropsToSort[i].key = cropsToSort[i].crop->m_GM;
7318  }
7319  }
7320  else if (sortKey=="Savings"){
7321  for (int i=0; i<(int)cropsToSort.size(); i++){//define the key to sorting
7322  cropsToSort[i].key = cropsToSort[i].crop->m_savings;
7323  }
7324  }
7325  else {
7326  for (int i=0; i<(int)cropsToSort.size(); i++){//define the key to sorting
7327  cropsToSort[i].key = cropsToSort[i].crop->m_GM_Savings;
7328  }
7329  }
7330 
7331  sort(cropsToSort.begin(), cropsToSort.end(), reverseSort());
7332 }
7333 
7334 void OptimisingFarm::randomizeCropList(vector<CropSort> &listToRandomize, string key){
7337  std::vector<CropSort>helper; //to store and shuffle elements with an equal value of a key
7338  helper.push_back(listToRandomize[0]); //save the first element of the list in the helper list
7339 
7340  for(int i=1; i<(int)listToRandomize.size(); i++){
7341  double key_current, key_previous;
7342  if(key=="GM"){
7343  key_current=listToRandomize[i].crop->m_GM;
7344  key_previous=listToRandomize[i-1].crop->m_GM;
7345  }
7346  else if (key=="Savings"){
7347  key_current=listToRandomize[i].crop->m_savings;
7348  key_previous=listToRandomize[i-1].crop->m_savings;
7349  }
7350  else if(key=="GM_Savings"){
7351  key_current=listToRandomize[i].crop->m_GM_Savings;
7352  key_previous=listToRandomize[i-1].crop->m_GM_Savings;
7353  }
7354  else{
7355  key_current=key_previous=0;
7356  g_msg->Warn( WARN_FILE, "OptimisingFarm::randomizeCropList():" "Unknown sorting key identificator", key.c_str() );
7357  exit(0);
7358  }
7359 
7360  if(key_current==key_previous){
7361  helper.push_back(listToRandomize[i]);
7362  }
7363  else{
7364  std::random_shuffle(helper.begin(), helper.end());
7365  //insert the elements of the vector - back to the original list
7366  //assign the elements of the vector in the reverse order (that's easier then the
7367  //normal order). The last element of the list has index = i-1.
7368  for(int j=(int)helper.size()-1; j>=0; j--){
7369  listToRandomize[i-1-j]=helper[j];
7370  }
7371  helper.clear(); //remove the elements...
7372  helper.push_back(listToRandomize[i]); //and 'start' a new vector with the current element
7373  }
7374  }
7375 }
7376 
7377 void OptimisingFarm::increaseCrops(vector<CropSort>cropsToIncrease, double &howMuchToIncrease){
7380  for(int i=0; howMuchToIncrease>0 && i<(int)cropsToIncrease.size(); i++){
7381  double area = cropsToIncrease[i].crop->m_areaPercent;
7382  double rotationMax = cropsToIncrease[i].crop->m_rotationMax;
7383  double rotMinCrop = cropsToIncrease[i].crop->m_rotationMin;
7384  if(area + howMuchToIncrease <= rotationMax){
7385  area += howMuchToIncrease; //finito
7386  howMuchToIncrease = 0;
7387  }
7388  else{
7389  howMuchToIncrease -= rotationMax-area;
7390  area = rotationMax;
7391  }
7392  cropsToIncrease[i].crop->m_areaPercent = area;
7393  cropsToIncrease[i].crop->m_areaVariable = area - rotMinCrop;
7394  }
7395 }
7396 
7397 void AnimalFarm::increaseCrops(vector<CropSort>cropsToIncrease, double &howMuchToIncrease){
7402  for(int i=0; howMuchToIncrease>0 && i<(int)cropsToIncrease.size(); i++){
7403  double area = cropsToIncrease[i].crop->m_areaPercent;
7404  double areaBefore = area;
7405  double rotationMax = cropsToIncrease[i].crop->m_rotationMax;
7406  double rotMinCrop = cropsToIncrease[i].crop->m_rotationMin;
7407  if(area + howMuchToIncrease <= rotationMax){
7408  area += howMuchToIncrease; //finito
7409  howMuchToIncrease = 0;
7410  }
7411  else{
7412  howMuchToIncrease -= rotationMax-area;
7413  area = rotationMax;
7414  }
7415  cropsToIncrease[i].crop->m_areaPercent = area;
7416  cropsToIncrease[i].crop->m_areaVariable = area - rotMinCrop;
7417 
7418  //checking if area has changed
7419  if(area > areaBefore){
7420  int index = (cfg_OptimiseBedriftsmodelCrops.value())? toc_Foobar*m_farmType + cropsToIncrease[i].crop->m_cropType : tov_Undefined*m_farmType + cropsToIncrease[i].crop->m_cropType_almass;
7421  bool fodder = m_OurManager->pm_data->Get_fodder(index);
7422  if(fodder){ //this is a fodder crop - so you need to buy less fodder (totalFUt)
7423  double resp = cropsToIncrease[i].crop->m_resp;
7424  double loss = cropsToIncrease[i].crop->m_totalLoss;
7425  double FUKey = m_OurManager->pm_data->Get_FUKey(index);
7426  double FUha = resp * (1-loss/100) * FUKey; //[ha * hkg/ha * FU/hkg = FU]
7427  double changeFU = (area-areaBefore) * m_totalArea/100 * FUha; //positive
7428  m_totalFUt -= changeFU;
7429  m_totalFUgrown += changeFU;
7430  }
7431  }
7432  }
7433 }
7434 
7435 void OptimisingFarm::decreaseCrops(vector<CropSort>cropsToDecrease, double &howMuchToDecrease){
7438  for(int j=(int)cropsToDecrease.size()-1; howMuchToDecrease>0 && j>=0; j--){ //start with the worst
7439  double areaCrop = cropsToDecrease[j].crop->m_areaPercent;
7440  double rotMinCrop = cropsToDecrease[j].crop->m_rotationMin;
7441  if(areaCrop - howMuchToDecrease >= rotMinCrop){
7442  areaCrop -= howMuchToDecrease;
7443  howMuchToDecrease = 0; //finito
7444  }
7445  else{
7446  howMuchToDecrease -= areaCrop - rotMinCrop;
7447  areaCrop = rotMinCrop;
7448  }
7449  cropsToDecrease[j].crop->m_areaPercent = areaCrop;
7450  cropsToDecrease[j].crop->m_areaVariable = areaCrop - rotMinCrop;
7451  }
7452 }
7453 
7454 void AnimalFarm::decreaseCrops(vector<CropSort>cropsToDecrease, double &howMuchToDecrease){
7459  for(int j=(int)cropsToDecrease.size()-1; howMuchToDecrease>0 && j>=0; j--){ //start with the worst
7460  double areaCrop = cropsToDecrease[j].crop->m_areaPercent;
7461  double areaBefore = areaCrop;
7462  double rotMinCrop = cropsToDecrease[j].crop->m_rotationMin;
7463  if(areaCrop - howMuchToDecrease >= rotMinCrop){
7464  areaCrop -= howMuchToDecrease;
7465  howMuchToDecrease = 0; //finito
7466  }
7467  else{
7468  howMuchToDecrease -= areaCrop - rotMinCrop;
7469  areaCrop = rotMinCrop;
7470  }
7471  cropsToDecrease[j].crop->m_areaPercent = areaCrop;
7472  cropsToDecrease[j].crop->m_areaVariable = areaCrop - rotMinCrop;
7473 
7474  if(areaCrop < areaBefore){
7475  int index = (cfg_OptimiseBedriftsmodelCrops.value())? toc_Foobar*m_farmType + cropsToDecrease[j].crop->m_cropType : tov_Undefined*m_farmType + cropsToDecrease[j].crop->m_cropType_almass;
7476  bool fodder = m_OurManager->pm_data->Get_fodder(index);
7477  if(fodder){ //this is a fodder crop - so you need to buy more fodder (totalFUt)
7478  double resp = cropsToDecrease[j].crop->m_resp;
7479  double loss = cropsToDecrease[j].crop->m_totalLoss;
7480  double FUKey = m_OurManager->pm_data->Get_FUKey(index);
7481  double FUha = resp * (1-loss/100) * FUKey; //[ha * hkg/ha * FU/hkg = FU]
7482  double changeFU = (areaBefore - areaCrop) * m_totalArea/100 * FUha; //positive number
7483  m_totalFUt += changeFU;
7484  m_totalFUgrown -= changeFU;
7485  }
7486  }
7487  }
7488 }
7489 
7490 void OptimisingFarm::determineAreas_ha(vector<CropOptimised*>allCrops){ //area in ha
7493  for(int i=0; i<(int)allCrops.size(); i++){
7494  double areaPercent = allCrops[i]->m_areaPercent;
7495  double area_ha = (areaPercent==0) ? 0 : (areaPercent/100 * m_totalArea);
7496  allCrops[i]->m_area_ha = area_ha;
7497  }
7498 }
7499 
7504  double totalAmount = 0;
7505  for (int i=0; i<(int)m_crops.size(); i++){
7506  double area_ha = m_crops[i]->m_area_ha;
7507  if(!area_ha==0){ //otherwise don't change totalAmount
7508  double value_per_ha;
7509  switch (a_var){
7510  case tocv_AreaPercent:
7511  value_per_ha = m_crops[i] ->m_areaPercent;
7512  break;
7513  case tocv_AreaHa:
7514  value_per_ha = m_crops[i] ->m_area_ha;
7515  break;
7516  case tocv_N:
7517  value_per_ha = m_crops[i] ->m_n;
7518  break;
7519  case tocv_Nt:
7520  value_per_ha = m_crops[i] ->m_nt;
7521  break;
7522  case tocv_BIHerb:
7523  value_per_ha = m_crops[i] ->m_BIHerb;
7524  break;
7525  case tocv_BIFi:
7526  value_per_ha = m_crops[i] ->m_BIFi;
7527  break;
7528  case tocv_BI:
7529  value_per_ha = m_crops[i] ->m_BI;
7530  break;
7531  case tocv_Grooming:
7532  value_per_ha = m_crops[i] ->m_grooming;
7533  break;
7534  case tocv_Hoeing:
7535  value_per_ha = m_crops[i] ->m_hoeing;
7536  break;
7537  case tocv_Weeding:
7538  value_per_ha = m_crops[i] ->m_weeding;
7539  break;
7540  case tocv_TotalLoss:
7541  value_per_ha = m_crops[i] ->m_totalLoss;
7542  break;
7543  case tocv_Response:
7544  value_per_ha = m_crops[i] ->m_resp;
7545  break;
7546  case tocv_Income:
7547  value_per_ha = m_crops[i] ->m_income_ha;
7548  break;
7549  case tocv_Costs:
7550  value_per_ha = m_crops[i] ->m_costs_ha;
7551  break;
7552  case tocv_GM:
7553  value_per_ha = m_crops[i] ->m_GM;
7554  break;
7555  case tocv_Savings:
7556  value_per_ha = m_crops[i] ->m_savings;
7557  break;
7558  default:
7559  g_msg->Warn( WARN_BUG, "OptimisingFarm::total(): ""Unknown crop variable type! ", "" );
7560  exit( 1 );
7561  }
7562  totalAmount += value_per_ha * area_ha; //each crop's/(field's) optimal values per ha multiplied by acreage of a crop
7563  }
7564  }
7565  return totalAmount;
7566  }
7567 
7568 void OptimisingFarm::Print_FarmVariables(ofstream * ap_output_file){
7571  //print the almass farm number
7572  (*ap_output_file) << m_almass_no << '\t';
7573 
7574  //print the values
7575  (*ap_output_file) << m_main_goal << '\t' << m_totalArea << '\t' << m_totalIncome<<'\t'<< m_totalCosts <<'\t'<< m_totalProfit <<'\t';
7576  (*ap_output_file) << m_totalFUdemand <<'\t' << m_totalFUdemandBefore << '\t' << m_totalFUt <<'\t'<< m_totalFUgrown << '\t';
7577  (*ap_output_file) << m_Nanim <<'\t'<< m_totalNanim <<'\t'<< m_totalNt <<'\t'<< m_totalN <<'\t';
7578  (*ap_output_file) << m_totalBI <<'\t'<< m_totalBIHerb <<'\t'<< m_totalBIFi <<'\t';
7579  (*ap_output_file) << m_totalGrooming <<'\t'<< m_totalHoeing <<'\t'<< m_totalWeeding <<'\t';
7580  (*ap_output_file) << endl;
7581 }
7582 
7586  double area_to_check = 0.0;
7587  for(int i=0; i<(int)m_crops.size(); i++) {
7588  area_to_check += m_crops[i]->m_areaPercent;
7589  }
7590 
7591  if(area_to_check > 100.0001 || area_to_check < 99.999){ //issue a warning
7592  ofstream ofile("Check_if_area_is_100%.txt",ios::app);
7593  ofile << m_almass_no << '\t' << "Farms area is not equal to 100%. The sum of crops areaPercent is: " << area_to_check << endl;
7594  ofile.close();
7595  }
7596 }
7597 
7603  for(int i = 0; i < (int)m_crops.size(); i++){
7604  if(m_crops[i]->m_areaPercent > 0){
7605  TTypesOfCrops toc = m_crops[i]->m_cropType; //Bedriftsmodel crop type
7606  TTypesOfVegetation tov;
7607 
7608  switch (toc) {
7609  case 0: //toc_SBarley
7610  tov = tov_SpringBarley;
7611  break;
7612  case 1: //toc_Oats
7613  tov = tov_Oats;
7614  break;
7615  case 2: //toc_OSCrops
7616  tov = tov_SpringBarley; //spring wheat - no code for this crop
7617  break;
7618  case 3: //toc_WBarley
7619  tov = tov_WinterBarley;
7620  break;
7621  case 4: //toc_WWheat
7622  tov = tov_WinterWheat;
7623  break;
7624  case 5: //toc_WRye
7625  tov = tov_WinterRye;
7626  break;
7627  case 6: //toc_Triticale
7628  tov = tov_Triticale;
7629  break;
7630  case 7: //toc_SRape
7631  tov = tov_SpringRape;
7632  break;
7633  case 8: //toc_WRape
7634  tov = tov_WinterRape;
7635  break;
7636  case 9: //toc_OOilseed
7637  tov = tov_WinterRape;
7638  break;
7639  case 10: //toc_Peas
7640  tov = tov_FieldPeas;
7641  break;
7642  case 11: //toc_OLSeed
7643  tov = tov_FieldPeas;
7644  break;
7645  case 12: //toc_GrassSeed //TRANSLATES TO TWO ALMASS CROPS
7646  tov = tov_SeedGrass1; //this translates to both tov_SeedGrass1 and tov_SeedGrass2; thus sg2 has to be considered in the rotation vector after the sg1; both get area percent = half of the original crop area percent
7647  break;
7648  case 13: //toc_Potato
7649  tov = tov_PotatoesIndustry;
7650  break;
7651  case 14: //toc_PotatoFood
7652  tov = tov_Potatoes;
7653  break;
7654  case 15: //toc_SugarBeet
7655  tov = tov_FodderBeet;
7656  break;
7657  case 16: //toc_GrassClover //TRANSLATES TO TWO ALMASS CROPS
7658  tov = tov_CloverGrassGrazed1; // also tov_CloverGrassGrazed2; need to first aggregate with CloverGrz and then divide the sum by two!
7659  break;
7660  case 17: //toc_OLSeedCut
7661  tov = tov_FieldPeasSilage;
7662  break;
7663  case 18: //toc_SCerealSil
7664  tov = tov_SpringBarleySilage; //undersown
7665  break;
7666  case 19: //toc_PeasSil
7667  tov = tov_FieldPeasSilage;
7668  break;
7669  case 20: //toc_MaizeSil
7670  tov = tov_MaizeSilage; //
7671  break;
7672  case 21: //toc_WCerealSil
7673  tov = tov_SpringBarleySilage;
7674  break;
7675  case 22: //toc_SCerealG
7676  tov = tov_SpringBarleySilage;
7677  break;
7678  case 23: //toc_PerGrassLow
7680  break;
7681  case 24: //toc_PerGrassNorm
7683  break;
7684  case 25: //toc_GrassEnv1
7685  tov = tov_PermanentGrassTussocky; // is aggregated with GrassEnv2
7686  break;
7687  case 26: //toc_GrassEnv2
7688  tov = tov_PermanentGrassTussocky; // is aggregated with GrassEnv1
7689  break;
7690  case 27: //toc_GrassRot
7691  tov = tov_FodderGrass;
7692  break;
7693  case 28: //toc_Setaside
7694  tov = tov_Setaside;
7695  break;
7696  case 29: //toc_Uncult
7697  tov = tov_PermanentSetaside;
7698  break;
7699  case 30: //toc_OUncult
7700  tov = tov_PermanentSetaside;
7701  break;
7702  case 31: //toc_FodderBeet
7703  tov = tov_FodderBeet;
7704  break;
7705  case 32: //toc_CloverGrz //TRANSLATES TO TWO ALMASS CROPS
7706  tov = tov_CloverGrassGrazed1; // also tov_CloverGrassGrazed2; need to first aggregate with GrassClover and then divide the sum by two!
7707  break;
7708  case 33: //toc_Veg
7709  tov = tov_Carrots;
7710  break;
7711  case 34: //toc_Fruit
7712  tov = tov_OrchardCrop;
7713  break;
7714  case 35: //toc_FruitTree
7715  tov = tov_OrchardCrop;
7716  break;
7717  case 36: //toc_OSpecCrops
7718  tov = tov_Carrots; // could be also smth else
7719  break;
7720  case 37: //toc_ChrisTree
7721  tov = tov_YoungForest;
7722  break;
7723  case 38: //toc_EnergyFor
7724  tov = tov_YoungForest; // ideally should be willow
7725  break;
7726  case 39: //toc_Other
7727  tov = tov_Carrots; // this also could be smth else
7728  break;
7729  default:
7730  g_msg->Warn( WARN_BUG, "OptimisingFarm::Translate_crops_to_almass(): ""Unknown crop type! ", "" );
7731  exit( 1 );
7732  }
7733 
7734  //try not separating fixed from variables crops
7735  AlmassCrop crop = { m_crops[i]->m_areaPercent, tov};
7736  m_crops_almass.push_back(crop);
7737 
7738  } //if
7739  }//for
7740 
7741  //aggregate the almass crops that are in >1 position in the m_crops vector - so that they are listed only once
7742 
7743  vector<AlmassCrop>crops_almass_aggregated;
7744  int size = (int)m_crops_almass.size();
7745 
7746  for(int i = 0; i < size; i++){
7747  TTypesOfVegetation tov1 = m_crops_almass[i].Tov;
7748  double summaryArea = m_crops_almass[i].Number; //initialize
7749  bool skip = false;
7750 
7751  for(int p = 0; p < i; p++){ //check if this tov was already aggregated (so check elements of the vector before this one)
7752  if(m_crops_almass[p].Tov == tov1){ //this tov is already aggregated, so skip i element
7753  skip = true;
7754  }
7755  }
7756  if (!skip){
7757  for(int j = i+1; j < size; j++){ // start comparing with the crop following the one at position i
7758  if(m_crops_almass[j].Tov == tov1){
7759  summaryArea += m_crops_almass[j].Number; //add area to the summary area
7760  }
7761  }
7762  AlmassCrop crop = {summaryArea, m_crops_almass[i].Tov, };
7763  crops_almass_aggregated.push_back(crop);
7764  }
7765  }
7766  m_crops_almass = crops_almass_aggregated; //save the aggregated crops in m_crops_almass vector
7767 
7768 
7769  //now deal with the crops that translate to more than one almass crop, i.e.:
7770  //1) GrassClover + CloverGrz = CGG1 + CGG2
7771  //2) GrassSeed = SG1 + SG2
7772 
7773 
7774  for(int i = 0; i < (int)m_crops_almass.size(); i++){
7775  if(m_crops_almass[i].Tov == tov_CloverGrassGrazed1){
7776  double pct = (m_crops_almass[i].Number)/2; //have to divide the area between CGG1 and CGG2
7777  m_crops_almass[i].Number = pct;
7778  AlmassCrop cgg2 = {pct, tov_CloverGrassGrazed2};
7779  m_crops_almass.push_back(cgg2);
7780  }
7781  if(m_crops_almass[i].Tov == tov_SeedGrass1){
7782  double pct = (m_crops_almass[i].Number)/2; //have to divide the area between SG1 and SG2
7783  m_crops_almass[i].Number = pct;
7784  AlmassCrop sg2 = {pct, tov_SeedGrass2};
7785  m_crops_almass.push_back(sg2);
7786  }
7787  }
7788 
7789 }
7790 
7791 
7796  m_crops_almass.clear();
7797 
7798  for(int i = 0; i < (int)m_crops.size(); i++){
7799  if(m_crops[i]->m_areaPercent > 0){
7800  TTypesOfVegetation tov = m_crops[i]->m_cropType_almass;
7801  AlmassCrop crop = { m_crops[i]->m_areaPercent, tov};
7802  m_crops_almass.push_back(crop);
7803  }
7804  }
7805 
7806 }
7807 
7809 
7810  //first deal with the probelmatic crops:CGG1 + CGG2 and SB, and SG1 + SG2
7811  double area_cgg=0;
7812  for(int i = 0; i < (int)m_crops_almass.size(); i++){
7813  if(m_crops_almass[i].Tov == tov_CloverGrassGrazed1){
7814  bool cg2=false;
7815  for(int j = 0; j < (int)m_crops_almass.size(); j++){
7816  if(m_crops_almass[j].Tov == tov_CloverGrassGrazed2){
7817  double pct = (m_crops_almass[i].Number + m_crops_almass[j].Number)/2; //take average
7818  m_crops_almass[i].Number = pct;
7819  m_crops_almass[j].Number = pct;
7820  area_cgg = pct;
7821  cg2=true;
7822  }
7823  }
7824  if(!cg2){ //there is cgg1 but not cgg2
7825  double pct = (m_crops_almass[i].Number)/2; //divide cgg1 area by two and save it in cgg1 and create cgg2
7826  m_crops_almass[i].Number = pct;
7827  area_cgg = pct;
7828  AlmassCrop cgg2 = {pct, tov_CloverGrassGrazed2};
7829  m_crops_almass.push_back(cgg2);
7830  }
7831  break;
7832  }
7833  }
7834 
7835  //cgg and sb
7836  bool sb=false;
7837  double new_area = area_cgg; //initialize with the current area of cgg - maybe it won't change
7838  for(int i = 0; i < (int)m_crops_almass.size(); i++){
7839  if(m_crops_almass[i].Tov == tov_SpringBarley){
7840  sb=true;
7841  double area_sb = m_crops_almass[i].Number;
7842  if(area_sb < area_cgg){ //problem
7843  new_area = (area_sb + 2*area_cgg)/3;
7844  m_crops_almass[i].Number = new_area;
7845  }
7846  break;
7847  }
7848  }
7849  if(!sb){ //there wasn't spring barley - need to add
7850  new_area = area_cgg*2/3;
7851  if(new_area >0){ //otherwise do not add sbarley
7852  AlmassCrop sb = {new_area, tov_SpringBarley};
7853  m_crops_almass.push_back(sb);
7854  }
7855  }
7856  //now find both cgg and change their areas
7857  for(int j = 0; j < (int)m_crops_almass.size(); j++){
7858  if(m_crops_almass[j].Tov == tov_CloverGrassGrazed1){
7859  m_crops_almass[j].Number = new_area;
7860  }
7861  if(m_crops_almass[j].Tov == tov_CloverGrassGrazed2){
7862  m_crops_almass[j].Number = new_area;
7863  }
7864  }
7865 
7866 
7867 
7868  //sg1 and sg2
7869  for(int i = 0; i < (int)m_crops_almass.size(); i++){
7870  if(m_crops_almass[i].Tov == tov_SeedGrass1){
7871  bool sg2=false;
7872  for(int j = 0; j < (int)m_crops_almass.size(); j++){
7873  if(m_crops_almass[j].Tov == tov_SeedGrass2){
7874  double pct = (m_crops_almass[i].Number + m_crops_almass[j].Number)/2; //take average
7875  m_crops_almass[i].Number = pct;
7876  m_crops_almass[j].Number = pct;
7877  sg2=true;
7878  }
7879  }
7880  if(!sg2){ //there is cgg1 but not cgg2
7881  double pct = (m_crops_almass[i].Number)/2; //divide cgg1 area by two and save it in cgg1 and create cgg2
7882  m_crops_almass[i].Number = pct;
7883  AlmassCrop sg2 = {pct, tov_SeedGrass2};
7884  m_crops_almass.push_back(sg2);
7885  }
7886  break;
7887  }
7888  }
7889 
7890  //first clear the current m_rotational_crops
7891  m_rotational_crops.clear();
7892 
7893  //then add rotational crops from the list of all crops - both rotational and permanent
7894  m_area_rot = 0;//sum of areas of rotational crops - need it for checking if there is any field without perm crops in case there are no rot. crops
7895  for(int i = 0; i < (int)m_crops_almass.size(); i++){
7896  TTypesOfVegetation tov = m_crops_almass[i].Tov;
7897 
7900  //do nothing - just need rotational crops
7901  }
7902  else {
7903  double pct = m_crops_almass[i].Number;
7904  if(pct<0.5) pct+=0.5; //thanks to that such crop won't disappear! (won't have area=0 after rounding)
7905  AlmassCrop pcd = {pct, tov};
7906  m_rotational_crops.push_back(pcd);
7907  m_area_rot += pct;
7908  }
7909  }
7910 }
7911 
7912 void OptimisingFarm::Print_rotations(ofstream * ap_output_file){
7915  //print the almass farm number
7916  //(*ap_output_file) << m_almass_no << '\t';
7917 
7918  //print the content of the m_rotation vector
7919  for(int i=0; i<(int)m_rotation.size(); i++){
7920  TTypesOfVegetation crop = m_rotation[i];
7921  (*ap_output_file) << i << '\t' << crop << endl;
7922  }
7923  (*ap_output_file) << endl;
7924 }
7925 
7934  //1. STOCK FARM
7936  else m_stockfarmer = false;
7937 
7938  //2. INTENSITY - skip
7939 
7940  //3. PERMANENT vs ROTATIONAL CROPS
7941  //sort them and put into two vectors: m_PermCrops (member of Farm class, type: struct PermCropData) + local vector rotational_crops (type: struct AlmassCrop)
7942 
7943  int no_perm = 0;
7944  int no_rotational = 0;
7945  int area_perm = 0; //sum of areas of permanent crops
7946  m_area_rot = 0; //sum of areas of rotational crops
7947 
7948  for(int i = 0; i < (int)m_crops_almass.size(); i++){
7949  TTypesOfVegetation tov = m_crops_almass[i].Tov;
7950 
7953  int pct = (int)(m_crops_almass[i].Number + 0.5); //round a double to int
7954  PermCropData pcd = {tov, pct};
7955  m_PermCrops.push_back(pcd);
7956  no_perm++;
7957  area_perm += pct;
7958  }
7959  else {
7960  double pct = m_crops_almass[i].Number;
7961  if(pct<0.5) pct+=0.5; //thanks to that such crop won't disappear! (won't have area=0 after rounding)
7962  AlmassCrop pcd = {pct, tov};
7963  m_rotational_crops.push_back(pcd);
7964  no_rotational++;
7965  m_area_rot += pct;
7966  }
7967  }
7968 
7969  //4. ROTATIONAL CROPS
7970 
7971  //first check if there are any rotational crops!
7972  if(m_rotational_crops.size()!=0){
7973 
7974  m_rotation.resize(100);
7975  vector<TTypesOfVegetation>all_crops; //vector the has a right proportion of each crop tov type
7976  vector<MakeRotation>rotation;
7977  rotation.resize(100);
7978 
7979  //scale the rotational crop areas to account for the area that is reserved for permanent crops
7980  //and
7981  //save scaled areas of SBarley and CGG1 to make a check in the next step
7982  int area_rot_int = (int)(m_area_rot + 0.5); //area in percent of rot crops - as an integer
7983  int SBarley_area=0;
7984  int CGG1_area=0;
7985 
7986  for(int i=0; i<(int)m_rotational_crops.size(); i++){
7987  double area = m_rotational_crops[i].Number;
7988  int area_scaled = (int)(100 * area / area_rot_int + 0.5);
7989  m_rotational_crops[i].Number = area_scaled;
7990  if(m_rotational_crops[i].Tov == tov_CloverGrassGrazed1) CGG1_area = (int) m_rotational_crops[i].Number; //scaled area
7991  if(m_rotational_crops[i].Tov == tov_SpringBarley) SBarley_area = (int) m_rotational_crops[i].Number; //(this is scaled area)
7992  }
7993 
7994  //check if we have enough spring barley for CGG1 and CGG2 (area CGG1 = area CGG2); if not - change the areas so that
7995  //SBarley = CGG1 = CGG2 area.
7996  if(SBarley_area < CGG1_area){ //problem
7997  if(SBarley_area == 0){ //there's no sbarley! - need to create
7998  AlmassCrop sbarley = {0, tov_SpringBarley};
7999  m_rotational_crops.push_back(sbarley); //add sbarley
8000  }
8001  int new_area = (int)((CGG1_area * 2 + SBarley_area)/3 + 0.5); //= (CGG1 + CGG2 + SBarley)/3 ->and take integer
8002  for(int i=0; i<(int)m_rotational_crops.size(); i++){
8005  m_rotational_crops[i].Number = new_area;
8006  }
8007  }
8008  }
8009 
8010 
8011  //fill the all_crops vector with tov types -> in the right proportions
8012  for(int i = 0; i<(int)m_rotational_crops.size(); i++){
8013  int area = (int) m_rotational_crops[i].Number; //conversion to int - OK! - this is already int after the previous for loop
8014  for(int j = 0; j<area; j++){
8015  all_crops.push_back(m_rotational_crops[i].Tov);
8016  }
8017  }//now the size of all_crops might NOT be 100! - so check and make it to be 100?
8018 
8019  //sort the all_crops vector and rearrange it so that the probability of two crops that cannot follow each other is minimised
8020  //so - the order of the for loops below matter!!!
8021  vector<TTypesOfVegetation>all_crops_helper; //vector helper
8022 
8023  for(int i = (int)all_crops.size()-1; i>=0; i--){
8024  if(all_crops[i] == tov_SpringBarley) {
8025  all_crops_helper.push_back(all_crops[i]);
8026  all_crops.erase(all_crops.begin() + i);
8027  }
8028  }
8029 
8030  for(int i = (int)all_crops.size()-1; i>=0; i--){
8031  if(all_crops[i] == tov_CloverGrassGrazed1) {
8032  all_crops_helper.push_back(all_crops[i]);
8033  all_crops.erase(all_crops.begin() + i);
8034  }
8035  }
8036  for(int i = (int)all_crops.size()-1; i>=0; i--){
8037  if(all_crops[i] == tov_CloverGrassGrazed2) {
8038  all_crops_helper.push_back(all_crops[i]);
8039  all_crops.erase(all_crops.begin() + i);
8040  }
8041  }
8042  for(int i = (int)all_crops.size()-1; i>=0; i--){
8043  if(all_crops[i] == tov_FodderBeet) {
8044  all_crops_helper.push_back(all_crops[i]);
8045  all_crops.erase(all_crops.begin() + i);
8046  }
8047  }
8048  for(int i = (int)all_crops.size()-1; i>=0; i--){
8049  if(all_crops[i] == tov_WinterRape) {
8050  all_crops_helper.push_back(all_crops[i]);
8051  all_crops.erase(all_crops.begin() + i);
8052  }
8053  }
8054  for(int i = (int)all_crops.size()-1; i>=0; i--){
8055  if(all_crops[i] == tov_SpringRape) {
8056  all_crops_helper.push_back(all_crops[i]);
8057  all_crops.erase(all_crops.begin() + i);
8058  }
8059  }
8060  for(int i = (int)all_crops.size()-1; i>=0; i--){
8061  if(all_crops[i] == tov_Potatoes) {
8062  all_crops_helper.push_back(all_crops[i]);
8063  all_crops.erase(all_crops.begin() + i);
8064  }
8065  }
8066  for(int i = (int)all_crops.size()-1; i>=0; i--){
8067  if(all_crops[i] == tov_SeedGrass1) {
8068  all_crops_helper.push_back(all_crops[i]);
8069  all_crops.erase(all_crops.begin() + i);
8070  }
8071  }
8072  for(int i = 0; i<(int)all_crops.size(); i++){
8073  if(all_crops[i] == tov_SeedGrass2) {
8074  all_crops_helper.push_back(all_crops[i]);
8075  all_crops.erase(all_crops.begin() + i);
8076  }
8077  }
8078  for(int i = (int)all_crops.size()-1; i>=0; i--){
8079  if(all_crops[i] == tov_FieldPeas) {
8080  all_crops_helper.push_back(all_crops[i]);
8081  all_crops.erase(all_crops.begin() + i);
8082  }
8083  }
8084  for(int i = (int)all_crops.size()-1; i>=0; i--){
8085  if(all_crops[i] == tov_FieldPeasSilage) {
8086  all_crops_helper.push_back(all_crops[i]);
8087  all_crops.erase(all_crops.begin() + i);
8088  }
8089  }
8090  for(int i = (int)all_crops.size()-1; i>=0; i--){
8091  if(all_crops[i] == tov_WinterBarley) {
8092  all_crops_helper.push_back(all_crops[i]);
8093  all_crops.erase(all_crops.begin() + i);
8094  }
8095  }
8096  for(int i = (int)all_crops.size()-1; i>=0; i--){
8097  if(all_crops[i] == tov_WinterWheat) {
8098  all_crops_helper.push_back(all_crops[i]);
8099  all_crops.erase(all_crops.begin() + i);
8100  }
8101  }
8102  for(int i = (int)all_crops.size()-1; i>=0; i--){
8103  if(all_crops[i] == tov_Setaside) {
8104  all_crops_helper.push_back(all_crops[i]);
8105  all_crops.erase(all_crops.begin() + i);
8106  }
8107  }
8108 
8109  for(int i = (int)all_crops.size()-1; i>=0; i--){
8110  if(all_crops[i] == tov_MaizeSilage) {
8111  all_crops_helper.push_back(all_crops[i]);
8112  all_crops.erase(all_crops.begin() + i);
8113  }
8114  }
8115 
8116  //now place the other - remaining crops (in the all_crops vector) in further positions of the helper vector
8117  for(int i = 0; i<(int)all_crops.size(); i++){
8118  all_crops_helper.push_back(all_crops[i]);
8119  }
8120 
8121  //check if the size is 100 - correct if not
8122  if(all_crops_helper.size()!=100){
8123  if(all_crops_helper.size()>100){
8124  for(int i = (int)all_crops_helper.size(); i>100; i--){
8125  all_crops_helper.erase(all_crops_helper.end()-1); //just remove the last element
8126  }
8127  }
8128  else{ //<100
8129  for(int i = (int)all_crops_helper.size(); i<100; i++){
8130  if(all_crops_helper[i-2] != tov_CloverGrassGrazed2) all_crops_helper.push_back(all_crops_helper[i-2]); //this way I duplicate the ending (max 2/4 last elements)
8131  else all_crops_helper.push_back(tov_SpringBarley); //add spring barley
8132  }
8133  }
8134  }
8135 
8136  //copy the helper to all_crops
8137  all_crops = all_crops_helper;
8138 
8139 
8140  //fill the rotation vector with tov_Undefined
8141  for(int i = 0; i<(int)rotation.size(); i++){
8142  rotation[i].Tov = tov_Undefined;
8143  }
8144 
8145 
8146  // go through all_crops - should be 100...
8147 
8148  for(int i = 0; i < (int)all_crops.size(); i++){
8149 
8150  //find a place for the tov in the rotation vector:
8151  bool test=false;
8152  int count=0;
8153  TTypesOfVegetation crop_index = all_crops[i]; //current crop (tov) you want to place in a vector
8154 
8155  int step=no_rotational;
8156  int p=0;
8157 
8158  for(int j = p; count<101 && test==false; j=j+step){
8159  double sb_area = (cfg_OptimiseBedriftsmodelCrops.value())? findCropByName ("SBarley")->m_areaPercent : findCropByName_almass ("SpringBarley")->m_areaPercent;
8160  if (crop_index == tov_SpringBarley && sb_area > (100/step)) step = (int)(100/sb_area + 0.5);
8161  if(j>=100) {//without this we would always start out in the same position
8162  if (crop_index == tov_SpringBarley) {p+=3; j=p;} //special case - sbarley, cgg1 and cgg2; has to be 3 - doesn't work with 4
8163  else j=++p;
8164  }
8165 
8166  if(!(rotation[j].taken)){ //not taken - so check if it is allowed here - lookup
8167 
8168  TTypesOfVegetation crop_before, crop_after;
8169 
8170  crop_before = (j==0) ? rotation[99].Tov : rotation[j-1].Tov;
8171  crop_after = (j==99) ? rotation[0].Tov : rotation[j+1].Tov;
8172 
8173  int lookup_before = m_OurManager->Get_lookup_table(crop_before * (tov_Undefined+1) + crop_index); //check with a preceeding crop; tov_undef+1 - because this tov_undef is included in the lookup table
8174  int lookup_after = m_OurManager->Get_lookup_table(crop_index * (tov_Undefined+1) + crop_after); //check with a following crop
8175 
8176  if(lookup_before==-1 || lookup_after==-1){ //issue a warning: wrong index...
8177  char index[ 20 ];
8178  sprintf( index, "%d", crop_index);
8179  g_msg->Warn( WARN_BUG, "OptimisingFarm::Make_rotations(): Error (possibly caused by a new tov type that is not incuded in the crops_lookup table) in reading the lookup table; tov type that should not appear: ", index );
8180  exit( 1 );
8181  }
8182 
8183  if(lookup_before==1 && lookup_after==1){
8184  rotation[j].Tov = all_crops[i]; //same as crop_index
8185  rotation[j].taken = true;
8186  test=true;
8187  }
8188  else count++; //did not succeed in placing the crop, so increase the count
8189  }
8190  else{
8191  count++; //did not succeed in placing the crop, so increase the count
8192  }
8193 
8194  } //inner for loop: searching for a place for a given crop
8195 
8196  if(test==false){ //there is no place that does not break the lookup table rules
8197 
8198  //so try to go through the whole rotation and find a place where the current crop fits
8199 
8200  for(int r=0; r<(int)rotation.size() && test==false; r++){
8201 
8202  TTypesOfVegetation crop_before, crop_after;
8203 
8204  crop_before = rotation[r].Tov;
8205  crop_after = (r==99) ? rotation[0].Tov : rotation[r+1].Tov;
8206  int lookup_before = m_OurManager->Get_lookup_table(crop_before * (tov_Undefined+1) + crop_index); //check with a preceeding crop; tov_undef+1 - because this tov_undef is included in the lookup table
8207  int lookup_after = m_OurManager->Get_lookup_table(crop_index * (tov_Undefined+1) + crop_after); //check with a following crop
8208 
8209  if(lookup_before==1 && lookup_after==1){
8210  MakeRotation crop = {true, all_crops[i]};
8211  rotation.insert(rotation.begin() + r+1, crop); //->insert before element r+1
8212  test=true;
8213 
8214  //need to remove 1 element of the rotation! as 1 additional was just inserted
8215  //but this might cause troubles: two already placed elements might become incompatible...
8216 
8217  for(int p=(int)rotation.size()-1; p>=0; p--){//start at the end - more efficient, as here should be empty elements
8218  if(rotation[p].Tov == tov_Undefined){
8219  rotation.erase(rotation.begin() + p);
8220  //check if the 'new neighbours' can be next to each other
8221  crop_before = (p==0) ? rotation[99].Tov : rotation[p-1].Tov;
8222  crop_after = (p==100) ? rotation[0].Tov : rotation[p].Tov; //100 because the index is p
8223  int crop_after_position = (p==100) ? 0 : p;
8224 
8225  int lookup_before = m_OurManager->Get_lookup_table(crop_before * (tov_Undefined+1) + crop_after); //check with a preceeding crop; tov_undef+1 - because this tov_undef is included in the lookup table
8226 
8227  TTypesOfVegetation crop_before1, crop_after1, crop_before2;
8228  crop_before2=tov_Undefined; //for the begininng
8229  int crop_before2_position;
8230  int count2=0;
8231 
8232  while(lookup_before!=1){ //need to move somewhere the crop_after
8233 
8234  //check if there is no correct rotation possible
8235  if(count2>100){ //problem: impossible to make a rotation
8236  //so switch some crop...to Spring Barley
8237  TTypesOfVegetation problem_crop = rotation[crop_before2_position].Tov;
8238  rotation[crop_before2_position].Tov = tov_SpringBarley;
8239  //issue a message
8240  char index[ 20 ];
8241  sprintf( index, "%d", problem_crop);
8242  g_msg->Warn( WARN_BUG, "OptimisingFarm::Make_rotations(): The following crop was changed to spring barley: ", index );
8243  break; //break the if
8244  }
8245 
8246  crop_index = crop_after; //now crop_after is searching for a place
8247  bool test2=false;
8248  for(int t=0; t<(int)rotation.size() && test2==false; t++){
8249  crop_before1 = rotation[t].Tov;
8250  crop_after1 = (t==99) ? rotation[0].Tov : rotation[t+1].Tov;
8251  int lookup_before1 = m_OurManager->Get_lookup_table(crop_before1 * (tov_Undefined+1) + crop_index); //check with a preceeding crop; tov_undef+1 - because this tov_undef is included in the lookup table
8252  int lookup_after1 = m_OurManager->Get_lookup_table(crop_index * (tov_Undefined+1) + crop_after1); //check with a following crop
8253 
8254  if(lookup_before1==1 && lookup_after1==1){
8255  //check for indefinite loop
8256 
8257  bool skip=true;
8258  for(int s=crop_after_position; s!=t+1; s++){ //check locations between;
8259  if(s==100) s=0;
8260  TTypesOfVegetation crop = rotation[s].Tov;
8261  int lookup = m_OurManager->Get_lookup_table(crop_before2 * (tov_Undefined+1) + crop);
8262  if( lookup == 1){
8263  skip = false;
8264  break; //there is a different crop that the one that we removed (crop_index) - so there shouldnt be an infinite loop
8265  }
8266  }
8267 
8268  if(!skip){
8269 
8270  MakeRotation crop = {true, crop_index};
8271  rotation.insert(rotation.begin() + t+1, crop);
8272  //now the crop to be removed can be at the same or changed position, depending on where we inserted the crop
8273 
8274  if(t+1 > crop_after_position){ //OK
8275  rotation.erase(rotation.begin() + crop_after_position); //remove the crop that was just placed in a new position-from the old one
8276  crop_before2 = (crop_after_position==0) ? rotation[99].Tov : rotation[crop_after_position-1].Tov;
8277  crop_before2_position = (crop_after_position==0) ? 99 : crop_after_position-1;
8278  crop_after = (crop_after_position==99) ? rotation[0].Tov : rotation[crop_after_position].Tov;
8279  crop_after_position = (crop_after_position==99) ? 0 : crop_after_position;
8280  lookup_before = m_OurManager->Get_lookup_table(crop_before2 * (tov_Undefined+1) + crop_after);
8281  }
8282  else{
8283  rotation.erase(rotation.begin() + crop_after_position + 1); //can be 99+1 -ok, now the size is 101
8284  crop_before2 = (crop_after_position==0) ? rotation[99].Tov : rotation[crop_after_position].Tov;
8285  crop_before2_position = (crop_after_position==0) ? 99 : crop_after_position;
8286  crop_after = (crop_after_position==99) ? rotation[0].Tov : rotation[crop_after_position+1].Tov;
8287  crop_after_position = (crop_after_position==99) ? 0 : crop_after_position+1;
8288  lookup_before = m_OurManager->Get_lookup_table(crop_before2 * (tov_Undefined+1) + crop_after);
8289  }
8290  test2=true;
8291  }
8292 
8293  }
8294 
8295  }
8296  count2++;
8297  } //while
8298 
8299  break; //break the for (index p) loop, need to remove just one element
8300  }//undefined removed
8301  }//for:searching for an undef element to remove
8302  }//if:found a place to put an element that doesnt fit in any empty space left
8303  }//for: searching for a place for a problematic crop
8304 
8305  if(test==false){ //we have a problem
8306  char index[ 20 ];
8307  sprintf( index, "%d", crop_index);
8308  //sprintf( index, "%d", m_almass_no);
8309  g_msg->Warn( WARN_BUG, "OptimisingFarm::Make_rotations(): The following tov type cannot be assigned a place in the rotation: ", index );
8310  exit( 1 );
8311  }
8312 
8313  }//there's no empty space that fits for the current crop
8314  }//outer for loop: searcin for an empty spae for a current crop
8315 
8316 
8317  //copy the tovs from rotation vector to the m_rotation vector
8318  for(int i=0; i<100; i++){
8319  m_rotation[i] = rotation[i].Tov;
8320  }
8321 
8322  }//if there are any rotational crops
8323 
8324 else{ //no rotational crops
8325  m_rotation.resize(0);
8326  }
8327 }
8328 
8337  vector<TTypesOfVegetation> veg_type;
8338  //vector<double>profits; //profit from each field
8339  //profits.resize(m_fields.size());
8340 
8341  double priceNt = cfg_Price_Nt.value();
8342 
8343  //for energy maize impacts on wildlife
8344  bool emaize=false;
8345 
8346  //exp. agg. yield - for now it is not necessary to do this every year since the fields size is constant, but later it might change!
8347  m_exp_aggregated_yield = (double)m_fields.size(); //cause each field is expected to give 100% = 1. Except the fields with a crop with exp yield = 0.
8348 
8349  //go through all farm's field:
8350  for(int i=0; i<(int)m_fields.size(); i++){
8351 
8352  CropActualValues crop_data;
8353  TTypesOfVegetation crop;
8354  double biomass=0; double area=0; double yield_loss_pest=0; double no_herb_app=0; double no_fi_app=0;
8355  double unit_loss_herb=0; double unit_loss_fi=0; //to determine or take from field's data
8356  double yield_ha=0; double income_ha=0; double income=0; double costs_ha=0; double costs=0; double profit_ha=0; double profit=0; //to determine
8357  double yield_exp=0; double yield_ratio=0; double income_exp=0; double costs_exp=0; double profit_exp=0; //to account for - it was already calculated per crop in the determine GM function
8358  double sellingPrice=0; double priceHerb=0; double priceFi=0; double priceLM=0; double priceH=0; double priceW=0; double priceG=0; double subsidy=0; //economic data - need to be given as input;
8359  double no_missed_herb_app, no_missed_fi_app = 0; //no_missed - how many applications of herb/fi were missed
8360  double fert_applied=0; double fert_opt=0; double fert_trade=0; double beta1=0; double beta2=0; double alfaH=0; double alfaFI=0;
8361  double yield_factor = 0; //this serves both as biomass-to-yield factor and day degrees-to-yield factor - they are saved in one input table (a single crop has just one of these factors!)
8362  VegElement * pf = dynamic_cast<VegElement*>(m_fields[i]);
8363 
8364  int cropDataStorage_index=-1; //initialize
8365 
8366  if(pf->Get_taken(1)){ //there is a crop at position one - so account for this crop; otherwise go to position 0
8367  crop_data = pf->Get_CropDataStorage(1);
8368  cropDataStorage_index = 1;
8369  }
8370  else{
8371  crop_data = pf->Get_CropDataStorage(0);
8372  cropDataStorage_index = 0;
8373  if(crop_data.taken==false){//error
8374  g_msg->Warn( WARN_BUG, "OptimisingFarm::ActualProfit(): There is no crop data in the fields m_CropDataStorage", "" );
8375  exit( 1 );
8376  }
8377  }
8378 
8379  crop = crop_data.tov_type;
8380 
8381  //for energy maize impacts on wildlife
8382  if (crop==tov_Maize) emaize = true;
8383  //
8384 
8385  bool do_accounting = true;
8386  if(cropDataStorage_index==0){ //could be this crop was not harvested yet
8387  bool harvested = crop_data.harvested;
8390  && !harvested){
8391  //this is a crop that shoud be harvested, but so far it wasn't - so do not account for this crop yet! - just skip this field in accounting
8392  do_accounting = false;
8393  }
8394  }
8395 
8396  if(do_accounting){
8397  area = crop_data.area * 0.0001; //change the units from sq. meters to ha!
8398 
8399  if(crop==tov_SeedGrass1 || crop==tov_SeedGrass2){ //alfaherb is more than 100! - so problem with negative yield
8400  double betaH = crop_parameter(crop, "BetaHerb");
8401  alfaFI = crop_parameter(crop, "AlfaFi");
8402  unit_loss_herb = betaH/100/2;
8403  unit_loss_fi = alfaFI/100;
8404  }
8405  else{
8406  alfaH = crop_parameter(crop, "AlfaHerb");
8407  alfaFI = crop_parameter(crop, "AlfaFi");
8408  unit_loss_herb = alfaH/100; //yield loss per unit of herb application, = max yield loss/optBI = betaH/optBI = alfa. (and /100).
8409  unit_loss_fi = alfaFI/100; //yield loss per unit of fung-insecticide application
8410  }
8411 
8412  //draw random numbers to modify the pest related yield loss
8413  //method from: http://stackoverflow.com/questions/9651024/using-stdtr1normal-distribution-in-qt
8414  std::random_device rd;
8415  std::normal_distribution<double> dist(1, 0.2);
8416  std::mt19937 engine(rd());
8417  double r_number_1 = dist(engine);
8418  double r_number_2 = dist(engine);
8419 
8420 
8421  //determine the pest related yield loss
8422  no_missed_herb_app = crop_data.missed_herb_app;
8423  no_missed_fi_app = crop_data.missed_fi_app;
8424  yield_loss_pest = no_missed_herb_app * unit_loss_herb * r_number_1 + no_missed_fi_app * unit_loss_fi * r_number_2; //total yield loss due to missed pesticide applications
8425 
8426  //determine the yield
8427  biomass = crop_data.biomass_at_harvest;
8428  yield_factor = m_OurManager->pm_data->Get_biomass_factor(tov_Undefined * m_soilType + crop); //crop is tov - integer
8429 
8430  fert_applied = findCropByName_almass (crop)->m_n;
8431  fert_opt = findCropByName_almass (crop)->m_optimalN;
8432  fert_trade = findCropByName_almass (crop)->m_nt;
8433 
8434  int index = tov_Undefined * m_soilType + crop;
8435  beta1=m_OurManager->pm_data->Get_beta1(index);
8436  beta2=m_OurManager->pm_data->Get_beta2(index);
8437 
8438  double dd=m_OurManager->GetDD();
8439 
8440  yield_ha = (biomass==-1)? dd : biomass; //if biomass=-1 this crop is not harvested - use daydegress to estimate the yield
8441  yield_ha *= yield_factor; //multiply by the factor to convert biomass to yield - works both for harvested and not harvested crops.
8442  if(fert_opt!=0){
8443  yield_ha -= (1 - fert_applied/fert_opt) * (beta1 * fert_opt + beta2 * fert_opt*fert_opt); //subtract the amount which depends on the applied ferilizer - if the applied=optimal, then amount subtracted=0. The expression in brackets - with betas - corresponds to the max yield loss-when fert=0.
8444  }
8445  yield_ha *= (1-yield_loss_pest); //finally account for the yield loss due to pests
8446 
8447  //get other numbers for economic calculations
8448  sellingPrice = m_OurManager->pm_data->Get_sellingPrice(tov_Undefined*tos_Foobar*m_farmType + tov_Undefined*m_soilType + crop); //always tov_Undefined because this funtion is called ONLY in almass crop mode!
8449  priceFi = crop_parameter(crop, "PriceFi");
8450  priceHerb = crop_parameter(crop, "PriceHerb");
8451  priceG = crop_parameter(crop, "PriceG");
8452  priceH = crop_parameter(crop, "PriceH");
8453  priceW = crop_parameter(crop, "PriceW");
8454  priceLM = crop_parameter(crop, "PriceLM");
8455  subsidy =crop_parameter(crop, "Subsidy");
8456 
8457  double grooming = findCropByName_almass (crop)->m_grooming;
8458  double hoeing = findCropByName_almass (crop)->m_hoeing;
8459  double weeding = findCropByName_almass (crop)->m_weeding;
8460 
8461  no_herb_app = crop_data.no_herb_app;
8462  no_fi_app = crop_data.no_fi_app;
8463 
8464  //special case for potatoes and fodder beet
8465  if(crop==tov_Potatoes || crop==tov_PotatoesIndustry){
8466  no_herb_app = 1.41; //need to be consistent with numbers in the fix BI function!
8467  no_fi_app = 9.28;
8468  }
8469  if(crop==tov_FodderBeet){
8470  no_herb_app = 2.28; //need to be consistent with numbers in the fix BI function!
8471  }
8472 
8473  //saving the amount of pesticides and fertilizer
8474  if(g_date->GetYearNumber()>9){ //do it for the first time in year 10 ->only then we account for new dec.- modes
8475  for(int i=0; i<m_OurManager->pm_data->Get_noCrops(); i++){
8476  if(m_OurManager->Get_crops_summary_BIs_tov(i) == crop){
8477  m_OurManager->Set_crops_summary_BIs_herb(i, no_herb_app * area);
8478  m_OurManager->Set_crops_summary_BIs_fi(i, no_fi_app * area);
8479  m_OurManager->Set_crops_summary_BIs(i, (no_fi_app+no_herb_app) * area);
8480  m_OurManager->Set_crops_fertilizer(i, fert_applied * area);
8481  m_OurManager->Set_crops_fertilizer_trade(i, fert_trade * area);
8482  break;
8483  }
8484  }
8485  }
8486 
8487 
8488  //GET THE ACTUAL FIGURES:
8489  //1. determine the actual income from this crop: use selling price also for fodder crops! they do not add to income, just diminish the costs of fodder...hm
8490  income_ha = yield_ha * sellingPrice + subsidy;
8491  income = income_ha * area; //total income from this crop
8492 
8493  //2. account for the costs incurred for this crop
8494  costs_ha = no_herb_app*priceHerb + no_fi_app*priceFi + grooming*priceG + hoeing*priceH + weeding*priceW + fert_trade*priceNt+ priceLM;
8495  costs = costs_ha * area;
8496 
8497  //3. determine the actual profit
8498  profit_ha = income_ha - costs_ha;
8499  profit = profit_ha * area;
8500 
8501  //4. determine what part of the expected yield you actually got from this crop - but do this by ha! here there are only crops that were grown this year - because we go through the list of fields
8502  yield_exp = findCropByName_almass (crop)->m_resp;
8503  if(yield_exp!=0){
8504  yield_ratio = yield_ha/yield_exp; // must be min. 0, can be > than 1.
8505  }
8506  else{
8507  m_exp_aggregated_yield -=1; //this crop wasn't expected to yield anything, so exclude it from the sum of expected yields
8508  }
8509 
8510  //add actual figures for this crop to the totals at a farm this year
8511  m_actual_income += income;
8512  m_actual_costs += costs;
8513  m_actual_profit += profit;
8514  m_actual_aggregated_yield += yield_ratio;
8515 
8516 
8517  //add expected figures for this crop to the totals at a farm this year
8518  //get the expected values! use the actual area - otherwise a comparison doesn't make sense!
8519 
8520  //to determine the expected income use last year's price
8521  double resp = findCropByName_almass (crop)->m_resp;
8522  double totalLoss = findCropByName_almass (crop)->m_totalLoss;
8523  double sellingPrice_lastyr = m_OurManager->pm_data->Get_sellingPrice_lastyr(tov_Undefined*tos_Foobar*m_farmType + tov_Undefined*m_soilType + crop); //always tov_Undefined because this funtion is called ONLY in almass crop mode!
8524 
8526  bool fodder = m_OurManager->pm_data->Get_fodder(index1);
8527  if (fodder) income_exp = subsidy;
8528  else income_exp = (sellingPrice_lastyr*resp*(1-totalLoss/100)+subsidy)*area;
8529 
8530  costs_exp = findCropByName_almass (crop)->m_costs_ha *area;
8531  profit_exp = income_exp - costs_exp;
8532 
8533  m_exp_income += income_exp; //add income expected from this crop to the total expected income
8534  m_exp_costs += costs_exp;
8535  m_exp_profit += profit_exp;
8536 
8537  //clean data in this field's struct: remove the data that you just accounted for
8538  pf->Clean_CropDataStorage(cropDataStorage_index);
8539  }
8540  else{//there was no accounting done, print the crop and year in which this happened
8541  #ifdef _DEBUG
8542  g_msg->Warn("OptimisingFarm::ActualProfit(): There was no accounting for tov: ", crop);
8543  //g_msg->Warn("Farm Number: ",GetFarmNumber());
8544  g_msg->Warn("Year Number: ",g_date->GetYearNumber());
8545  #endif
8546  }
8547 
8548  //send the info on this field's crop for the landscape total crop areas accounting
8549  //first find the right index in m_cropTotals:
8550  int index_for_croptotals=0;
8552  for(int k = 0; k<size; k++){
8554  if(crop_type == crop){
8555  index_for_croptotals = k;
8556  break;
8557  }
8558  }
8559  //then add the area of this field to the right element of m_cropTotals; change the units from sq meters to ha.
8560  m_OurManager->Add_to_cropTotals(index_for_croptotals, m_fields[i]->GetArea() * 0.0001); //yearly totals
8561  if(g_date->GetYearNumber()>20){ //do it for the first time in year 10 ->only then we account for new dec.- modes//for wildlife runs - only since year 20 when emaize appears, but here in year 20 we only account for year 19...that's why it has to be '>20'
8562  m_OurManager->Set_cropTotals_sum(index_for_croptotals, m_fields[i]->GetArea() * 0.0001);
8563  if(m_farmType == toof_Plant){
8564  m_OurManager->Set_cropTotals_plant_sum(index_for_croptotals, m_fields[i]->GetArea() * 0.0001);
8565  }
8566  else if(m_farmType == toof_Pig){
8567  m_OurManager->Set_cropTotals_pig_sum(index_for_croptotals, m_fields[i]->GetArea() * 0.0001);
8568  }
8569  else if(m_farmType == toof_Cattle){
8570  m_OurManager->Set_cropTotals_cattle_sum(index_for_croptotals, m_fields[i]->GetArea() * 0.0001);
8571  }
8572  else if(m_farmType == toof_Other){
8573  m_OurManager->Set_cropTotals_other_sum(index_for_croptotals, m_fields[i]->GetArea() * 0.0001);
8574  }
8575  }
8576 
8577  //then add also to farm type specific crop totals
8578 
8579 
8580 
8581  }//for: going through m_fields
8582 
8583 
8584  //print the expected and actual values
8585  ofstream ofile ("Economic_figures.txt", ios::app);
8586  ofile << "farm_no: " << m_almass_no << '\t' << "year_no " << g_date->GetYearNumber() << endl;
8587  ofile << "Expected: " << '\t' <<"Income " << m_exp_income << "\tCosts "<< m_exp_costs << "\tProfit " << m_exp_profit<< "\tAgg.yield " << m_exp_aggregated_yield;
8588  ofile << endl;
8589  ofile << "Actual: " << '\t' << "Income " << m_actual_income << "\tCosts "<< m_actual_costs << "\tProfit " << m_actual_profit<< "\tAgg.yield " << m_actual_aggregated_yield;
8590  ofile << endl <<endl;
8591  ofile.close();
8592 
8593 
8594  //save the economic figures for this year (or rather past - we account for things happen in the year before the current March 1st, xxxx)
8597  m_previous_costs.push_back(m_actual_costs);
8598  m_previous_aggregated_yields.push_back(m_actual_aggregated_yield);
8599 
8600 
8601  double min_need_satisfaction1 = cfg_Min_need_satisfaction1.value();
8602  double min_need_satisfaction2 = cfg_Min_need_satisfaction2.value();
8603  if(cfg_OnlyDeliberation.value()){ //then everybody deliberates (and: min cert is set to 0 when config var OnlyDeliberation is set to true)
8604  min_need_satisfaction1 = 100;
8605  min_need_satisfaction2 = 100;
8606  }
8607 
8609  if(m_exp_profit>0){
8610  if(m_actual_profit >= min_need_satisfaction1*m_exp_profit){
8612  }
8613  else{
8615  }
8616  }
8617  else if(m_exp_profit<0){
8618  if(m_actual_profit >= (2 - min_need_satisfaction1) * m_exp_profit){ //e.g. EP=-1000, AP=-1100 -> ok for MNS<=0.9.
8620  }
8621  else{
8623  }
8624  }
8625  else{ //exp profit = 0
8626  m_need_satisfaction_level = (m_actual_profit >0)? 1 : 0; //need to deal with this case - not very likely to happen
8627  }
8628  }
8629  else if (m_main_goal == tofg_yield){
8630  m_need_satisfaction_level = (m_actual_aggregated_yield >= m_exp_aggregated_yield * min_need_satisfaction2)? 1 : 0 ;
8631  }
8632 
8633  m_previous_satisfaction_levels.push_back(m_need_satisfaction_level); //add it to the list of satisfaction levels from last 5 years
8634  if(m_previous_satisfaction_levels.size()>5){ // it's been more than 5 years since the first accoutning, so...
8635  m_previous_satisfaction_levels.erase(m_previous_satisfaction_levels.begin()); //remove the first element: satisfaction level 6 years ago
8636  }
8637 
8638  //for energy maize impact on wildlife - January 2014
8639  if(cfg_MaizeEnergy.value()){
8640  double threshold = cfg_AnimalsThreshold.value();
8641  double sum = 0;
8642  for(int i=0; i<m_animals_numbers.size(); i++){
8643  sum += m_animals_numbers[i];
8644  }
8645  double avrg_animals_no = 0;
8646  if(m_animals_numbers.size()>0){
8647  avrg_animals_no = sum/m_animals_numbers.size();
8648  }
8649 
8650  if(emaize && animals_no < threshold * avrg_animals_no && m_animals_numbers.size()>2){ //three conditions: 1. you actually have grown energy maize
8651  // 2. the animal numbers have decreased below the acceptable level 3. you have data on animal numbers from min. 3 years
8652  //then set the rotation max. for energy maize to zero and force deliberation to stop growing energy maize
8653  CropOptimised *em = findCropByName_almass ("Maize");
8654  em->m_rotationMax = 0;
8655  force_deliberation = true;
8656  }
8657  m_animals_numbers.push_back(animals_no);
8658  if(m_animals_numbers.size() > 3){ //have data for more than 3 years now
8659  m_animals_numbers.erase(m_animals_numbers.begin()); //remove the oldest data - first element
8660  }
8661 
8662  //force optimisation when energy maize price changed by more than a given %
8665  if(abs(EMPrice_current - EMPrice_lastyr) > EMPrice_lastyr * cfg_PriceChangeThreshold.value()){
8666  force_deliberation = true;
8667  }
8668  }
8669  //
8670 
8671  //and restart the actual and expected values - for next year
8672  m_exp_income = 0;
8673  m_exp_costs = 0;
8674  m_exp_profit = 0;
8675  //exp agg yield is determined at the begininng of this function;
8676  m_actual_income = 0;
8677  m_actual_costs = 0;
8678  m_actual_profit = 0;
8679  m_actual_aggregated_yield = 0;
8680 
8681 }
8682 
8683 
8685 
8701  double field_size_pct = a_field->GetArea()/GetArea() * 100; //convert field size to pct of total arable farm area (a_rotational_crops will contain values of areas in %)
8702  TTypesOfVegetation current_crop =a_field->GetVegType();
8703  TTypesOfVegetation crop_to_grow = tov_Undefined;
8704 
8705  if(current_crop==tov_PermanentGrassGrazed || current_crop==tov_PermanentGrassTussocky || current_crop==tov_PermanentSetaside ||
8706  current_crop==tov_PermanentGrassLowYield || current_crop==tov_YoungForest || current_crop==tov_OrchardCrop) {
8707 
8708  crop_to_grow = current_crop; //and do not switch rot index - has to stay as it is to mark the field as perm
8709  }
8710  else{
8711 
8712  if((int)m_rotational_crops_copy.size()==0 ){ // in the 1st year it is empty since the choose dec. mode was not called yet!
8713  m_rotational_crops_copy = m_rotational_crops; //restart the copy - it is empty and we still need crops
8714  //debug
8715  if((int)m_rotational_crops_copy.size()==0){ //should not happen!
8716  char index[ 20 ];
8717  sprintf( index, "%d", m_almass_no);
8718  g_msg->Warn( WARN_BUG, "OptimisingFarm::Match_crop_to_field(): rot crops vector is empty! Farm no: ", index );
8719  exit( 1 );
8720  }
8721  }
8722 
8723  if (current_crop==tov_SeedGrass1){
8724  bool sg2=false;
8725  for(int i=0; i< (int)m_rotational_crops_copy.size(); i++){
8727  if(crop==tov_SeedGrass2) sg2 = true;
8728  }
8729  if (!sg2){ //there is no seedgrass2 in the list of crops. Otherwise just go to the normal procedure of choosing crop
8730  crop_to_grow = tov_SeedGrass2;
8731  }
8732  }
8733  if (current_crop==tov_CloverGrassGrazed1){
8734  bool cgg2=false;
8735  for(int i=0; i< (int)m_rotational_crops_copy.size(); i++){
8737  if(crop==tov_CloverGrassGrazed2) cgg2 = true;
8738  }
8739  if (!cgg2){ //there is no tov_CloverGrassGrazed2 in the list of crops. Otherwise just go to the normal procedure of choosing crop
8740  crop_to_grow = tov_CloverGrassGrazed2;
8741  }
8742  }
8743 
8744  if (current_crop!=tov_SpringBarley){
8745  bool other_crop_than_cgg = false;
8746  for(int i=0; i< (int)m_rotational_crops_copy.size(); i++){
8749  other_crop_than_cgg = true;
8750  break;
8751  }
8752  }
8753  if (!other_crop_than_cgg){ //there is no other tov than CGG1 or CGG2 in the list of crops. So need to grow smth which will fit - SB.
8754  crop_to_grow = tov_SpringBarley;
8755  }
8756  }
8757 
8758  bool Sb_inserted=false;
8759  if(crop_to_grow==tov_Undefined){ //if not, it is already CGG2 or SG
8760 
8761  //create the vector with numbers
8762  vector<int>probability_line;
8763  probability_line.push_back(0); //add the first element
8764  for(int i=0; i< (int)m_rotational_crops_copy.size(); i++){
8765  if(m_rotational_crops_copy[i].Number<0.5) m_rotational_crops_copy[i].Number += 0.5; //just in case - to avoid having crops that disappeear
8766  int area = (int)(m_rotational_crops_copy[i].Number + 0.5); //change to integer
8767  probability_line.push_back(area + (int)probability_line[probability_line.size() - 1]); //add a number equal to the sum of the current last element and this crop's area
8768  }
8769 
8770  //pick an index of a crop
8771  //see: http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution
8772  std::random_device rd;
8773  std::mt19937 gen(rd());
8774  int last_number = probability_line[(int)probability_line.size() - 1]; //the last number
8775  distribution_type2 dis(0, last_number - 1);
8776  double crop_index = 0;
8777 
8778  double diff = 0;
8779  int index_j = 0;
8780  bool crop_found = false;
8781  for(int c = 0; !crop_found; c++){
8782  crop_index = dis(gen); //int from a range 0 - sum of crop areas in percent - only crops that haven't been grown yet - on their 'full' i.e. planned area
8783  //which crop is it?
8784  for(int j=0; j < (int)probability_line.size(); j++){
8785  if(j==(int)probability_line.size()-1) { //unless j=0 smth's wrong: we didnt find this index
8786  if(j==0){ //there are no crops left - prob. line contains just one element - 0.why?
8787  char index[ 20 ];
8788  sprintf( index, "%d", (int) crop_index);
8789  g_msg->Warn( WARN_BUG, "OptimisingFarm::Match_crop_to_field(): no crops left, index drawn is ", index );
8790  exit( 1 );
8791  }
8792  else{
8793  char index[ 20 ];
8794  sprintf( index, "%d", (int) crop_index);
8795  g_msg->Warn( WARN_BUG, "OptimisingFarm::Match_crop_to_field(): index not found in the prob. line", index );
8796  exit( 1 );
8797  }
8798  }
8799  if(crop_index >= probability_line[j] && crop_index < probability_line[j+1]) {
8800  if(j >= (int)m_rotational_crops_copy.size()) { //problem
8801  char index[ 20 ];
8802  sprintf( index, "%d", j);
8803  g_msg->Warn( WARN_BUG, "OptimisingFarm::Match_crop_to_field(): index out of a range", index );
8804  exit( 1 );
8805  }
8806  crop_to_grow = m_rotational_crops_copy[j].Tov;
8807  index_j = j;
8808  break; //got the crop type
8809  }
8810 
8811  }
8812  //make a check
8813  int lookup_before = m_OurManager->Get_lookup_table(current_crop * (tov_Undefined+1) + crop_to_grow); //check with a preceeding crop; tov_undef+1 - because this tov_undef is included in the lookup table
8814  if(lookup_before==-1){ //issue a warning: wrong index...
8815  char index[ 20 ];
8816  sprintf( index, "%d", current_crop);
8817  g_msg->Warn( WARN_BUG, "OptimisingFarm::Match_crop_to_field(): Error (possibly caused by a new tov type that is not incuded in the crops_lookup table) in reading the lookup table; tov type that should not appear: ", index );
8818  exit( 1 );
8819  }
8820  if(lookup_before==1){ //if so, make another check - but not if we tried already 20 times - then release this constraint
8821 
8822  bool WRape_grown = false;
8823  if(cfg_Areas_Based_on_Distribution.value()){ //then another check: spring rape cannot be grown if the farm grows winter rape within 1000 m (www.landbrugsinfo.dk)
8824  if(crop_to_grow == tov_SpringRape){
8825  for(int w=0; w<(int)m_fields.size(); w++){
8826  if(m_fields[w]->GetVegType() == tov_WinterRape) WRape_grown = true;
8827  }
8828  }
8829  }
8830 
8831  if(c<20){
8832  diff = field_size_pct - m_rotational_crops_copy[index_j].Number;
8833  if(diff <= 20 && !WRape_grown){ //diff in size smaller than 20 percent points - ok. Plus there is no winter rape around in case the chosen crop is SRape
8834  crop_found=true;
8835  break; //break the for - this crop is OK
8836  }
8837  }
8838  else{
8839  diff = field_size_pct - m_rotational_crops_copy[index_j].Number;
8840  if(!WRape_grown){
8841  crop_found=true; //this crop must be accepted
8842  break;
8843  }
8844  }
8845  }
8846  if(c==1000 && !crop_found){ //seems there's no crop that can follow the current one, so restart the crops instead and continue the search!
8847  m_rotational_crops_copy = m_rotational_crops; //restart - that's not enough - need a new prob line
8848  probability_line.clear();
8849  probability_line.push_back(0); //add the first element
8850  for(int i=0; i< (int)m_rotational_crops_copy.size(); i++){
8851  if(m_rotational_crops_copy[i].Number<0.5) m_rotational_crops_copy[i].Number += 0.5; //necessary to avoid having crop disappeeared
8852  int area = (int)(m_rotational_crops_copy[i].Number + 0.5); //change to integer
8853  probability_line.push_back(area + (int)probability_line[probability_line.size() - 1]); //add a number equal to the sum of the current last element and this crop's area
8854  }
8855 
8856  last_number = probability_line[(int)probability_line.size() - 1]; //the last number
8857  distribution_type2 dis(0, last_number - 1);
8858  }
8859  if(c>1500){ //seems there's no crop that can follow the current one - issue a warning; but now do this only after restarting
8860  #ifdef _DEBUG
8861  char index[ 20 ];
8862  sprintf( index, "%d", current_crop);
8863  g_msg->Warn( WARN_BUG, "OptimisingFarm::Match_crop_to_field(): There is no crop that can follow the current crop. Sbarley will be grown. The current crop is: ", index );
8864  #endif
8865  crop_to_grow=tov_SpringBarley;
8866  Sb_inserted=true;
8867  break;
8868  //exit( 1 );
8869  }
8870  }
8871 
8872  //crop found, so update the vector of crops
8873  if(!Sb_inserted){
8874  if(diff < 0){ //crop area should be larger than this field's area
8875  m_rotational_crops_copy[index_j].Number -= field_size_pct;
8876  }
8877  else{
8878  if(m_rotational_crops_copy.size() <1){ //smth is wrong
8879  char index[ 20 ];
8880  sprintf( index, "%d", current_crop);
8881  g_msg->Warn( WARN_BUG, "OptimisingFarm::Match_crop_to_field(): m_rotational_crops_copy is empty, the crop chosen is: ", index );
8882  exit( 1 );
8883  }
8884  m_rotational_crops_copy.erase(m_rotational_crops_copy.begin() + index_j);
8885  }
8886  }
8887  }
8888 
8889  //switch the rotational index:
8890 
8891  //1. find the chosen crop in the m_rotation
8892  int position_in_mrotation=-1;
8893  int size=(int)m_rotation.size();
8894 
8895  for(int c=0; c< (int)m_rotation.size(); c++){
8896  if(m_rotation[c] == crop_to_grow){
8897  position_in_mrotation=c;
8898  break;
8899  }
8900  }
8901 
8902  if(position_in_mrotation==-1){
8903  char error_num[ 20 ];
8904  sprintf( error_num, "%d", crop_to_grow );
8905  g_msg->Warn( WARN_FILE, "OptimisingFarm::Match_crop_to_field(): ""Unknown vegetation type:", error_num );
8906  exit( 1 );
8907  }
8908  //2. switch the rot index to a crop just before the chosen one
8909  if(position_in_mrotation!=0){
8910  a_field->SetRotIndex(position_in_mrotation-1);
8911  }
8912  else{
8913  a_field->SetRotIndex(size-1);
8914  }
8915  }//current crop is a rotational crop
8916 }
8917 
8922 polylist* Farm::ListOpenFields( int a_openness )
8923 {
8924  polylist* p_list = new polylist;
8925  int nf = (int) m_fields.size();
8926  for ( int i = 0; i < nf; i++ )
8927  {
8928  if ( m_fields[ i ]->GetOpenness() >= a_openness )
8929  {
8930  p_list->push_back( m_fields[i]->GetPoly());
8931  }
8932  }
8933  return p_list;
8934 }
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1234
TTypesOfOptFarms
Definition: farm.h:224
TTypesOfFarmSize Get_farmSize(void)
Definition: farm.h:1893
#define PROG_START
Definition: farm.h:76
Inbuilt farm type.
Definition: farm.h:955
double m_rotationMin
Minimum area in percent of farm&#39;s arable area for a given crop (depends on a farm size...
Definition: farm.h:1509
CfgInt cfg_Animals_number_test_day("ANIMALS_NUMBER_TEST_DAY", CFG_CUSTOM, 152)
This parameter specifies the day at which farmers observe the number of animals residing at their far...
UserDefinedFarm11(FarmManager *a_manager)
Definition: farm.cpp:1871
TTypeOfFarmerGoal Get_main_goal()
Definition: farm.h:1915
void Print_FarmVariables(ofstream *ap_output_file)
Prints farm-level variables to a text file (one file for all farms).
Definition: farm.cpp:7568
void PrintOutput(TTypesOfCropVariables a_var, string a_fileName)
Makes an output file for one crop variable and prints its values for each crop and each OptimisingFar...
Definition: farm.cpp:4027
Inbuilt farm type.
Definition: farm.h:967
CfgBool cfg_UseBedriftsmodelFarmAreas("USE_BEDRIFTSMODEL_FARM_AREAS", CFG_CUSTOM, false)
If set to true, the farm areas from the original farm optimisation model are used in the optimisation...
UserDefinedFarm5(FarmManager *a_manager)
Definition: farm.cpp:1824
TTypesOfLivestockParameters
Definition: farm.h:338
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1252
DataForOptimisation()
The constructor.
Definition: farm.cpp:4573
vector< double > m_previous_satisfaction_levels
Vector of satisfaction levels in five previous years.
Definition: farm.h:2002
CfgBool g_farm_fixed_rotation_farms_async("FARM_FIXED_ROTATION_FARMS_ASYNC", CFG_CUSTOM, false)
UserDefinedFarm13(FarmManager *a_manager)
Definition: farm.cpp:1885
vector< CropSort > m_winterCrops
Vector of structs containing pointers to winter crops.
Definition: farm.h:2055
The landscape class containing all environmental and topographical data.
Definition: landscape.h:109
virtual int GetFirstCropIndex(TTypesOfLandscapeElement a_type)
Gets the first crop for the farm.
Definition: farm.cpp:1099
UserDefinedFarm28(const char *fname, FarmManager *a_manager)
Definition: farm.cpp:2132
void sumMinAreas()
Adds minimum required areas of variable crops to the variable m_assigned.
Definition: farm.cpp:5817
Subclass of the OptimisingFarm. Either pig or cattle farm.
Definition: farm.h:2232
virtual void decreaseCrops(vector< CropSort >cropsToDecrease, double &howMuchToDecrease)
Decreases area of cropsToDecrease by howMuchToDecrease.
Definition: farm.cpp:7454
OrganicPig(FarmManager *a_manager)
Definition: farm.cpp:1617
virtual void checkWinterRotation1()
Animal farm version of the OptimisingFarm::checkWinterRotation1() function (accounts for fodder chang...
Definition: farm.cpp:6159
void ActualProfit()
Calls OptimisingFarm::ActualProfit for all optimising farms.
Definition: farm.cpp:2956
virtual void HandleEvents(void)
If there are events to carry out do this, and perhaps start a new crop.
Definition: farm.cpp:755
Definition: farm.h:235
long Date(void)
Definition: calendar.h:57
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1189
int Get_almass_no(void)
Definition: farm.h:1896
void randomizeCropList(vector< CropSort > &listToRandomize, string key)
Swaps randomly elements of the list holding same values of the key (according to which the list was p...
Definition: farm.cpp:7334
Inbuilt special purpose farm type.
Definition: farm.h:1049
~FarmManager()
Farm manager destructor.
Definition: farm.cpp:2250
void Make_rotational_crops()
Creates a vector m_rotational_crops using the results of optimisation.
Definition: farm.cpp:7808
CfgBool cfg_OnlyDeliberation("ONLY_DELIBERATION", CFG_CUSTOM, true)
If set to yes, the only decision mode/startegy the farmers can use is deliberation (i...
int GetNextCropStartDate(LE *a_field, TTypesOfVegetation &a_curr_veg)
Returns the start date of the next crop in the rotation.
Definition: farm.cpp:666
UserDefinedFarm1(FarmManager *a_manager)
Definition: farm.cpp:1792
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1005
TTypesOfFarmSize md_farmSize
Definition: farm.h:596
void AssignPermanentCrop(TTypesOfVegetation tov, int pct)
Used to assign a permanent crop to an otherwise rotational field polygon.
Definition: farm.cpp:1973
void ChooseDecisionMode_for_farms()
Calls OptimisingFarm::ChooseDecisionMode for all optimising farms.
Definition: farm.cpp:2967
void Check_SG_and_CGG()
Modifies areas of SeedGrass1 and SeedGrass2, CloverGrassGrazed1 and CloverGrassGrazed2 to be even...
Definition: farm.cpp:5400
void findFertilizer(CropOptimised *a_crop, int a_foobar, double benefit)
Determines the optimal amounts of: total fertilizer (CropOptimised::m_n) and purchased fertilizer (Cr...
Definition: farm.cpp:5429
vector< CropOptimised * > m_fixedCrops
Vector of pointers to fixed crops.
Definition: farm.h:2051
TTypesOfFarmSize TranslateFarmSizeCodes(string &str)
Definition: farm.cpp:3821
double crop_parameter(int index, string par_name)
Reads in crop parameters that do NOT vary with any farm level parameters.
Definition: farm.cpp:7279
int Get_winterMax(int i)
Definition: farm.h:530
UserDefinedFarm26(const char *fname, FarmManager *a_manager)
Definition: farm.cpp:2122
void ReadLivestockData()
Reads the data on livestock parameters (do not vary with farm variables) and saves them in a vector D...
Definition: farm.cpp:3735
void Set_Crop(CropOptimised *p_crop)
Definition: farm.h:1900
TTypesOfFarm GetType(void)
Definition: farm.h:803
vector< LE * > m_fields
Definition: farm.h:839
CfgFloat cfg_Price_SBarley("PRICE_SBARLEY", CFG_CUSTOM, 83)
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1428
TTypesOfOptFarms m_farmType
Farm&#39;s type (cattle, pig, plant, other).
Definition: farm.h:2067
UserDefinedFarm34(const char *fname, FarmManager *a_manager)
Definition: farm.cpp:2162
long m_run
Definition: farm.h:396
CfgFloat cfg_Min_certainty("MIN_CERTAINTY", CFG_CUSTOM, 0)
A parameter setting the minimum certainty level.
void findBIs(CropOptimised *a_crop, double benefit)
Determines the optimal Treatment frequency indices (behandling index, BI in Danish) (CropOptimised::m...
Definition: farm.cpp:5570
bool DoIt(int a_probability)
Return chance out of 100.
Definition: farm.cpp:610
UserDefinedFarm10(FarmManager *a_manager)
Definition: farm.cpp:1864
double m_totalFUgrown
Fodder grown, i.e. obtained from growing fodder crops. [fodder units].
Definition: farm.h:2097
virtual void increaseCrops(vector< CropSort >cropsToIncrease, double &howMuchToIncrease)
Increases area of cropsToIncrease by howMuchToIncrease.
Definition: farm.cpp:7397
TTypesOfParameters
Definition: farm.h:317
Definition: farm.h:352
CfgBool g_farm_enable_crop_rotation("FARM_ENABLE_CROP_ROTATION", CFG_CUSTOM, true)
vector< int > FarmHuntRef
The hunter&#39;s is the farm reference number to where he hunts.
Definition: farm.h:448
void Print_rotations(ofstream *ap_output_file)
Prints the content of a farm&#39;s m_rotation. Not used in ALMaSS crop mode.
Definition: farm.cpp:7912
vector< double > m_previous_incomes
Vector of incomes from previous years.
Definition: farm.h:1996
int GetNoOpenFields(int a_openness)
Returns the number of the fields above an openness of a_openness.
Definition: farm.cpp:1073
double m_totalBIHerb
Total amount of herbicides which is planned to be applied at a farm. Expressed as a Treatment frequen...
Definition: farm.h:2105
virtual bool Spraying_herbicides(TTypesOfVegetation a_tov_type)
Returns true if a farmer decided to treat a given crop with herbicides.
Definition: farm.cpp:4871
bool CheckOpenness(int a_openness, int a_ref)
Check if a farm has at least one field with openness above a_openness.
Definition: farm.cpp:2922
void determineMinFodder(int a_foobar)
Covers the min. required fodder production for animal farms.
Definition: farm.cpp:7064
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1448
double Get_sellingPrice_lastyr(int i)
Definition: farm.h:566
Inbuilt special purpose farm type.
Definition: farm.h:1071
void ReadLivestockNumbers()
Reads the data on livestock numbers and saves them in a vector DataForOptimisation::m_livestockNumber...
Definition: farm.cpp:3053
UserDefinedFarm3(FarmManager *a_manager)
Definition: farm.cpp:1808
vector< int > m_decision_mode_counters
Vector with counters for each decision mode. 0 - imitation, 1 - social comparison, 2 - repeat, 3 - deliberation.
Definition: farm.h:1971
OptimisingFarm * Find_neighbour_to_imitate()
Picks randomly a farmer to imitate/compare with. It chooses among neighbouring farmers with similar f...
Definition: farm.cpp:4903
void setCattleCropsAtMin()
Decreases area of cattle crops to their min. required area.
Definition: farm.cpp:6550
Class storing farm information: farm&#39;s number used in ALMaSS system, farm&#39;s soil type, farm&#39;s size (business or private) and farm&#39;s real ID number.
Definition: farm.h:591
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1144
virtual void SetVegType(TTypesOfVegetation, TTypesOfVegetation)
Definition: elements.h:164
CropOptimised * findCropByName(string crop_name)
Returns a pointer to a crop whose name is specified as the argument (bedriftsmodel, i.e. original farm optimization model, crops mode).
Definition: farm.cpp:7285
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1368
bool LeSwitch(FarmEvent *ev)
Call do function for any crop with an outstanding event. Signal if the crop has terminated.
Definition: farm.cpp:331
vector< CropOptimised * > m_crops
Vector of pointers to all crops.
Definition: farm.h:2040
vector< AlmassCrop > m_crops_almass
Vector of structs with almass type crops with positive areas in % (result of optimisation).
Definition: farm.h:2057
virtual void InitiateManagement(void)
Kicks off the farm&#39;s management.
Definition: farm.cpp:1227
void FarmManagement()
Runs the daily farm management for each farm, but also calculates annual spilled grain and maize...
Definition: farm.cpp:2258
void Set_tov_type(TTypesOfVegetation a_tov_type, int index)
Definition: elements.h:568
UserDefinedFarm24(const char *fname, FarmManager *a_manager)
Definition: farm.cpp:2112
CropOptimised * findCropByName_almass(string crop_name)
Returns a pointer to almass crop whose name is specified as the argument (ALMaSS crops mode)...
Definition: farm.cpp:7293
void Set_crops_summary_BIs(int i, double BI)
Definition: farm.h:1713
vector< CropSort > m_variableCrops
Vector of structs containing pointers to crops which are not fixed.
Definition: farm.h:2042
CfgBool g_farm_fixed_crop_enable("FARM_FIXED_CROP_ENABLE", CFG_CUSTOM, false)
void checkCattleRotation_almass()
Checks if the cattle restriction is fulfilled - in the ALMaSS crops mode.
Definition: farm.cpp:6827
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1288
TTypeOfFarmerGoal m_main_goal
Farmer&#39;s main goal (determined by a farmer&#39;s type) .
Definition: farm.h:1960
CfgFloat cfg_Price_FU("PRICE_FU", CFG_CUSTOM, 1.157)
Price of a fodder unit. [DKK/FU].
void SetRotIndex(int a_index)
Definition: elements.h:301
Inbuilt special purpose farm type.
Definition: farm.h:1061
UserDefinedFarm31(const char *fname, FarmManager *a_manager)
Definition: farm.cpp:2147
UserDefinedFarm18(const char *fname, FarmManager *a_manager)
Definition: farm.cpp:2082
void DistributeFarmerTypes()
Randomly assigns farmer types to farms (OptimisingFarm) in proportions specified in an input file...
Definition: farm.cpp:4488
ConventionalCattle(FarmManager *a_manager)
Definition: farm.cpp:1554
double m_exp_income
An expected farm&#39;s income at a farm in a given year.
Definition: farm.h:1981
boost::variate_generator< base_generator_type &, boost::uniform_real<> > g_rand_uni
double m_area_rot
Area assigned to rotational crops. [ha].
Definition: farm.h:2123
CfgFloat cfg_Yield_max_proportion("YIELD_MAX_PROPORTION", CFG_CUSTOM, 0)
A parameter setting the proportion of farmers of a type yield maximiser.
UserDefinedFarm(const char *fname, FarmManager *a_manager)
Definition: farm.cpp:1921
double m_actual_profit
An actual profit realised at a farm in a given year.
Definition: farm.h:1975
virtual void preventCashCrops()
Prevents small cattle farms from growing cash crops and maize silage.
Definition: farm.h:2150
TTypesOfFarmSize m_farmSize
Scale of the farm - business (size above 10 ha) or private (size below 10 ha).
Definition: farm.h:2071
A data structure to hold hunter information for distribution.
Definition: farm.h:438
int GetTotalArea(void)
Returns the area of all fields owned by that farm.
Definition: farm.cpp:1054
CfgBool cfg_Areas_Based_on_Distribution("AREAS_BASED_ON_DISTRIBUTION", CFG_CUSTOM, false)
If set to true, crops are assigned area based on their gross margin proportion in the total GM for al...
void DumpFarmrefs()
dumps the farmrefs file to a standard named file
Definition: farm.cpp:2548
void SimpleEvent(long a_date, int a_todo, bool a_lock)
Adds an event to this crop management.
Definition: farm.cpp:257
UserDefinedFarm33(const char *fname, FarmManager *a_manager)
Definition: farm.cpp:2157
double m_income_ha
Value of income per ha of a crop. Includes value of sales and subsidy [DKK/ha].
Definition: farm.h:1544
Subclass of the NonAnimalFarm.
Definition: farm.h:2352
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1153
UserDefinedFarm19(const char *fname, FarmManager *a_manager)
Definition: farm.cpp:2087
vector< CropSort > m_rotationCrops
Vector of structs containing pointers to (winter) rotation crops.
Definition: farm.h:2053
double m_costs_ha
Costs of growing 1 ha of a crop. Include costs of labour and machine (constant), pesticides (herbicid...
Definition: farm.h:1542
void determineFodderAreas(int a_foobar)
Determines areas of fodder crops and corrects areas of non-fodder crops.
Definition: farm.cpp:7142
CfgBool cfg_OptimisingFarms("OPTIMISING_FARMS", CFG_CUSTOM, false)
If set to true, the farmer decision making model is active.
int GetYearNumber(void)
Definition: calendar.h:68
void SetOwner(Farm *a_owner, int a_owner_num, int a_owner_index)
Definition: elements.h:213
void Make_rotations()
Creates m_rotation. Not used in ALMaSS crop mode.
Definition: farm.cpp:7926
FarmManager()
Farm manager constructor.
Definition: farm.cpp:2177
int FindClosestFarmOpennessProbSmallIsBest(HunterInfo a_hinfo, vector< int > *a_farmlist, int a_openness, vector< int > *a_farmsizelist)
Finds the closest farm to this co-ordinate with openness more than a value but uses a probability dis...
Definition: farm.cpp:2756
int homeY
Hunter home y-coord.
Definition: farm.h:446
Integer configurator entry class.
Definition: configurator.h:85
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1225
double Get_FUKey(int i)
Definition: farm.h:561
double m_BIFi
Value of BI for fung- and insecticides [BI/ha].
Definition: farm.h:1526
void FarmLevelCalculation()
Calls functions determining farm level values before the initial optimisation.
Definition: farm.cpp:5136
void Save_diff_farm_types_areas()
Calculates and saves total areas of all optimising farms and specific farm types. ...
Definition: farm.cpp:2927
CfgBool cfg_DumpFarmAreas("DUMP_FARM_AREAS", CFG_CUSTOM, false)
If set to true, an output file with farm areas is produced.
void Set_crops_summary_BIs_fi(int i, double BIfi)
Definition: farm.h:1712
TTypesOfOptFarms TranslateFarmCodes(string &str)
Definition: farm.cpp:3796
virtual void findFodderDemand()
Determines farm&#39;s total demand for fodder (m_totalFUdemand).
Definition: farm.cpp:5193
Definition: farm.h:253
void ReadInitialCropAreas()
Reads the data on farms&#39; initial crop distributions and saves them in a vector DataForOptimisation::m...
Definition: farm.cpp:3094
double total(TTypesOfCropVariables variable_name)
Function for determining total values per farm after initial optimisation.
Definition: farm.cpp:7500
A class for storing livestock parameters and variables for optimising farms.
Definition: farm.h:1474
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1243
void RemoveField(int a_OwnerIndex, LE *a_field)
Definition: farm.cpp:2298
int FindClosestFarmOpenness(HunterInfo a_hinfo, vector< int > *a_farmlist, int a_openness)
Finds the closest farm to this co-ordinate but uses a probability distribtution for acceptance...
Definition: farm.cpp:2678
Definition: farm.h:348
int Pct
Definition: farm.h:378
CfgFloat cfg_Environmentalist_proportion("ENVIRONMENTALIST_PROPORTION", CFG_CUSTOM, 0)
A parameter setting the proportion of farmers of a type environmentalist.
int Get_cropsSize(void)
Definition: farm.h:1898
int Get_decision_mode_counters(int index)
Definition: farm.h:1917
TTypesOfAnimals Get_livestockTypes(int i)
Definition: farm.h:514
CfgFloat cfg_Price_WWheat("PRICE_WWHEAT", CFG_CUSTOM, 94)
double Get_cropArea(int index)
Definition: farm.h:523
double m_Nanim
Amount of animal fertilizer available at a farm per hectar. [kg/ha].
Definition: farm.h:2089
Definition: farm.h:258
CfgFloat cfg_ClosestFarmProbParam2("CLOSESTFARMPROBPARAMTWO", CFG_CUSTOM, 1.0)
A fitting parameter for the probability of hunter acceptance of a farm with distance from home - scal...
double m_totalNanim
Total animal fertilizer at a farm. A sum of Livestock::m_NanimUsable (from all types of livestock)...
Definition: farm.h:2087
void Check_if_area_100()
Checks if the sum of crops&#39; areaPercent is 100%.
Definition: farm.cpp:7583
CfgBool cfg_MaizeEnergy("MAIZE_ENERGY", CFG_CUSTOM, false)
If set to true, the energy maize crop is included in the simulation.
void assignFixed()
Adds areas of fixed crops to the variable m_assigned. For each fixed crop it saves its area under var...
Definition: farm.cpp:5798
void PrintFinalResults()
At the end of a simulation it prints results on crop distribution, pesticide and fertilizer usage...
Definition: farm.cpp:4264
CfgFloat cfg_Yield_max_pest_prob_multiplier("YIELD_MAX_PEST_PROB_MULITPLIER", CFG_CUSTOM, 1.5)
A parameter of the yield maximizer farmer type: it increases the chance of necessity of carrying out ...
boost::random::uniform_int_distribution distribution_type2
double Get_actual_profit()
Definition: farm.h:1910
double m_lossFi
Value of the yield loss due to the limited use of fung- and insecticides [%].
Definition: farm.h:1538
Struct redefining operator < - used for sorting crops.
Definition: farm.h:2024
TTypesOfVegetation
double m_actual_aggregated_yield
Actual aggregated yield at a farm in a given year.
Definition: farm.h:1988
TTypesOfOptFarms Get_farmType(void)
Definition: farm.h:1891
double value(void)
Definition: configurator.h:107
void DumpFarmAreas()
Definition: farm.cpp:1536
Definition: elements.h:81
TTypesOfVegetation Tov
Definition: farm.h:377
vector< AlmassCrop > m_rotational_crops_copy
A copy of m_rotational_crops used when matching crops to fields.
Definition: farm.h:2061
double m_totalWeeding
Total manual weeding planned at a farm.
Definition: farm.h:2115
double m_totalFUdemandBefore
Farm&#39;s total demand for fodder. [fodder units]
Definition: farm.h:2091
Definition: farm.h:247
double m_areaPercent
Area of a crop in percent of a farm&#39;s total area [%].
Definition: farm.h:1552
long GetMgtLoopDetectCount(void)
Definition: elements.h:121
Subclass of the NonAnimalFarm.
Definition: farm.h:2361
Definition: farm.h:259
A farm that carries out crop, pesticide and fertilizer planning using simplified optimisation or othe...
Definition: farm.h:1885
int GetFarmCentroidX()
Definition: farm.h:1912
virtual int GetNextCropIndex(int a_rot_index)
Returns the next crop in the rotation.
Definition: farm.cpp:1141
UserDefinedFarm30(const char *fname, FarmManager *a_manager)
Definition: farm.cpp:2142
double m_resp
Response - yield of a crop per ha [hkg/ha].
Definition: farm.h:1522
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1418
TTypesOfVegetation m_event
Definition: farm.h:398
TTypesOfFarmSize
Definition: farm.h:239
void AddField(int a_OwnerIndex, LE *a_newland, int a_Owner)
Definition: farm.cpp:2292
bool IsDuplicateRef(int a_ref, HunterInfo *a_hinfo)
Checks if we already have this ref.
Definition: farm.cpp:2639
Struct for storing ALMaSS crop type (TTypesOfVegetation) with a corresponding value (mainly crop area...
Definition: farm.h:496
CfgBool cfg_organic_extensive("FARM_ORGANIC_EXTENSIVE", CFG_CUSTOM, false)
void Set_animals_no(int a_number)
Definition: farm.h:1916
void Make_almass_crops_vector()
Creates a vector storing crops with positive area. Used in ALMaSS crop mode.
Definition: farm.cpp:7792
double m_totalFUt
Fodder from trade (has to be purchased). [fodder units].
Definition: farm.h:2095
void Set_Livestock(Livestock *p_lvs)
Definition: farm.h:1899
virtual double Prob_multiplier()
Used when determining whether there should be a spraying event (i.e. pesticides application) or not...
Definition: farm.cpp:4895
double m_totalArea
Total area of a farm. A sum of initial crop areas (if in bedriftsmodel, i.e. original farm optimizati...
Definition: farm.h:2081
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1438
Inbuilt special purpose farm type.
Definition: farm.h:1080
double m_areaVariable
Area of a crop that can be changed when checking for restrictions (=m_areaPercent - m_rotationMin) [%...
Definition: farm.h:1554
void InitFarms()
Calls OptimisingFarm::Init for all optimising farms.
Definition: farm.cpp:2565
Definition: farm.h:233
vector< CropSort > m_variableCrops2
Vector of structs containing pointers to crops which are not fixed and: in case of the winter rotatio...
Definition: farm.h:2047
void ReadFarmsData()
Reads farm level parameters and saves them in a vector DataForOptimisation::m_farm_data.
Definition: farm.cpp:3007
CfgFloat cfg_FarmSizeProbParam1("FARMSIZEPROBPARAMONE", CFG_CUSTOM, 1.5)
A fitting parameter for the probability of hunter acceptance of a farm that is smaller.
double m_actual_costs
Actual costs at a farm in a given year.
Definition: farm.h:1983
vector< TTypesOfVegetation > m_rotation
Definition: farm.h:840
virtual void InitiateManagement(void)
Kicks off the farm&#39;s management.
Definition: farm.cpp:1212
int Get_livestockNumber(int index)
Definition: farm.h:521
CfgFloat cfg_ClosestFarmProbParam1("CLOSESTFARMPROBPARAMONE", CFG_CUSTOM, 0.005)
A fitting parameter for the probability of hunter acceptance of a farm wiht distance from home - slop...
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1358
Livestock(TTypesOfAnimals a_animalType, int a_number)
Constructor.
Definition: farm.cpp:4617
UserDefinedFarm2(FarmManager *a_manager)
Definition: farm.cpp:1800
OptimisingPigFarm(FarmManager *a_myfarmmanager, int a_No)
Definition: farm.cpp:4803
TTypesOfSoils Get_soilType(void)
Definition: farm.h:1892
OptimisingOtherFarm(FarmManager *a_myfarmmanager, int a_No)
Definition: farm.cpp:4814
virtual void createCropsLists(int a_foobar)
Creates lists of crops.
Definition: farm.cpp:5093
double m_grooming
Value of mechanical weed control for a crop - grooming [DKK/ha].
Definition: farm.h:1530
CfgFloat cfg_Env_fert_multiplier("ENV_FERT_MULTIPLIER", CFG_CUSTOM, 0.8)
A parameter of the environmentalist farmer type: reduces environmentalist&#39;s use of fertiliser...
double Get_Nnorm(int i)
Definition: farm.h:547
void ReadRotation(std::string fname)
Reads a rotation file into the rotation.
Definition: farm.cpp:618
Crop()
Definition: farm.cpp:248
Inbuilt special purpose farm type.
Definition: farm.h:1029
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1279
double m_GM
Value of gross margin for a crop (m_income_ha - m_costs_ha) [DKK/ha].
Definition: farm.h:1546
double m_totalLoss
Summary value of the yield loss due to the limited use of herbicides and fung- and insecticides [%]...
Definition: farm.h:1540
CfgFloat cfg_Price_Oats("PRICE_OATS", CFG_CUSTOM, 75)
double m_exp_aggregated_yield
Expected aggregated yield at a farm in a given year.
Definition: farm.h:1991
void determineAreas_ha(vector< CropOptimised * >crops)
Determines areas of crops in ha.
Definition: farm.cpp:7490
double Get_sellingPrice(int i)
Definition: farm.h:564
int GetFarmNumber(void)
Definition: farm.h:698
Definition: farm.h:263
int GetFarmCentroidY()
Definition: farm.h:1913
const char * value(void)
Definition: configurator.h:139
UserDefinedFarm16(FarmManager *a_manager)
Definition: farm.cpp:1906
void ReadCropsData_perFarmType()
Reads the data on crops&#39; parameters that vary with a farm type (fixed, fodder, FUKey) and saves them ...
Definition: farm.cpp:3404
double m_totalArea_original
Total area of a farm as in bedriftsmodel, i.e. original farm optimization model. [ha].
Definition: farm.h:2083
int InvIntPartition(vector< tpct > *items, int target)
Finds all possible sums of the integers in the items array.
Definition: farm.cpp:2045
CfgFloat cfg_PriceChangeThreshold("PRICE_CHANGE_THRESHOLD", CFG_CUSTOM, 0.2)
This parameter specifies the relative difference in energy maize price which causes a farmer to delib...
void BumpRunNum(void)
Definition: elements.h:118
virtual TTypesOfVegetation GetVegType(void)
Definition: elements.h:125
class LE_TypeClass * g_letype
Definition: elements.cpp:265
int m_soilSubType
Farm&#39;s soil subtype. Defined only for cattle farms on sandy soil (0-bad, 1-good, 2-undefined).
Definition: farm.h:2075
Definition: farm.h:349
TTypesOfParameters TranslateParametersCodes(string &str)
Definition: farm.cpp:3910
NoPesticideNoPFarm(FarmManager *a_manager)
Definition: farm.cpp:1765
CfgFloat cfg_Min_fodder_prod_pig("MIN_FODDER_PROD_PIG", CFG_CUSTOM, 20)
A parameter setting the minimum proportion of fodder demand that has to be supplied from own fodder p...
Inbuilt special purpose farm type.
Definition: farm.h:1089
virtual void findFodderDemand()
Determines farm&#39;s total demand for fodder (m_totalFUdemand).
Definition: farm.cpp:5216
double m_nt
Amount of purchased (and applied) fertilizer per ha of a crop [kg N/ha].
Definition: farm.h:1515
virtual void preventCashCrops()
Prevents small cattle farms from growing cash crops and maize silage.
Definition: farm.cpp:5227
The Farm Manager class.
Definition: farm.h:1563
bool Get_fodder(int i)
Definition: farm.h:559
double Get_livestockParameter(int i)
Definition: farm.h:534
void Set_Neighbour(OptimisingFarm *farm)
Definition: farm.h:1905
Inbuilt special purpose farm type.
Definition: farm.h:1098
double m_totalCosts
Planned total costs of growing crops at a farm. [DKK].
Definition: farm.h:2117
virtual void determineAreas(int a_foobar)
Determines areas of variable crops.
Definition: farm.cpp:5827
TTypesOfOptFarms md_farmType
Definition: farm.h:594
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1216
int m_farm_centroidy
Farm&#39;s centroid, value y. Equal to the average of the y centroid values of all farm&#39;s fields...
Definition: farm.h:863
CropActualValues Get_CropDataStorage(int index)
Definition: elements.h:592
LE * m_field
Definition: farm.h:400
void Create_Output_file_for_farms()
Creates an output file. Prints the crop variables in the first row of the file. The file is used then...
Definition: farm.cpp:4132
class MapErrorMsg * g_msg
Definition: maperrormsg.cpp:38
TTypesOfFarm m_farmtype
Definition: farm.h:842
boost::random::uniform_real_distribution< double > distribution_type3
UserDefinedFarm6(FarmManager *a_manager)
Definition: farm.cpp:1832
Inbuilt special purpose farm type.
Definition: farm.h:1107
int ConnectFarm(int a_owner)
Definition: farm.cpp:2303
Class for storing data for optimisation.
Definition: farm.h:505
void ReadCropsData()
Reads the data on crops&#39; parameters that do not vary with farm variables and saves them in a vector D...
Definition: farm.cpp:3179
void Set_area_in_crop_data(double a_area)
Definition: elements.h:570
vector< CropOptimised * > m_grownVariableCrops
Vector of pointers to variable crops that are grown on area larger than areaMin (after determineAreas...
Definition: farm.h:2049
NonAnimalFarm(FarmManager *a_myfarmmanager, int a_No)
Definition: farm.cpp:4799
void FindNeighbours()
Finds all OptimisingFarms&#39; neighbours and saves them in the farm&#39;s OptimisingFarm::m_neighbours vecto...
Definition: farm.cpp:4180
CfgInt g_farm_fixed_crop_type("FARM_FIXED_CROP_TYPE", CFG_CUSTOM, 22)
int m_farm_centroidx
Farm&#39;s centroid, value x. Equal to the average of the x centroid values of all farm&#39;s fields...
Definition: farm.h:861
UserDefinedFarm9(FarmManager *a_manager)
Definition: farm.cpp:1856
int FindFarmWithRandom(vector< int > *a_farmlist)
Finds a farm openness more than a value not on the list.
Definition: farm.cpp:2876
The base class for all farm types.
Definition: farm.h:683
int SupplyYearNumber(void)
Definition: landscape.h:1542
double Get_rotationMax(int i)
Definition: farm.h:569
CfgBool cfg_OptimiseBedriftsmodelCrops("OPTIMISE_BEDRIFTSMODEL_CROPS", CFG_CUSTOM, false)
If set to true, the original farm optimisation model&#39;s crop set is used in the farmer decision making...
virtual void checkWinterRotation1()
Checks if the restriction on a winter rotation is fulfilled.
Definition: farm.cpp:5992
virtual void checkRestrictions()
Checks if the restrictions are fulfilled and corrects crops&#39; areas if necessary.
Definition: farm.cpp:5933
static CfgStr l_map_farmref_file("MAP_FARMREF_FILE", CFG_CUSTOM,"farmrefs.txt")
UserDefinedFarm14(FarmManager *a_manager)
Definition: farm.cpp:1892
void OptimisationOutput()
Creates output files for all crop level variables and for landscape level crop distribution. Includes results of the initial farm otpimisation.
Definition: farm.cpp:3974
bool value(void)
Definition: configurator.h:123
void ReadCropsData_perFarm_and_Soil_and_Size_almass()
Reads the data on crops&#39; parameters that vary with a farm type, soil type and farm size (rotationMax...
Definition: farm.cpp:3640
void Init(ofstream *ap_output_file)
Function carrying out the initial calculations at a farm level (including the initial optimisation)...
Definition: farm.cpp:4817
UserDefinedFarm22(const char *fname, FarmManager *a_manager)
Definition: farm.cpp:2102
int FindOpennessFarm(int a_openness)
Finds a random farm with at least one field with openness above a_openness.
Definition: farm.cpp:2910
virtual bool Spraying_fungins(TTypesOfVegetation a_tov_type)
Returns true if a farmer decided to treat a given crop with fung- and insecticides.
Definition: farm.cpp:4883
void findGrossMargin(CropOptimised *a_crop, int a_foobar, double benefit)
Determines the gross margin (CropOptimised::m_GM) for a given crop at a farm.
Definition: farm.cpp:5748
void ChooseDecisionMode()
Function determines which decision mode to use. The choice depends on the values of need satisfaction...
Definition: farm.cpp:5001
TTypesOfOptFarms Get_farmType(int a_almass_no)
Used by FarmManager::CreateFarms. Finds a matching almass number and returns farm&#39;s type...
Definition: farm.cpp:4609
Definition: farm.h:260
vector< AlmassCrop > m_rotational_crops
Vector of structs with almass type crops with positive areas in % (result of optimisation): includes ...
Definition: farm.h:2059
void PrintNeighbours()
Creates an output file with a list of neighbours of each OptimisingFarm.
Definition: farm.cpp:4224
void ReadCropsData_perSoilType()
Reads the data on crops&#39; parameters that vary with a soil type (alfa, beta1, beta2, Nnorm) and saves them in vectors of the DataForOptimisation class.
Definition: farm.cpp:3247
OptimisingPlantFarm(FarmManager *a_myfarmmanager, int a_No)
Definition: farm.cpp:4810
int m_farmRealID
Farm&#39;s real ID number.
Definition: farm.h:2073
double Get_cropParameter(int i)
Definition: farm.h:538
void fixBI()
Sets values of Treatment frequency indices (BI) for crops with fixed amount of pesticides (CropOptimi...
Definition: farm.cpp:5646
CfgFloat cfg_AnimalsThreshold("ANIMALS_THRESHOLD", CFG_CUSTOM, 0)
This parameter specifies the proportion of average number of animals on a farm for previous 3 years...
bool cash_crops_allowed
Sets to true if cash crops are allowed. True by default.
Definition: farm.h:2254
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1398
int DayInYear(void)
Definition: calendar.h:58
void ReadEnergyMaizePrice()
Definition: farm.cpp:3767
CfgFloat cfg_Min_need_satisfaction1("MIN_NEED_SATISFACTION_ONE", CFG_CUSTOM, 100)
A parameter setting the minimum satisfaction level for profit.
virtual void checkRestrictions()
Checks if the restrictions are fulfilled and corrects crops&#39; areas if necessary.
Definition: farm.cpp:5965
Definition: farm.h:254
double m_totalBIFi
Total amount of fung- and insecticides which is planned to be applied at a farm. Expressed as a Treat...
Definition: farm.h:2107
vector< double > m_previous_profits
Vector of profits from previous years.
Definition: farm.h:1994
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1017
static CfgStr l_emaize_price_file("EMAIZE_PRICE_FILE", CFG_CUSTOM,"EM_price.txt")
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:992
Subclass of the AnimalFarm.
Definition: farm.h:2290
Struct used for sorting crops.
Definition: farm.h:2018
CropOptimised * Get_crop(int i)
Definition: farm.h:1897
CfgFloat cfg_Price_SRape("PRICE_SRAPE", CFG_CUSTOM, 163)
vector< Livestock * > m_livestock
Vector of pointers to animals belonging to a farm.
Definition: farm.h:2038
double m_area_ha
Area of a crop in ha at a farm [ha].
Definition: farm.h:1556
double m_totalProfit
Planned total profit (= income - costs) at a farm. In case of animal farms costs of purchased fodder ...
Definition: farm.h:2121
double GetSpilledGrain()
Returns the average amount of spilled grain in KJ/m2 this year.
Definition: farm.cpp:2584
double m_actual_income
An actual income at a farm in a given year.
Definition: farm.h:1979
Landscape * g_landscape_p
Definition: Landscape.cpp:238
CropOptimised * m_fakeCrop
Crop used to fill up area of a farm up to 100% in case its non-fodder crops do not sum to 100% in det...
Definition: farm.h:2235
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1408
void ReadLookupTable()
Reads the lookup table with allowed/forbidden crop order from a text file and saves it into a vector ...
Definition: farm.cpp:4148
bool m_stockfarmer
Definition: farm.h:845
UserDefinedFarm32(const char *fname, FarmManager *a_manager)
Definition: farm.cpp:2152
int pct
Definition: farm.h:384
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1180
A struct to hold the information required to trigger a farm event.
Definition: farm.h:391
int FindClosestFarmOpennessProbNearRoostIsBest(HunterInfo a_hinfo, vector< int > *a_farmlist, int a_openness, vector< APoint > *a_farmsizelist)
Finds the closest farm to this co-ordinate with openness more than a value but uses a probability dis...
Definition: farm.cpp:2812
TTypesOfCrops Get_cropTypes(int i)
Definition: farm.h:516
double m_exp_costs
Expected costs at a farm in a given year.
Definition: farm.h:1985
PesticideTrialTreatment(FarmManager *a_manager)
Definition: farm.cpp:1647
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1328
Inbuilt special purpose farm type.
Definition: farm.h:1039
CfgInt cfg_LifeStage("LIFE_STAGE", CFG_CUSTOM, 0)
This parameter specifies the life stage of a species whose numbers farmers use during their decision ...
UserDefinedFarm8(FarmManager *a_manager)
Definition: farm.cpp:1848
void Switch_rotation()
Switches OptimisingFarms Farm::m_rotation to the list of all possible rotational crops.
Definition: farm.cpp:4465
void CreateFarms(const char *a_farmfile)
Definition: farm.cpp:2323
TTypesOfVegetation m_cropType_almass
Type/name of a crop (ALMaSS crops).
Definition: farm.h:1503
double Get_beta2(int i)
Definition: farm.h:545
vector< double > m_previous_costs
Vector of costs from previous years.
Definition: farm.h:1998
virtual void checkWinterCrops()
Checks if the restriction on a max. share of winter crops is fulfilled.
Definition: farm.cpp:6359
A class for storing all parameters and results of crop optimisation.
Definition: farm.h:1491
FarmManager * g_farmmanager
Definition: farm.cpp:238
int Get_NeighboursSize(void)
Definition: farm.h:1906
void Match_crop_to_field(LE *a_field)
Finds a crop to be grown on a given field next year.
Definition: farm.cpp:8684
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1348
int GetMaxOpenness()
Returns the maximum openness score of the fields.
Definition: farm.h:718
ConventionalPlant(FarmManager *a_manager)
Definition: farm.cpp:1591
void Set_CropDataStorage(int index, CropActualValues a_struct)
Definition: elements.h:591
TTypesOfVegetation Tov
Definition: farm.h:2032
virtual TTypesOfLandscapeElement GetElementType(void)
Definition: elements.h:113
OptimisingFarm(FarmManager *a_myfarmmanager, int a_No)
The constructor.
Definition: farm.cpp:4676
int FindFarmWithOpenness(vector< int > *a_farmlist, int a_openness)
Finds a farm openness more than a value not on the list.
Definition: farm.cpp:2893
OrganicPlant(FarmManager *a_manager)
Definition: farm.cpp:1624
void optimizeCrops(int a_foobar)
Carries out crop optimisation at a farm.
Definition: farm.cpp:5319
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1270
CfgFloat cfg_Env_pest_multiplier("ENV_PEST_MULTIPLIER", CFG_CUSTOM, 1.25)
A parameter of the environmentalist farmer type: increases the chance that environmentalist does not ...
double m_assigned
Variable holding a value of area already reserved for certain crops at a farm. [0-100%].
Definition: farm.h:2099
void ReadInitialCropAreas_almass()
Reads the data on farms&#39; initial crop distributions and saves them in a vector of a DataForOptimisati...
Definition: farm.cpp:3135
CfgFloat cfg_Neighbor_dist("NEIGHBOR_DIST", CFG_CUSTOM, 1.5)
A parameter setting the maximum distance from a farm to another farm that can be considred a neighbou...
void findResponse(CropOptimised *a_crop, int a_foobar)
Determines the response (CropOptimised::m_resp) of a crop at a farm.
Definition: farm.cpp:5554
double m_certainty_level
Farmer&#39;s certainty level.
Definition: farm.h:1969
virtual void increaseCrops(vector< CropSort >cropsToIncrease, double &howMuchToIncrease)
Increases area of crops by a specified number.
Definition: farm.cpp:7377
int FindClosestFarm(HunterInfo a_hinfo, vector< int > *a_farmlist)
Finds the closest farm to this co-ordinate.
Definition: farm.cpp:2649
long GetMgtLoopDetectDate(void)
Definition: elements.h:119
TTypesOfVegetation TranslateCropCodes(std::string &str)
Definition: farm.cpp:1435
FarmManager * m_OurManager
Pointer to the FarmManager.
Definition: farm.h:837
void findYieldLoss(CropOptimised *a_crop)
Determines the yield losses (CropOptimised::m_lossHerb, CropOptimised::m_lossFi, CropOptimised::m_tot...
Definition: farm.cpp:5723
TTypesOfVegetation TranslateVegTypes(int VegReference)
Definition: elements.cpp:2692
AnimalFarm(FarmManager *a_myfarmmanager, int a_No)
Definition: farm.cpp:4793
CfgFloat cfg_Price_Triticale("PRICE_TRITICALE", CFG_CUSTOM, 80)
void Initialize(FarmManager *a_pfm)
Assigns to each farm its farm type, farm size, farm&#39;s real ID number, and soil type. It creates livestock and crops.
Definition: farm.cpp:4710
String configurator entry class.
Definition: configurator.h:132
vector< PermCropData > m_PermCrops
Definition: farm.h:841
Bool configurator entry class.
Definition: configurator.h:116
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1207
double Get_biomass_factor(int i)
Definition: farm.h:576
TTypesOfAnimals
Definition: farm.h:245
int GetRotIndex(void)
Definition: elements.h:303
TTypesOfCrops
Definition: farm.h:269
virtual bool Do(Farm *a_farm, LE *a_field, FarmEvent *a_ev)
Definition: farm.cpp:253
AgroChemIndustryCerealFarm3(FarmManager *a_manager)
Definition: farm.cpp:1702
double m_n
Total amount of fertilizer applied per ha of a crop [kg N/ha].
Definition: farm.h:1513
void Save_last_years_crops()
It saves the OptimisingFarm::m_rotational_crops in a vector m_rotational_crops_visible which is acces...
Definition: farm.cpp:4995
CfgFloat cfg_Profit_max_proportion("PROFIT_MAX_PROPORTION", CFG_CUSTOM, 100)
A parameter setting the proportion of farmers of a type profit maximiser.
CfgFloat cfg_RoostDistProbParam1("ROOSTDISTPROBPARAMONE", CFG_CUSTOM, 1.5)
A fitting parameter for the probability of hunter acceptance of a farm with distance from roost...
DataForOptimisation * pm_data
Pointer to the DataForOptimisation.
Definition: farm.h:1733
Struct used only in Bedriftsmodel crop type mode for creating m_rotation vector. Bool member used for...
Definition: farm.h:2030
int m_tried_to_do
Definition: elements.h:85
void AddNewEvent(TTypesOfVegetation a_event, long a_date, LE *a_field, int a_todo, long a_num, bool a_lock, int a_start, bool a_first_year, TTypesOfVegetation a_crop)
Adds an event to the event queue for a farm.
Definition: farm.cpp:599
void Set_cropTotals_plant_sum(int i, double crop_area)
Definition: farm.h:1715
Definition: farm.h:360
int SupplyDayInYear(void)
Definition: landscape.h:1522
vector< unsigned > polylist
Definition: farm.h:162
int Get_livestockNumbersSize()
Definition: farm.h:522
int GetArea(void)
Returns the area of arable fields owned by that farm.
Definition: farm.cpp:1045
void Save_last_years_crops_for_farms()
Calls OptimisingFarm::Save_last_years_crops for all optimising farms.
Definition: farm.cpp:2979
bool Get_taken(int index)
Definition: elements.h:567
class Calendar * g_date
Definition: calendar.cpp:38
vector< AlmassCrop > Get_rotational_crops_visible()
Definition: farm.h:1909
void ReadFarmsData_perFarmType()
Reads the data on farms&#39; parameters that vary with a farm type and saves them in a vector of a DataFo...
Definition: farm.cpp:3707
double m_savings
Value of savings resulting from growing a fodder crop and not purchasing amount of fodder correspondi...
Definition: farm.h:1548
Used for storing permanent crop data for the farm rotation.
Definition: farm.h:376
TTypesOfCrops TranslateCropsCodes(string &str)
Definition: farm.cpp:3861
ELEMTYPE m_element
Definition: lowqueue.h:88
void Set_cropTotals_other_sum(int i, double crop_area)
Definition: farm.h:1718
int FindClosestFarmOpennessProb(HunterInfo a_hinfo, vector< int > *a_farmlist, int a_openness)
Finds the closest farm to this co-ordinate with openness more than a value but uses a probability dis...
Definition: farm.cpp:2705
vector< OptimisingFarm * > m_neighbours
Vector of pointers to the farms considered neighbours (fulfilling the neighbourship condition) of a g...
Definition: farm.h:1965
double m_area_scaling_factor
Factor used to scale areas of fixed crops and livestock numbers. Used to adjust these values to the f...
Definition: farm.h:2085
void SetMgtLoopDetectCount(long a_num)
Definition: elements.h:122
UserDefinedFarm12(FarmManager *a_manager)
Definition: farm.cpp:1878
double m_totalGrooming
Total grooming planned at a farm.
Definition: farm.h:2111
double m_optimalN
Optimal amount of fertilizer per ha of a crop supposing ferilizer price equals zero [kg N/ha]...
Definition: farm.h:1517
void findMWeedControl(CropOptimised *a_crop)
Determines the optimal mechanical weed control means (CropOptimised::m_grooming, CropOptimised::m_hoe...
Definition: farm.cpp:5676
double m_GM_Savings
Holds the value of m_GM in case of non-fodder crops and a value of m_savings in case of fodder crops ...
Definition: farm.h:1550
double Get_actual_aggregated_yield()
Definition: farm.h:1911
double GetSpilledMaize()
Returns the average amount of spilled maize in KJ/m2 this year.
Definition: farm.cpp:2601
void findNanim()
Determines amount of animal fertilizer per ha (m_Nanim) at a farm.
Definition: farm.cpp:5188
TTypesOfVegetation Get_cropTypes_almass(int i)
Definition: farm.h:579
UserDefinedFarm4(FarmManager *a_manager)
Definition: farm.cpp:1816
TTypesOfCropVariables
Definition: farm.h:345
Subclass of the OptimisingFarm. Either plant or other farm.
Definition: farm.h:2332
bool CompPcts(tpct i, tpct j)
Used for sorting a farmers field size vector.
Definition: farm.cpp:245
static CfgBool l_map_read_farmfile("MAP_READ_FARMFILE", CFG_PRIVATE, true)
void findTotalNanim()
Determines total animal fertilizer (m_totalNanim) available at a farm.
Definition: farm.cpp:5166
double m_totalNt
Total amount of fertilizer purchased at a farm. [kg].
Definition: farm.h:2103
UserDefinedFarm7(FarmManager *a_manager)
Definition: farm.cpp:1840
void Set_taken(bool a_taken, int index)
Definition: elements.h:566
void createFodderCrops(int a_foobar)
Creates a list of pointers to all fodder crops.
Definition: farm.cpp:5119
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1388
virtual void decreaseCrops(vector< CropSort >cropsToDecrease, double &howMuchToDecrease)
Decreases area of a crops by a specified number.
Definition: farm.cpp:7435
void Set_crops_fertilizer(int i, double fert)
Definition: farm.h:1720
void ResetTrace(void)
Definition: elements.cpp:463
CfgFloat cfg_Price_WBarley("PRICE_WBARLEY", CFG_CUSTOM, 93)
UserDefinedFarm23(const char *fname, FarmManager *a_manager)
Definition: farm.cpp:2107
void Assign_rotation(vector< TTypesOfVegetation >a_new_rotation)
Definition: farm.cpp:1201
void ActualProfit()
Function that determines actual crop yields and profit in a given year.
Definition: farm.cpp:8329
void RemoveField(LE *a_field)
Removes a field from a farm.
Definition: farm.cpp:1186
double m_totalIncome
Planned total income from growing crops at a farm. [DKK].
Definition: farm.h:2119
virtual void HandleEvents(void)
If there are events to carry out do this, and perhaps start a new crop.
Definition: farm.cpp:684
bool force_deliberation
If set to true, a farm must use deliberation as a decision strategy.
Definition: farm.h:2009
virtual void checkWinterCrops()
Animal farm version of the checkWinterCrops() function (accounts for fodder changes).
Definition: farm.cpp:6455
void checkCattleRotation()
Checks if the cattle restriction is fulfilled - in the Bedriftsmodel (original farm optimization mode...
Definition: farm.cpp:6576
void PrintDecModes_counts()
For each OptimizingFarm it prints the number of times each of the decision modes was used within a si...
Definition: farm.cpp:4243
double m_lossHerb
Value of the yield loss due to the limited use of herbicides [%].
Definition: farm.h:1536
Definition: farm.h:275
void OptimiseFarm(int a_foobar)
Carries out the whole farm optimisation.
Definition: farm.cpp:5288
void CropDistribution()
Calculates total crop areas (at the landscape level). Includes results of the initial farm otpimisati...
Definition: farm.cpp:4111
double m_totalHoeing
Total hoeing planned at a farm.
Definition: farm.h:2113
TTypesOfAnimals TranslateAnimalsCodes(string &str)
Definition: farm.cpp:3832
vector< double > m_animals_numbers
Vector for storing numbers of animals at a farm in previous years (3).
Definition: farm.h:2007
void findTotalArea()
Determines m_totalArea of a farm.
Definition: farm.cpp:5147
Definition: farm.h:257
double m_hoeing
Value of mechanical weed control for a crop - hoeing [DKK/ha].
Definition: farm.h:1532
void createVariableCrops(int a_foobar)
Creates a list of pointers to all variable crops included in the optimisation and a list of pointers ...
Definition: farm.cpp:5102
double GetDD(void)
Returnes day degrees for the period March 1st - November 1st. Used for determining yields of crops th...
Definition: farm.h:1692
UserDefinedFarm25(const char *fname, FarmManager *a_manager)
Definition: farm.cpp:2117
UserDefinedFarm15(FarmManager *a_manager)
Definition: farm.cpp:1899
OptimisingFarm * m_previously_imitated_neighbour
The neighbouring farmer whose crops might be copied in imitation and social comparison decision modes...
Definition: farm.h:2004
CfgFloat cfg_Price_Nt("PRICE_NT", CFG_CUSTOM, 1.93)
Price of fertilizer. [DKK/kg].
void ReadCropsData_perFarm_and_Soil()
Reads the data on crops&#39; parameters that vary with a farm and soil type (sellingPrice) and saves them...
Definition: farm.cpp:3526
CfgFloat cfg_Min_fodder_prod_cattle("MIN_FODDER_PROD_CATTLE", CFG_CUSTOM, 35)
A parameter setting the minimum proportion of fodder demand that has to be supplied from own fodder p...
void Set_cropTotals_sum(int i, double crop_area)
Definition: farm.h:1714
int value(void)
Definition: configurator.h:92
UserDefinedFarm35(const char *fname, FarmManager *a_manager)
Definition: farm.cpp:2167
CfgBool g_farm_fixed_rotation_enable("FARM_FIXED_ROTATION_ENABLE", CFG_CUSTOM, false)
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1171
double m_BI
Summary value of BI for herbicides and fung- and insecticides [BI/ha].
Definition: farm.h:1528
CfgInt g_farm_fixed_rotation_farmtype("FARM_FIXED_ROTATION_FARMTYPE", CFG_CUSTOM, 0)
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1318
Inbuilt farm type.
Definition: farm.h:979
virtual void createCropsLists(int a_foobar)
Creates lists of crops.
Definition: farm.cpp:5097
Definition: farm.h:228
void Warn(MapErrorState a_level, std::string a_msg1, std::string a_msg2)
Definition: maperrormsg.cpp:56
int Get_cropAreasSize()
Definition: farm.h:524
void ReadCropsData_perFarm_and_Soil_and_Size()
Reads the data on crops&#39; parameters that vary with a farm type, soil type and farm size (rotationMax...
Definition: farm.cpp:3597
void check_WRape_WBarley()
Checks if the restriction on winter rape and winter barley attachment is fulfilled and corrects crops...
Definition: farm.cpp:6903
Definition: farm.h:271
double biomass_at_harvest
Definition: elements.h:477
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1338
void SetVegStore(int a_veg)
Definition: elements.h:127
void SetMgtLoopDetectDate(long a_num)
Definition: elements.h:120
Used for storing farmers field size vectors.
Definition: farm.h:382
double m_exp_profit
An expected farm&#39;s profit for a given year.
Definition: farm.h:1977
void AddToIllegalList(int a_farm_ref, vector< int > *a_farmlist)
Add to a list if a farm is not already among the illegal list of references.
Definition: farm.cpp:2622
void ReadCropsData_perFarm_and_Soil_almass()
Reads the data on crops&#39; parameters that vary with a farm and soil type (sellingPrice) and saves them...
Definition: farm.cpp:3559
double GetAreaDouble(void)
Returns the area of arable fields owned by that farm.
Definition: farm.cpp:1064
virtual void Management(void)
Starts the main management loop for the farm and performs some error checking.
Definition: farm.cpp:306
TTypesOfSoils TranslateSoilCodes(string &str)
Definition: farm.cpp:3809
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1261
UserDefinedFarm21(const char *fname, FarmManager *a_manager)
Definition: farm.cpp:2097
OrganicCattle(FarmManager *a_manager)
Definition: farm.cpp:1610
vector< double > m_previous_aggregated_yields
Vector of aggregated yields from previous years.
Definition: farm.h:2000
double GetArea(void)
Definition: elements.h:196
TTypesOfLandscapeElement
void ReadCropsData_perSoilType_almass()
Reads the data on crops&#39; parameters that vary with a soil type (alfa, beta1, beta2, Nnorm) and saves them in vectors of the DataForOptimisation class. ALMaSS crop mode.
Definition: farm.cpp:3313
bool Get_fixed(int i)
Definition: farm.h:554
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1124
long m_pri
Definition: lowqueue.h:89
int Get_cropTypes_almass_size()
Definition: farm.h:580
vector< FarmData * > m_farm_data
Definition: farm.h:601
int GetAreaOpenFields(int a_openness)
Returns the area of the fields above an openness of a_openness.
Definition: farm.cpp:1083
virtual void determineAreas(int a_foobar)
Determines areas of variable crops.
Definition: farm.cpp:5896
CfgFloat cfg_Price_WRape("PRICE_WRAPE", CFG_CUSTOM, 163)
void Add_to_cropTotals(int i, double value)
Definition: farm.h:1695
int animals_no
Holds the number of animals in a farm at a particular day in a year (depends on a species)...
Definition: farm.h:2011
void Translate_crops_to_almass()
Translates crops from Bedriftsmodel (original farm optimization model) to Almass crops. Used in Bedriftsmodel crop mode.
Definition: farm.cpp:7598
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1198
double m_need_satisfaction_level
Farmer&#39;s actual satisfaction level.
Definition: farm.h:1967
virtual ~Farm(void)
Farm destructor - deletes all crop instances and empties event queues.
Definition: farm.cpp:958
int index
Definition: farm.h:383
double m_rotationMax
Maximum area in percent of farm&#39;s arable area for a given crop (depends on a farm size...
Definition: farm.h:1507
int homeX
Hunter home x-coord.
Definition: farm.h:444
int m_todo
Definition: farm.h:397
double m_BIHerb
Value of BI for herbicides [BI/ha].
Definition: farm.h:1524
UserDefinedFarm29(const char *fname, FarmManager *a_manager)
Definition: farm.cpp:2137
TTypesOfCrops m_cropType
Type/name of a crop (original farm optimization model crop types).
Definition: farm.h:1501
void sortCrops(vector< CropSort > &cropsToSort, string sortingKey)
Sorts structs of type CropSort.
Definition: farm.cpp:7311
UserDefinedFarm27(const char *fname, FarmManager *a_manager)
Definition: farm.cpp:2127
Farm(FarmManager *a_manager)
Farm constructor - creates an instance of each possible crop type.
Definition: farm.cpp:862
TTypesOfSoils
Definition: farm.h:232
int m_almass_no
Farm&#39;s almass number.
Definition: farm.h:2077
Subclass of the AnimalFarm.
Definition: farm.h:2305
double m_weeding
Value of mechanical weed control for a crop - manual weeding [DKK/ha].
Definition: farm.h:1534
long GetRunNum(void)
Definition: elements.h:117
Double configurator entry class.
Definition: configurator.h:100
void Set_cropTotals_pig_sum(int i, double crop_area)
Definition: farm.h:1716
double m_totalFUdemand
Farm&#39;s total demand for fodder (it is covered by growing fodder crops and/or purchasing fodder and th...
Definition: farm.h:2093
TTypesOfVegetation Get_crops_summary_BIs_tov(int i)
Definition: farm.h:1710
int Get_noCrops()
Definition: farm.h:585
void Set_crops_summary_BIs_herb(int i, double BIherb)
Definition: farm.h:1711
Definition: farm.h:304
AgroChemIndustryCerealFarm1(FarmManager *a_manager)
Definition: farm.cpp:1669
double Get_beta1(int i)
Definition: farm.h:543
polylist * ListOpenFields(int a_openness)
Returns a list of fields with openness above a_openness.
Definition: farm.cpp:8922
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1378
Struct for storing actual data on crop type, area of a field it is grown in, biomass at harvest...
Definition: elements.h:474
TTypesOfSoils md_soilType
Definition: farm.h:595
ConventionalPig(FarmManager *a_manager)
Definition: farm.cpp:1572
ConvMarginalJord(FarmManager *a_manager)
Definition: farm.cpp:1655
PesticideTrialToxicControl(FarmManager *a_manager)
Definition: farm.cpp:1639
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1298
CfgFloat cfg_Min_need_satisfaction2("MIN_NEED_SATISFACTION_TWO", CFG_CUSTOM, 100)
A parameter setting the minimum satisfaction level for yield.
Definition: farm.h:280
int SupplyFarmAnimalCensus(int a_farm_ref, int a_LifeStage)
Definition: Landscape.cpp:608
PesticideTrialControl(FarmManager *a_manager)
Definition: farm.cpp:1631
TTypesOfCropVariables TranslateCropVariablesCodes(string &str)
Definition: farm.cpp:3949
void Set_cropTotals_cattle_sum(int i, double crop_area)
Definition: farm.h:1717
double Get_rotationMin(int i)
Definition: farm.h:571
CfgBool cfg_Sensitivity_analysis("SENSITIVITY_ANALYSIS", CFG_CUSTOM, false)
virtual void InitiateManagement(void)
Kicks off the farm&#39;s management.
Definition: farm.cpp:4647
void InitializeVector(vector< double > &vector)
Initializes vector with -1 values.
Definition: farm.cpp:4562
double Get_alfa(int i)
Definition: farm.h:541
vector< AlmassCrop > m_rotational_crops_visible
Stores a copy of m_rotational_crops from a previous year and is accessible to farmers who want to cop...
Definition: farm.h:2063
NoPesticideBaseFarm(FarmManager *a_manager)
Definition: farm.cpp:1720
void correctFodderDemand(int a_foobar)
Determines how much fodder is produced from fixed crops and min. areas of variable crops...
Definition: farm.cpp:7011
void ReadCropsData_almass()
Reads the data on crops&#39; parameters that do not vary with farm variables and saves them in a vector D...
Definition: farm.cpp:3211
void AddField(LE *a_newfield)
Adds a field to a farm.
Definition: farm.cpp:1161
TTypesOfVegetation tov_type
Definition: elements.h:476
UserDefinedFarm20(const char *fname, FarmManager *a_manager)
Definition: farm.cpp:2092
double m_totalBI
Total amount of pesticides (sum of m_totalBIHerb and m_totalBIFi) which is planned to be applied at a...
Definition: farm.h:2109
TTypesOfSoils m_soilType
Farm&#39;s soil type (sandy, clay, other).
Definition: farm.h:2069
bool InIllegalList(int a_farm_ref, vector< int > *a_farmlist)
Checks a list to see if a farm matches the illegal list of references.
Definition: farm.cpp:2611
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1162
AgroChemIndustryCerealFarm2(FarmManager *a_manager)
Definition: farm.cpp:1686
int Get_lookup_table(int index)
Definition: farm.h:1736
OptimisingFarm * Get_Neighbour(int i)
Definition: farm.h:1907
A farm that can have its rotation defined by the user at runtime.
Definition: farm.h:1308
void InitiateManagement(void)
Definition: farm.cpp:2284
OptimisingCattleFarm(FarmManager *a_myfarmmanager, int a_No)
Definition: farm.cpp:4807
virtual void checkRestrictions()
Checks if the restrictions are fulfilled and corrects crops&#39; areas if necessary.
Definition: farm.cpp:5980
Used in event handling.
Definition: lowqueue.h:83
UserDefinedFarm17(FarmManager *a_manager)
Definition: farm.cpp:1914
void CheckRotationManagementLoop(FarmEvent *ev)
Definition: farm.cpp:641
int GetFirstDate(TTypesOfVegetation a_tov)
Gets the start date for a crop type.
Definition: farm.cpp:1288
void ChooseNextCrop(int a_no_dates)
Chooses the next crop to grow in a field.
Definition: farm.cpp:263
double m_benefit
A value of selling price for non-fodder crops or a value of fodder units obtained from a hkg of a fod...
Definition: farm.h:1520
TTypesOfLivestockParameters TranslateLivestockParametersCodes(string &str)
Definition: farm.cpp:3937
double m_totalN
Total amount of fertilizer used at a farm. [kg].
Definition: farm.h:2101
void Set_crops_fertilizer_trade(int i, double fert_trade)
Definition: farm.h:1721
void Centroids()
Finds farm&#39;s centroids - x and y.
Definition: farm.cpp:4857
void Clean_CropDataStorage(int index)
Definition: elements.cpp:1751
void ReadCropsData_perFarmType_almass()
Reads the data on crops&#39; parameters that vary with a farm type (fixed, fodder, FUKey) and saves them ...
Definition: farm.cpp:3460