ALMaSS Hare ODDox  1.1
The hare model description following ODdox protocol
OCloverGrassGrazed1.cpp
Go to the documentation of this file.
1 //
2 // OCloverGrassGrazed1.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/OCloverGrassGrazed1.h"
30 
31 
32 using namespace std;
33 
34 extern CfgBool cfg_organic_extensive;
35 extern CfgFloat cfg_silage_prop;
36 
37 bool OCloverGrassGrazed1::Do( Farm *a_farm, LE *a_field, FarmEvent *a_ev )
38 {
39  m_farm = a_farm;
40  m_field = a_field;
41  m_ev = a_ev;
42 
43  bool done = false;
44  int d1 = 0;
45  int noDates= 2;
46 
47  switch ( m_ev->m_todo ) {
48  case ocgg1_start:
49  {
50  // Set up the date management stuff
51  // Could save the start day in case it is needed later
52  // m_field->m_startday = m_ev->m_startday;
53  m_last_date = g_date->DayInYear(10, 10);
54  // Start and stop dates for all events after harvest
55  m_field->SetMDates(0, 0, g_date->DayInYear(7, 8));
56  // Determined by harvest date - used to see if at all possible
57  m_field->SetMDates(1, 0, g_date->DayInYear(1, 10));
58  m_field->SetMDates(0, 1, g_date->DayInYear(10, 10));
59  m_field->SetMDates(1, 1, g_date->DayInYear(10, 10));
60  // Check the next crop for early start, unless it is a spring crop
61  // in which case we ASSUME that no checking is necessary!!!!
62  // So DO NOT implement a crop that runs over the year boundary
63  if (m_ev->m_startday > g_date->DayInYear(1, 7))
64  {
65  if (m_field->GetMDates(0, 0) >= m_ev->m_startday)
66  {
67  g_msg->Warn(WARN_BUG, "OCloverGrassGrazed1::Do(): "
68  "Harvest too late for the next crop to start!!!", "");
69  exit(1);
70  }
71  // Now fix any late finishing problems
72  for (int i = 0; i < noDates; i++)
73  {
74  if (m_field->GetMDates(0, i) >= m_ev->m_startday)
75  m_field->SetMDates(0, i, m_ev->m_startday - 1);
76  if (m_field->GetMDates(1, i) >= m_ev->m_startday)
77  m_field->SetMDates(1, i, m_ev->m_startday - 1);
78  }
79  }
80  // Now no operations can be timed after the start of the next crop.
81  // Added test for management plan testing.
82  if (!(m_ev->m_first_year)) {
83  // Are we before July 1st?
84  d1 = g_date->OldDays() + g_date->DayInYear(1, 7);
85  if (g_date->Date() < d1) {
86  // Yes, too early. We assumme this is because the last crop was late
87  g_msg->Warn(WARN_BUG, "OCloverGrassGrazed1::Do(): "
88  "Crop start attempt between 1st Jan & 1st July", "");
89  exit(1);
90  }
91  else {
92  d1 = g_date->OldDays() + m_first_date + 365; // Add 365 for spring crop
93  if (g_date->Date() > d1) {
94  // Yes too late - should not happen - raise an error
95  g_msg->Warn(WARN_BUG, "OCloverGrassGrazed1::Do(): "
96  "Crop start attempt after last possible start date",
97  "");
98  exit(1);
99  }
100  }
101  }
102  else {
103  // First (invisible) year or testing. Force the correct starting date.
104  d1 = g_date->OldDays() + g_date->DayInYear(1, 4);
105  // If testing and not the first year, then push all events
106  // into next year (start event is called in the autumn after
107  // the current year has finished).
108  if (!m_ev->m_first_year) d1 += 365;
109  }
110  m_field->SetLastSownVeg(m_field->GetVegType()); //Force last sown, needed for goose habitat classification
111  // OK, let's go.
112  OCGG1_CUT_DATE = 0;
113  SimpleEvent(d1, ocgg1_ferti_zero, false);
114  }
115  break;
116 
117  case ocgg1_ferti_zero:
118  if ( m_ev->m_lock || m_farm->DoIt( 50 ))
119  {
120  if (!m_farm->FA_Slurry( m_field, 0.0,
121  g_date->DayInYear( 30, 4 ) - g_date->DayInYear())) {
122  // We didn't do it today, try again tomorrow.
123  SimpleEvent( g_date->Date() + 1, ocgg1_ferti_zero, true );
124  break;
125  }
126  }
127  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 25, 5 ),
128  ocgg1_cut_to_silage, false );
129  // Start a watering thread
130  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 1, 6 ),
131  ocgg1_water_zero, false );
132  break;
133 
134  case ocgg1_cut_to_silage:
135  if ( m_ev->m_lock || m_farm->DoIt( (int) (cfg_silage_prop.value()*100 )))
136  {
137  if (!m_farm->CutToSilage( m_field, 0.0,
138  g_date->DayInYear( 15, 6 ) - g_date->DayInYear())) {
139  // We didn't do it today, try again tomorrow.
140  SimpleEvent( g_date->Date() + 1, ocgg1_cut_to_silage, true );
141  break;
142  }
143  // Success so queue up the next event
144  OCGG1_CUT_DATE=g_date->DayInYear();
145  if ( OCGG1_CUT_DATE+14>g_date->DayInYear(25,5) )
146  SimpleEvent( g_date->OldDays() + OCGG1_CUT_DATE+14,
147  ocgg1_cattle_out, false );
148  else
149  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 25, 5 ),
150  ocgg1_cattle_out, false );
151  break;
152  }
153  else
154  {
155  // Didn't want to cut so go direct to graze
156  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 25, 5 ),
157  ocgg1_cattle_out, true );
158 
159  }
160  break;
161 
162  case ocgg1_water_zero:
163  if ( m_ev->m_lock || m_farm->DoIt( 30 ))
164  {
165  if (!m_farm->Water( m_field, 0.0,
166  g_date->DayInYear( 15, 6 ) - g_date->DayInYear())) {
167  // We didn't do it today, try again tomorrow.
168  SimpleEvent( g_date->Date() + 1, ocgg1_water_zero, true );
169  break;
170  }
171  // Success
172  if ( (g_date->DayInYear()+7)<g_date->DayInYear( 25,6 ) )
173  SimpleEvent( g_date->OldDays() + (g_date->DayInYear()+7),
174  ocgg1_water_one, false );
175  else
176  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 25,6 ),
177  ocgg1_water_one, false );
178  break;
179  }
180  // Didn't water so let the thread die
181  break;
182 
183  case ocgg1_water_one:
184  if ( m_ev->m_lock || m_farm->DoIt( 67 )) //**CJT** check this or 20
185  {
186  // --FN--
187  if (!m_farm->Water( m_field, 0.0,
188  g_date->DayInYear( 25, 7 ) - g_date->DayInYear())) {
189  // We didn't do it today, try again tomorrow.
190  SimpleEvent( g_date->Date() + 1, ocgg1_water_one, true );
191  break;
192  }
193  }
194  break;
195  // End of watering thread
196 
197  case ocgg1_cattle_out:
198  if ( m_ev->m_lock || m_farm->DoIt( 50 ))
199  {
200  if (cfg_organic_extensive.value()) {
201  if (!m_farm->CattleOutLowGrazing( m_field, 0.0,
202  m_field->GetMDates(1,0) - g_date->DayInYear())) {
203  SimpleEvent( g_date->Date() + 1, ocgg1_cattle_out, true );
204  break;
205  }
206  }
207  else {
208  if (!m_farm->CattleOut( m_field, 0.0,
209  m_field->GetMDates(1,0) - g_date->DayInYear())) {
210  SimpleEvent( g_date->Date() + 1, ocgg1_cattle_out, true );
211  break;
212  }
213  }
214  // Success
215  // Keep them out there
216  SimpleEvent( g_date->Date() + 1, ocgg1_cattle_is_out, false );
217  break;
218  }
219  // don't graze so carry on with fertilizer etc.
220  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 25,5 ),
221  ocgg1_ferti_one, false );
222  break;
223 
224  case ocgg1_cattle_is_out: // Keep the cattle out there
225  // CattleIsOut() returns false if it is not time to stop grazing
226  if (cfg_organic_extensive.value()) {
227  if (!m_farm->CattleIsOutLow( m_field, 0.0,
228  m_field->GetMDates(0,1) - g_date->DayInYear(),m_field->GetMDates(0,1))) {
229  SimpleEvent( g_date->Date() + 1, ocgg1_cattle_is_out, false );
230  break;
231  }
232  }
233  else {
234  if (!m_farm->CattleIsOut( m_field, 0.0,
235  m_field->GetMDates(0,1) - g_date->DayInYear(),m_field->GetMDates(0,1))) {
236  SimpleEvent( g_date->Date() + 1, ocgg1_cattle_is_out, false );
237  break;
238  }
239  }
240  // if it is time to stop grazing then that years activities are over
241  done = true; // End of activities
242  break;
243 
244  case ocgg1_ferti_one:
245  if (!m_farm->FA_Slurry( m_field, 0.0,
246  ( OCGG1_CUT_DATE+4 ) - g_date->DayInYear())) {
247  SimpleEvent( g_date->Date() + 1, ocgg1_ferti_one, true );
248  break;
249  }
250  OCGG1_SLURRY=g_date->DayInYear();
251  if ( (g_date->DayInYear(15,6))<OCGG1_CUT_DATE+21 )
252  SimpleEvent( g_date->OldDays() + (OCGG1_CUT_DATE+21),
253  ocgg1_cut_to_silage1, false );
254  else
255  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 15,6 ),
256  ocgg1_cut_to_silage1, false );
257  break;
258 
260  if ( m_ev->m_lock || m_farm->DoIt((int) (cfg_silage_prop.value()* 60 )))
261  {
262  if (!m_farm->CutToSilage( m_field, 0.0,
263  g_date->DayInYear( 7,7 ) - g_date->DayInYear())) {
264  // We didn't do it today, try again tomorrow.
265  SimpleEvent( g_date->Date() + 1, ocgg1_cut_to_silage, true );
266  break;
267  }
268  // Success so queue up the next event
269  OCGG1_CUT_DATE=g_date->DayInYear();
270  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 15, 6 ),
271  ocgg1_ferti_two, false );
272  break;
273  }
274  else
275  {
276  // Didn't want to cut so go direct to graze
277  SimpleEvent( g_date->OldDays() + OCGG1_SLURRY+14,
278  ocgg1_cattle_out, true ); // Must do it
279  }
280  break;
281 
282  case ocgg1_ferti_two:
283  if ( m_ev->m_lock || m_farm->DoIt( 60 ))
284  {
285  if (!m_farm->FA_Slurry( m_field, 0.0,
286  (OCGG1_CUT_DATE+4) - g_date->DayInYear())) {
287  SimpleEvent( g_date->Date() + 2, ocgg1_ferti_two, true );
288  break;
289  }
290  OCGG1_SLURRY=g_date->DayInYear();
291  }
292  {
293  d1=OCGG1_SLURRY+21;
294  long d2=g_date->DayInYear(1,7);
295  if (d2>d1) d1=d2;
296  SimpleEvent( g_date->OldDays() + d1,
297  ocgg1_cut_to_silage2, false );
298  }
299  break;
300 
302  if ( m_ev->m_lock || m_farm->DoIt( (int) (cfg_silage_prop.value()*60) ))
303  {
304  if (!m_farm->CutToSilage( m_field, 0.0,
305  g_date->DayInYear( 30, 6 ) - g_date->DayInYear())) {
306  // We didn't do it today, try again tomorrow.
307  SimpleEvent( g_date->Date() + 1, ocgg1_cut_to_silage2, true );
308  break;
309  }
310  // Success so queue up the next event
311  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 5, 7 ),
312  ocgg1_ferti_three, false );
313  break;
314  }
315  else
316  {
317  // Didn't want to cut so go direct to graze
318  SimpleEvent( g_date->OldDays() + OCGG1_SLURRY+14,
319  ocgg1_cattle_out, true ); // Must do it !
320  }
321  break;
322 
323  case ocgg1_ferti_three:
324  if (!m_farm->FA_Slurry( m_field, 0.0,
325  m_field->GetMDates(0,0) - g_date->DayInYear())) {
326  SimpleEvent( g_date->Date() + 1, ocgg1_ferti_three, true );
327  break;
328  }
329  done = true; // nothing else to do
330  break;
331 
332  default:
333  g_msg->Warn( WARN_BUG, "OCloverGrassGrazed1::Do(): "
334  "Unknown event type! ", "" );
335  exit( 1 );
336  }
337  return done;
338 }
339 //---------------------------------------------------------------------------
OCGG1_SLURRY
#define OCGG1_SLURRY
Definition: OCloverGrassGrazed1.h:33
FarmEvent
A struct to hold the information required to trigger a farm event.
Definition: farm.h:463
ocgg1_cut_to_silage2
Definition: OCloverGrassGrazed1.h:42
ocgg1_ferti_three
Definition: OCloverGrassGrazed1.h:39
ocgg1_cattle_out
Definition: OCloverGrassGrazed1.h:45
OCGG1_CUT_DATE
#define OCGG1_CUT_DATE
Definition: OCloverGrassGrazed1.h:31
OCloverGrassGrazed1::Do
bool Do(Farm *a_farm, LE *a_field, FarmEvent *a_ev)
Definition: OCloverGrassGrazed1.cpp:37
cfg_organic_extensive
CfgBool cfg_organic_extensive
ocgg1_ferti_one
Definition: OCloverGrassGrazed1.h:37
ocgg1_water_zero
Definition: OCloverGrassGrazed1.h:43
ocgg1_start
Definition: OCloverGrassGrazed1.h:35
ocgg1_cut_to_silage
Definition: OCloverGrassGrazed1.h:40
ocgg1_cattle_is_out
Definition: OCloverGrassGrazed1.h:46
ocgg1_water_one
Definition: OCloverGrassGrazed1.h:44
cfg_silage_prop
CfgFloat cfg_silage_prop
ocgg1_ferti_zero
Definition: OCloverGrassGrazed1.h:36
Farm
The base class for all farm types.
Definition: farm.h:767
ocgg1_ferti_two
Definition: OCloverGrassGrazed1.h:38
ocgg1_cut_to_silage1
Definition: OCloverGrassGrazed1.h:41