ALMaSS Rabbit ODdox  1.00
The rabbit model description following ODdox protocol
plants.cpp
Go to the documentation of this file.
1 //
2 // plants.cpp
3 //
4 /*
5 *******************************************************************************************************
6 Copyright (c) 2011, Christopher John Topping, Aarhus University
7 All rights reserved.
8 
9 Redistribution and use in source and binary forms, with or without modification, are permitted provided
10 that the following conditions are met:
11 
12 Redistributions of source code must retain the above copyright notice, this list of conditions and the
13 following disclaimer.
14 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
15 the following disclaimer in the documentation and/or other materials provided with the distribution.
16 
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
18 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
20 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 ********************************************************************************************************
26 */
27 
28 #define _CRT_SECURE_NO_DEPRECATE
29 
30 #include <cstdio>
31 #include <math.h>
32 #include <stdlib.h>
33 #include "configurator.h"
34 #include "maperrormsg.h"
35 #include "plants.h"
36 #include "tov_declaration.h"
37 
38 extern void FloatToDouble(double&,float);
40 
41 double CropData::FindDiff( double a_ddegs, double a_yddegs, int a_plant,
42  int a_phase, int a_type )
43 {
44  // Check for valid plant number at runtime?
45  // This is broken for growth curves where one can risk passing
46  // more than a single inflection point in the growth curve in a
47  // single day...
48 
49  int index = m_numbers[ a_plant ];
50  unsigned int oldindex=0, newindex=0;
51 
52  if ( m_growth[ index ]->m_dds[ a_phase ][ 0 ] == 99999 ) {
53  return 0.0;
54  }
55 
56  for ( unsigned int i=0; i<MaxNoInflections; i++ ) {
57  // In other words: If the current value for summed day degrees
58  // is smaller than the X position of the *next* inflection
59  // point, then we are in the correct interval.
60  if ( m_growth[ index ]->m_dds[ a_phase ][ i+1 ] > a_ddegs ) {
61  newindex = i;
62  break;
63  // return m_growth[ index ]->m_slopes[ a_phase ][ a_type ][i];
64  }
65  }
66 
67  for ( unsigned int i=0; i<MaxNoInflections; i++ ) {
68  if ( m_growth[ index ]->m_dds[ a_phase ][ i+1 ] > a_yddegs ) {
69  oldindex = i;
70  break;
71  // return m_growth[ index ]->m_slopes[ a_phase ][ a_type ][i];
72  }
73  }
74 
75  double diff;
76 
77  if ( newindex > oldindex ) {
78  // We have passed an inflection point between today and yesterday.
79  // First add the increment from yesterdays day degree sum up to
80  // the inflection point.
81  double dddif =
82  m_growth[ index ]->m_dds[ a_phase ][ newindex ] - a_yddegs;
83  diff =
84  m_growth[ index ]->m_slopes[ a_phase ][ a_type ][oldindex]*
85  dddif;
86 
87  // Then from the inflection point up to today.
88  dddif = a_ddegs -
89  m_growth[ index ]->m_dds[ a_phase ][ newindex ];
90  diff +=
91  m_growth[ index ]->m_slopes[ a_phase ][ a_type ][ newindex ]*
92  dddif;
93  } else {
94  // No inflection point passed.
95  diff = m_growth[ index ]->m_slopes[ a_phase ][ a_type ][ newindex ] *
96  (a_ddegs - a_yddegs);
97  }
98  return diff;
99 }
100 
101 
102 double CropData::GetLAgreenDiff( double a_ddegs, double a_yddegs,
103  int a_plant, int a_phase )
104 {
105  return FindDiff( a_ddegs, a_yddegs, a_plant, a_phase, 0 );
106 }
107 
108 
109 double CropData::GetLAtotalDiff( double a_ddegs, double a_yddegs,
110  int a_plant, int a_phase )
111 {
112  return FindDiff( a_ddegs, a_yddegs, a_plant, a_phase, 1 );
113 }
114 
115 
116 double CropData::GetHeightDiff( double a_ddegs, double a_yddegs,
117  int a_plant, int a_phase )
118 {
119  return FindDiff( a_ddegs , a_yddegs, a_plant, a_phase, 2 );
120 }
121 
122 
123 
124 unsigned int CropData::FindCropNum( const char* a_cropcurvefile )
125 {
126  int NoPlants;
127 
128  m_numbers.resize(201);
129  for ( unsigned int i=0; i<201; i++) {
130  m_numbers[ i ] = -1;
131  }
132 
133  m_ifile = fopen(a_cropcurvefile, "r" );
134  if (!m_ifile){
135  g_msg->Warn(WARN_FILE, "CropData::CropData: Unable to open file",
136  a_cropcurvefile );
137  exit(1);
138  }
139 
140  fscanf( m_ifile , "%d", &NoPlants ); // How many tables to read in
141  m_growth.resize( NoPlants );
142  m_num_crops = NoPlants;
143 
144  return NoPlants;
145 }
146 
147 
148 
149 void CropData::SetVegNum( unsigned int a_i, const char* a_cropcurvefile )
150 {
151  int ThisPlant;
152 
153  // Find out what crop and what nutrient status
154  fscanf( m_ifile, "%d", &ThisPlant);
155 
156  // Check if valid plant number (from the file).
157  if ( ThisPlant < 0 || ThisPlant > 200 ) {
158  g_msg->Warn(WARN_FILE, "CropData::FindCropNum(): Illegal plant number"
159  " specified in", a_cropcurvefile );
160  exit(1);
161  }
162 
163  m_numbers[ ThisPlant ] = a_i;
164 
165  // if greater than 100 then it is low nutrient
166  if ( ThisPlant > 100 ) {
167  m_growth[ a_i ]->m_lownut = true;
168  } else {
169  m_growth[ a_i ]->m_lownut = false;
170  }
171 }
172 
173 
174 CropData::CropData( const char* a_vegcurvefile )
175 {
176  // Just finds out how many veg curves there are.
177  unsigned int NoPlants = FindCropNum( a_vegcurvefile );
178 
179  for ( unsigned int i=0; i<NoPlants; i++) {
180  CropGrowth* temp;
181  temp = new CropGrowth;
182  m_growth[ i ] = temp;
183  SetVegNum( i, a_vegcurvefile );
184 
185  for (unsigned int j=0; j<5; j++) { // for each growth phase
186  // 'Local' index into crop growth curves.
187  int lk = 0;
188  for (unsigned int k=0; k<MaxNoInflections; k++) {
189  // for each inflection point
190  int entry;
191  fscanf( m_ifile, "%d", &entry );
192  float f1=0,f2=0,f0=0;
193  if ( entry == -1 ) {
194  // Crop start data.
195  m_growth[ i ]->m_start_valid[j] = true;
196  fscanf( m_ifile, "%g %g %g",&f1,&f0,&f2);
197  FloatToDouble(m_growth[ i ]->m_start[j][1],f1);
198  FloatToDouble(m_growth[ i ]->m_start[j][0],f0);
199  FloatToDouble(m_growth[ i ]->m_start[j][2],f2);
200  } else {
201  // Add inflection point to normal growth curves.
202  m_growth[ i ]->m_dds[j][lk] = (double)entry;
203  fscanf( m_ifile, "%g %g %g",&f1,&f0,&f2);
204  FloatToDouble(m_growth[ i ]->m_slopes[j][1][lk],f1);
205  FloatToDouble(m_growth[ i ]->m_slopes[j][0][lk],f0);
206  FloatToDouble(m_growth[ i ]->m_slopes[j][2][lk],f2);
207  lk++;
208  }
209  } // MaxNoInflections
210  } // Growth Phases
211  } // NoPlants
212  fclose( m_ifile );
213 }
214 
216 {
217  for ( unsigned int i=0; i<m_growth.size(); i++ )
218  delete m_growth[i];
219 }
220 
222 {
223  for (unsigned int j=0; j<5; j++) {
224  m_start_valid[j] = false;
225  for ( unsigned int k=0; k<3; k++) {
226  m_start[j][k] = 0.0;
227  }
228  }
229 }
230 
232 {
233  char error_num[20];
234 
235  switch (VegReference)
236  {
238  case tov_OSpringBarley:
240  return 101;
242  case tov_SpringBarley:
243  case tov_SpringBarleySpr:
249  return 1;
250  case tov_WinterBarley:
252  return 2;
253  case tov_OWinterBarley:
255  return 102;
256  case tov_WinterWheat:
262  case tov_WWheatPControl:
265  return 4;
266  case tov_OWinterWheat:
268  return 104;
269  case tov_WinterRye:
271  return 5;
272  case tov_OWinterRye:
273  return 105;
274  case tov_Oats:
275  return 6;
276  case tov_OOats:
277  return 106;
278  case tov_Maize:
279  case tov_MaizeSilage:
280  case tov_MaizeStrigling:
281  return 8;
282  case tov_OMaizeSilage:
283  return 108;
288  return 13;
290  case tov_OSBarleySilage:
293  return 113;
294  case tov_WinterRape:
296  return 22;
297  case tov_OWinterRape:
298  return 22;
301  return 25;
304  return 26;
305  case tov_SeedGrass1:
306  case tov_SeedGrass2:
307  case tov_OSeedGrass1:
308  case tov_OSeedGrass2:
309  return 27;
310  case tov_FodderGrass:
316  case tov_OGrazingPigs:
317  return 29;
318  case tov_OFieldPeas:
320  case tov_FieldPeas:
322  case tov_FieldPeasSilage:
323  case tov_BroadBeans:
324  return 30;
325  case tov_Carrots:
326  return 41;
327  case tov_OCarrots:
328  return 141;
329  case tov_Potatoes: return 50;
330  case tov_OPotatoes: return 150;
331  case tov_PotatoesIndustry: return 50;
332  case tov_SugarBeet:
333  case tov_FodderBeet:
334  case tov_OFodderBeet:
335  return 60;
336  // Special growth mode for green but unused elements.
337  // tov_PermanentSetaside Does not change growth phase no matter
338  // how hard one tries to do just that.
339  case tov_PermanentSetaside: return 92;
340  case tov_Heath:
341  case tov_Setaside:
342  case tov_OSetaside: return 112;
343  case tov_OrchardCrop:
344  case tov_YoungForest:
345  case tov_NaturalGrass:
346  case tov_Wasteland: return 90;
347  case tov_NoGrowth: return 91;
348  case tov_Lawn: return 94;
349  //case tov_SpringWheat: return 3;
350  case tov_OTriticale:
351  case tov_Triticale: return 7;
352  case tov_SpringRape: return 21;
353 
354  default: // No matching code so we need an error message of some kind
355  sprintf( error_num, "%d", VegReference );
356  g_msg->Warn( WARN_FILE,
357  "CropData::VegTypeToCurveNum(): Unknown vegetation type:",
358  error_num );
359  exit( 1 );
360  }
361 }
362 
363 
364 bool CropData::StartValid( int a_veg_type, int a_phase )
365 {
366  int a=m_numbers[ a_veg_type ];
367  CropGrowth* p=m_growth[a];
368  return p-> m_start_valid[ a_phase ];
369 }
FILE * m_ifile
Definition: plants.h:84
int VegTypeToCurveNum(TTypesOfVegetation VegReference)
Definition: plants.cpp:231
double FindDiff(double a_ddegs, double a_yddegs, int a_plant, int a_phase, int a_type)
Definition: plants.cpp:41
double GetLAtotalDiff(double a_ddegs, double a_yddegs, int a_plant, int a_phase)
Definition: plants.cpp:109
class CropData * g_crops
Definition: plants.cpp:39
unsigned int FindCropNum(const char *a_cropcurvefile)
Definition: plants.cpp:124
void FloatToDouble(double &, float)
TTypesOfVegetation
vector< CropGrowth * > m_growth
Definition: plants.h:81
vector< int > m_numbers
Definition: plants.h:82
class MapErrorMsg * g_msg
Definition: maperrormsg.cpp:38
double GetHeightDiff(double a_ddegs, double a_yddegs, int a_plant, int a_phase)
Definition: plants.cpp:116
~CropData()
Definition: plants.cpp:215
bool StartValid(int a_veg_type, int a_phase)
Definition: plants.cpp:364
CropGrowth(void)
Definition: plants.cpp:221
void SetVegNum(unsigned int a_i, const char *a_cropcurvefile)
Definition: plants.cpp:149
void Warn(MapErrorState a_level, std::string a_msg1, std::string a_msg2)
Definition: maperrormsg.cpp:56
const unsigned int MaxNoInflections
Definition: plants.h:39
CropData(const char *a_cropcurvefile)
Definition: plants.cpp:174
double GetLAgreenDiff(double a_ddegs, double a_yddegs, int a_plant, int a_phase)
Definition: plants.cpp:102
int m_num_crops
Definition: plants.h:83