ALMaSS Hare ODDox  1.1
The hare model description following ODdox protocol
OFodderbeet.cpp
Go to the documentation of this file.
1 //
2 // OFodderbeet.cpp
3 //
4 /*
5 *******************************************************************************************************
6 Copyright (c) 2011, Christopher John Topping, University of Aarhus
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 #include "../../Landscape/ls.h"
29 #include "../../Landscape/cropprogs/OFodderbeet.h"
30 
31 bool OFodderbeet::Do(Farm *a_farm, LE *a_field, FarmEvent *a_ev)
32 {
33  m_farm = a_farm;
34  m_field = a_field;
35  m_ev = a_ev;
36  // int d1;
37 
38  bool done = false;
39 
40  switch (m_ev->m_todo)
41  {
42  case ofb_start:
43  {
44  m_field->SetVegPatchy(true); // Root crop so open
45  // Set up the date management stuff
46  // Could save the start day in case it is needed later
47  // m_field->m_startday = m_ev->m_startday;
48  m_last_date = g_date->DayInYear(10, 11);
49  // Start and stop dates for all events after harvest
50  int noDates = 1;
51  m_field->SetMDates(0, 0, g_date->DayInYear(10, 10));
52  // 0,0 determined by harvest date - used to see if at all possible
53  m_field->SetMDates(1, 0, g_date->DayInYear(10, 11));
54  // Check the next crop for early start, unless it is a spring crop
55  // in which case we ASSUME that no checking is necessary!!!!
56  // So DO NOT implement a crop that runs over the year boundary
57 
58  //new if: do the check only for non-optimising farms and if year>0. (030713 - m_rotation used only in the hidden year, so I modified the condition from >7 to >0)
59  int d1;
60  if (!(m_farm->GetType() == tof_OptimisingFarm && g_date->GetYearNumber()>0)){
61 
62  if (m_ev->m_startday>g_date->DayInYear(1, 7))
63  {
64  if (m_field->GetMDates(0, 0) >= m_ev->m_startday)
65  {
66  g_msg->Warn(WARN_BUG, "OFodderBeet::Do(): "
67  "Harvest too late for the next crop to start!!!", "");
68  exit(1);
69  }
70  // Now fix any late finishing problems
71  for (int i = 0; i<noDates; i++) {
72  if (m_field->GetMDates(0, i) >= m_ev->m_startday) {
73  m_field->SetMDates(0, i, m_ev->m_startday - 1); //move the starting date
74  }
75  if (m_field->GetMDates(1, i) >= m_ev->m_startday){
76  m_field->SetMConstants(i, 0);
77  m_field->SetMDates(1, i, m_ev->m_startday - 1); //move the finishing date
78  }
79  }
80  }
81  // Now no operations can be timed after the start of the next crop.
82 
83  // CJT note:
84  // Start single block date checking code to be cut-'n-pasted...
85 
86  if (!m_ev->m_first_year)
87  {
88  // Are we before July 1st?
89  d1 = g_date->OldDays() + g_date->DayInYear(1, 7);
90  if (g_date->Date() < d1)
91  {
92  // Yes, too early. We assumme this is because the last crop was late
93  g_msg->Warn(WARN_BUG, "OFodderBeet::Do(): "
94  "Crop start attempt between 1st Jan & 1st July", "");
95  exit(1);
96  }
97  else
98  {
99  d1 = g_date->OldDays() + m_first_date; // Add 365 for spring crop
100  if (g_date->Date() > d1)
101  {
102  // Yes too late - should not happen - raise an error
103  g_msg->Warn(WARN_BUG, "OFodderBeet::Do(): "
104  "Crop start attempt after last possible start date", "");
105  exit(1);
106  }
107  }
108  }
109  else
110  {
111  // If this is the first year of running then it is possibel to start
112  // on day 0, so need this to tell us what to do:
113  SimpleEvent(g_date->OldDays() + g_date->DayInYear(1, 3),
114  ofb_spring_plough, false);
115  break;
116  }
117  }//if
118 
119  // End single block date checking code. Please see next line
120  // comment as well.
121  // Reinit d1 to first possible starting date.
122  d1 = g_date->OldDays() + g_date->DayInYear(1, 10); // Was 1,10
123  if (g_date->Date() > d1) {
124  d1 = g_date->Date();
125  }
126  // OK, let's go.
127  SimpleEvent(d1, ofb_autumn_plough, false);
128  }
129  break;
130 
131  case ofb_autumn_plough:
132  if (m_ev->m_lock || m_farm->DoIt(40))
133  {
134  if (!m_farm->AutumnPlough(m_field, 0.0,
135  g_date->DayInYear(15, 12) -
136  g_date->DayInYear())) {
137  SimpleEvent(g_date->Date() + 1, ofb_autumn_plough, true);
138  break;
139  }
140  // Did autumn plough, so skip manure and spring plough.
141  SimpleEvent(g_date->OldDays() + g_date->DayInYear(15, 3) + 365,
142  ofb_start_threads_one, false);
143  break;
144  }
145  SimpleEvent(g_date->OldDays() + g_date->DayInYear(15, 3) + 365,
146  ofb_fertmanure, false);
147  break;
148 
149  case ofb_fertmanure:
150  if (m_ev->m_lock || m_farm->DoIt(40))
151  {
152  if (!m_farm->FA_Manure(m_field, 0.0,
153  g_date->DayInYear(9, 4) -
154  g_date->DayInYear())) {
155  SimpleEvent(g_date->Date() + 1, ofb_fertmanure, true);
156  break;
157  }
158  }
159  SimpleEvent(g_date->Date(), ofb_spring_plough, false);
160  break;
161 
162  case ofb_spring_plough:
163  if (m_ev->m_lock || m_farm->DoIt(60))
164  {
165  if (!m_farm->SpringPlough(m_field, 0.0,
166  g_date->DayInYear(10, 4) -
167  g_date->DayInYear())) {
168  SimpleEvent(g_date->Date() + 1, ofb_spring_plough, true);
169  break;
170  }
171  }
172  SimpleEvent(g_date->Date() + 1, ofb_start_threads_one, false);
173  break;
174 
176  // Today is the 15th of March, at the least.
177  OFB_DID_HARROW = false;
178  OFB_DID_NPKS_ONE = false;
179  OFB_DID_SLURRY = false;
180  OFB_SOW_DATE = 0;
181  SimpleEvent(g_date->Date(), ofb_spring_harrow, false);
182  SimpleEvent(g_date->OldDays() + g_date->DayInYear(5, 4),
183  ofb_fertnpks_one, false);
184  SimpleEvent(g_date->OldDays() + g_date->DayInYear(5, 4),
185  ofb_fertslurry, false);
186  break;
187 
188  case ofb_spring_harrow:
189  if (!m_farm->SpringHarrow(m_field, 0.0,
190  g_date->DayInYear(11, 4) -
191  g_date->DayInYear())) {
192  SimpleEvent(g_date->Date() + 1, ofb_spring_harrow, true);
193  break;
194  }
195  OFB_DID_HARROW = true;
197  // We are the last surviving thread.
198  SimpleEvent(g_date->OldDays() + g_date->DayInYear(10, 4),
199  ofb_spring_sow, false);
200  }
201  break;
202 
203  case ofb_fertnpks_one:
204  if (!m_farm->FA_NPK(m_field, 0.0,
205  g_date->DayInYear(5, 5) -
206  g_date->DayInYear())) {
207  SimpleEvent(g_date->Date() + 1, ofb_fertnpks_one, true);
208  break;
209  }
210  OFB_DID_NPKS_ONE = true;
212  // We are the last surviving thread.
213  SimpleEvent(g_date->OldDays() + g_date->DayInYear(10, 4),
214  ofb_spring_sow, false);
215  }
216  break;
217 
218  case ofb_fertslurry:
219  if (!m_farm->FA_Slurry(m_field, 0.0,
220  g_date->DayInYear(5, 5) -
221  g_date->DayInYear())) {
222  SimpleEvent(g_date->Date() + 1, ofb_fertslurry, true);
223  break;
224  }
225  OFB_DID_SLURRY = true;
227  // We are the last surviving thread.
228  SimpleEvent(g_date->OldDays() + g_date->DayInYear(10, 4),
229  ofb_spring_sow, false);
230  }
231  break;
232 
233  case ofb_spring_sow:
234  if (!m_farm->SpringSow(m_field, 0.0,
235  g_date->DayInYear(1, 5) -
236  g_date->DayInYear())) {
237  SimpleEvent(g_date->Date() + 1, ofb_spring_sow, true);
238  break;
239  }
240  OFB_SOW_DATE = g_date->Date();
241  SimpleEvent(g_date->Date(), ofb_spring_roll, false);
242  break;
243 
244  case ofb_spring_roll:
245  if (m_ev->m_lock || m_farm->DoIt(80))
246  {
247  if (!m_farm->SpringRoll(m_field, 0.0,
248  g_date->DayInYear(15, 4) -
249  g_date->DayInYear())) {
250  SimpleEvent(g_date->Date() + 1, ofb_spring_roll, true);
251  break;
252  }
253  }
254  {
255  int d1 = g_date->OldDays() + g_date->DayInYear(20, 4);
256  if (d1 < OFB_SOW_DATE + 14) {
257  d1 = OFB_SOW_DATE;
258  }
260  }
261  break;
262 
263 
265  if (m_ev->m_lock || m_farm->DoIt(100))
266  {
267  if (!m_farm->RowCultivation(m_field, 0.0,
268  g_date->DayInYear(25, 5) -
269  g_date->DayInYear())) {
270  SimpleEvent(g_date->Date() + 1, ofb_row_cultivation_one, true);
271  break;
272  }
273  // Did first row cultivation, queue up the second too.
274  OFB_DID_ROW_TWO = false;
275  {
276  int d1 = g_date->Date() + 14;
277  if (d1 < g_date->OldDays() + g_date->DayInYear(17, 5)) {
278  d1 = g_date->OldDays() + g_date->DayInYear(17, 5);
279  }
281  }
282  }
283  else {
284  // Didn't do row cultivation on this field. Signal already done.
285  OFB_DID_ROW_TWO = true;
286  }
287  OFB_DID_NPKS_TWO = false;
288  OFB_DID_WATER_ONE = false;
289  OFB_TRULY_DID_WATER_ONE = false;
290  SimpleEvent(g_date->OldDays() + g_date->DayInYear(1, 6),
291  ofb_fertnpks_two, false);
292  SimpleEvent(g_date->OldDays() + g_date->DayInYear(1, 7),
293  ofb_water_one, false);
294  break;
295 
297  if (!m_farm->RowCultivation(m_field, 0.0,
298  g_date->DayInYear(15, 6) -
299  g_date->DayInYear())) {
300  SimpleEvent(g_date->Date() + 1, ofb_row_cultivation_two, true);
301  break;
302  }
303  OFB_DID_ROW_TWO = true;
304  if (OFB_DID_NPKS_TWO &&
306  ) {
307  // We are the last surviving thread.
308  SimpleEvent(g_date->OldDays() + g_date->DayInYear(1, 8),
309  ofb_water_two, false);
310  }
311  break;
312 
313  case ofb_fertnpks_two:
314  if (m_ev->m_lock || m_farm->DoIt(40))
315  {
316  if (!m_farm->FA_NPK(m_field, 0.0,
317  g_date->DayInYear(15, 6) -
318  g_date->DayInYear())) {
319  SimpleEvent(g_date->Date() + 1, ofb_fertnpks_two, true);
320  break;
321  }
322  }
323  OFB_DID_NPKS_TWO = true;
324  if (OFB_DID_ROW_TWO &&
326  ) {
327  // We are the last surviving thread.
328  SimpleEvent(g_date->OldDays() + g_date->DayInYear(1, 8),
329  ofb_water_two, false);
330  }
331  break;
332 
333  case ofb_water_one:
334  if (m_ev->m_lock || m_farm->DoIt(25))
335  {
336  if (!m_farm->Water(m_field, 0.0,
337  g_date->DayInYear(30, 7) -
338  g_date->DayInYear())) {
339  SimpleEvent(g_date->Date() + 1, ofb_water_one, true);
340  break;
341  }
343  }
344  OFB_DID_WATER_ONE = true;
345  if (OFB_DID_ROW_TWO &&
347  ) {
348  // We are the last surviving thread.
349  SimpleEvent(g_date->OldDays() + g_date->DayInYear(1, 8),
350  ofb_water_two, false);
351  }
352  break;
353 
354 
355  case ofb_water_two:
357  {
358  if (!m_farm->Water(m_field, 0.0,
359  g_date->DayInYear(30, 8) -
360  g_date->DayInYear())) {
361  SimpleEvent(g_date->Date() + 1, ofb_water_two, true);
362  break;
363  }
364  }
365  ChooseNextCrop(1);
366  SimpleEvent(g_date->OldDays() + g_date->DayInYear(10, 10),
367  ofb_harvest, false);
368  break;
369 
370  case ofb_harvest:
371  if (m_field->GetMConstants(0) == 0) {
372  if (!m_farm->Harvest(m_field, 0.0, -1)) { //raise an error
373  g_msg->Warn(WARN_BUG, "OFodderbeet::Do(): failure in 'Harvest' execution", "");
374  exit(1);
375  }
376  }
377  else {
378  if (!m_farm->Harvest(m_field, 0.0, m_field->GetMDates(1, 0) - g_date->DayInYear())) {
379  SimpleEvent(g_date->Date() + 1, ofb_harvest, true);
380  break;
381  }
382  }
383  m_field->SetVegPatchy(false);
384  done = true;
385  break;
386 
387  default:
388  g_msg->Warn(WARN_BUG, "OFodderbeet::Do(): "
389  "Unknown event type! ", "");
390  exit(1);
391  }
392 
393  return done;
394 }
395 
396 
Farm::SpringRoll
virtual bool SpringRoll(LE *a_field, double a_user, int a_days)
Carry out a roll event in the spring on a_field.
Definition: farmfuncs.cpp:525
Farm::FA_Slurry
virtual bool FA_Slurry(LE *a_field, double a_user, int a_days)
Spready slurry on a_field owned by an stock farmer.
Definition: farmfuncs.cpp:965
Farm::SpringPlough
virtual bool SpringPlough(LE *a_field, double a_user, int a_days)
Carry out a ploughing event in the spring on a_field.
Definition: farmfuncs.cpp:444
ofb_row_cultivation_one
Definition: OFodderbeet.h:54
Farm::Harvest
virtual bool Harvest(LE *a_field, double a_user, int a_days)
Carry out a harvest on a_field.
Definition: farmfuncs.cpp:1769
FarmEvent::m_lock
bool m_lock
Definition: farm.h:465
FarmEvent
A struct to hold the information required to trigger a farm event.
Definition: farm.h:463
OFB_DID_NPKS_ONE
#define OFB_DID_NPKS_ONE
Definition: OFodderbeet.h:34
Farm::DoIt
bool DoIt(double a_probability)
Return chance out of 0 to 100.
Definition: farm.cpp:800
FarmEvent::m_first_year
bool m_first_year
Definition: farm.h:467
tof_OptimisingFarm
Definition: farm.h:273
ofb_fertnpks_two
Definition: OFodderbeet.h:56
OFB_DID_NPKS_TWO
#define OFB_DID_NPKS_TWO
Definition: OFodderbeet.h:39
ofb_spring_roll
Definition: OFodderbeet.h:53
ofb_autumn_plough
Definition: OFodderbeet.h:45
Farm::FA_Manure
virtual bool FA_Manure(LE *a_field, double a_user, int a_days)
Spread manure on a_field owned by an stock farmer.
Definition: farmfuncs.cpp:1036
ofb_spring_plough
Definition: OFodderbeet.h:47
OFB_SOW_DATE
#define OFB_SOW_DATE
Definition: OFodderbeet.h:36
Farm::GetType
TTypesOfFarm GetType(void)
Definition: farm.h:901
Crop::m_first_date
int m_first_date
Definition: farm.h:540
FarmEvent::m_startday
int m_startday
Definition: farm.h:466
Farm::FA_NPK
virtual bool FA_NPK(LE *a_field, double a_user, int a_days)
Apply NPK fertilizer to a_field owned by an stock farmer.
Definition: farmfuncs.cpp:917
ofb_start_threads_one
Definition: OFodderbeet.h:48
Crop::SimpleEvent
void SimpleEvent(long a_date, int a_todo, bool a_lock)
Adds an event to this crop management.
Definition: farm.cpp:307
OFB_DID_ROW_TWO
#define OFB_DID_ROW_TWO
Definition: OFodderbeet.h:38
OFB_DID_HARROW
#define OFB_DID_HARROW
Definition: OFodderbeet.h:33
ofb_spring_sow
Definition: OFodderbeet.h:52
OFodderbeet::Do
bool Do(Farm *a_farm, LE *a_field, FarmEvent *a_ev)
Definition: OFodderbeet.cpp:31
OFB_DID_WATER_ONE
#define OFB_DID_WATER_ONE
Definition: OFodderbeet.h:40
ofb_spring_harrow
Definition: OFodderbeet.h:49
OFB_DID_SLURRY
#define OFB_DID_SLURRY
Definition: OFodderbeet.h:35
ofb_start
Definition: OFodderbeet.h:44
ofb_water_one
Definition: OFodderbeet.h:57
ofb_harvest
Definition: OFodderbeet.h:59
ofb_fertmanure
Definition: OFodderbeet.h:46
Crop::m_farm
Farm * m_farm
Definition: farm.h:537
Crop::m_field
LE * m_field
Definition: farm.h:538
FarmEvent::m_todo
int m_todo
Definition: farm.h:469
ofb_row_cultivation_two
Definition: OFodderbeet.h:55
Farm::RowCultivation
virtual bool RowCultivation(LE *a_field, double a_user, int a_days)
Carry out a harrowing between crop rows on a_field.
Definition: farmfuncs.cpp:1510
Farm::Water
virtual bool Water(LE *a_field, double a_user, int a_days)
Carry out a watering on a_field.
Definition: farmfuncs.cpp:1717
Crop::m_last_date
int m_last_date
Definition: farm.h:542
Farm::AutumnPlough
virtual bool AutumnPlough(LE *a_field, double a_user, int a_days)
Carry out a ploughing event in the autumn on a_field.
Definition: farmfuncs.cpp:132
Farm::SpringSow
virtual bool SpringSow(LE *a_field, double a_user, int a_days)
Carry out a sowing event in the spring on a_field.
Definition: farmfuncs.cpp:546
Farm
The base class for all farm types.
Definition: farm.h:767
OFB_TRULY_DID_WATER_ONE
#define OFB_TRULY_DID_WATER_ONE
Definition: OFodderbeet.h:41
ofb_fertnpks_one
Definition: OFodderbeet.h:50
ofb_fertslurry
Definition: OFodderbeet.h:51
Crop::ChooseNextCrop
void ChooseNextCrop(int a_no_dates)
Chooses the next crop to grow in a field.
Definition: farm.cpp:318
Crop::m_ev
FarmEvent * m_ev
Definition: farm.h:539
ofb_water_two
Definition: OFodderbeet.h:58
Farm::SpringHarrow
virtual bool SpringHarrow(LE *a_field, double a_user, int a_days)
Carry out a harrow event in the spring on a_field.
Definition: farmfuncs.cpp:471