ALMaSS Vole ODDox  1.1
The vole model description following ODdox protocol
CloverGrassGrazed2.cpp
Go to the documentation of this file.
1 /*
2 *******************************************************************************************************
3 Copyright (c) 2011, Christopher John Topping, University of Aarhus
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without modification, are permitted provided
7 that the following conditions are met:
8 
9 Redistributions of source code must retain the above copyright notice, this list of conditions and the
10 following disclaimer.
11 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
12 the following disclaimer in the documentation and/or other materials provided with the distribution.
13 
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
15 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
17 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
18 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
19 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 ********************************************************************************************************
23 */
24 
25 //#define __EcoSol_01
26 #define _CRT_SECURE_NO_DEPRECATE
27 #include "../../BatchALMaSS/ALMaSS_Setup.h"
28 #include "../../Landscape/ls.h"
29 #include "../../Landscape/cropprogs/CloverGrassGrazed2.h"
30 
31 extern Landscape * g_landscape_p;
32 
33 extern CfgFloat cfg_silage_prop;
35 extern CfgInt cfg_pest_productapplic_period;
36 extern CfgFloat cfg_pest_product_1_amount;
37 
38 using namespace std;
39 
40 bool CloverGrassGrazed2::Do( Farm *a_farm, LE *a_field, FarmEvent *a_ev )
41 {
42  m_farm = a_farm;
43  m_field = a_field;
44  m_ev = a_ev;
45  long d1 = 0;
46  int noDates=2;
47  bool done = false;
48 
49  switch ( m_ev->m_todo ) {
50 
51  case cgg2_start:
52 
53  CGG2_CUT_DATE = 0;
54  CGG2_WATER_DATE = 0;
55  CGG2_DO_STUBBLE = 0;
56  CGG2_STOP_CATTLE = 0;
57 
58  m_last_date=g_date->DayInYear(1,10);
59 
60  // Start and stop dates for all events after harvest
61  m_field->SetMDates(0,0,g_date->DayInYear(25, 6));
62 
63  // Determined by harvest date - used to see if at all possible
64  m_field->SetMDates(1,0,g_date->DayInYear(25, 6));
65  m_field->SetMDates(0,1,g_date->DayInYear(1,9));
66  m_field->SetMDates(1,1,g_date->DayInYear(1,10));
67 
68  // Check the next crop for early start, unless it is a spring crop
69  // Check the next crop for early start, unless it is a spring crop
70  // in which case we ASSUME that no checking is necessary!!!!
71  // So DO NOT implement a crop that runs over the year boundary
72 
73  //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)
74  if(!(m_farm->GetType() == tof_OptimisingFarm && g_date->GetYearNumber()>0)){
75 
76  if (m_ev->m_startday>g_date->DayInYear(1,7))
77  {
78  if (m_field->GetMDates(0,0) >=m_ev->m_startday)
79  {
80  g_msg->Warn( WARN_BUG, "CloverGrassGrazed2::Do(): "
81  "Harvest too late for the next crop to start!!!", "" );
82  exit( 1 );
83  }
84  // Now fix any late finishing problems
85  for (int i=0; i<noDates; i++) {
86  if(m_field->GetMDates(0,i)>=m_ev->m_startday) {
87  m_field->SetMDates(0,i,m_ev->m_startday-1); //move the starting date
88  }
89  if(m_field->GetMDates(1,i)>=m_ev->m_startday){
90  m_field->SetMConstants(i,0);
91  m_field->SetMDates(1,i,m_ev->m_startday-1); //move the finishing date
92  }
93  }
94  }
95  // Now no operations can be timed after the start of the next crop.
96  // Added test for management plan testing. FN, 19/5-2003.
97  if ( ! ( m_ev->m_first_year //|| g_farm_test_crop.value()
98  )) {
99  // Are we before July 1st?
100  d1 = g_date->OldDays() + g_date->DayInYear( 1,7 );
101  if (g_date->Date() < d1) {
102  // Yes, too early. We assumme this is because the last crop was late
103  g_msg->Warn( WARN_BUG, "CloverGrassGrazed2::Do(): "
104  "Crop start attempt between 1st Jan & 1st July", "" );
105  exit( 1 );
106  }
107  else
108  {
109  d1 = g_date->OldDays() + m_first_date+365; // Add 365 for spring crop
110  if (g_date->Date() > d1) {
111  // Yes too late - should not happen - raise an error
112  g_msg->Warn( WARN_BUG, "CloverGrassGrazed2::Do(): "
113  "Crop start attempt after last possible start date",
114  "" );
115  exit( 1 );
116  }
117  }
118  } else {
119  // First (invisible) year or testing. Force the correct starting date.
120  d1 = g_date->OldDays() + g_date->DayInYear( 1, 4 );
121  // If testing and not the first year, then push all events
122  // into next year (start event is called in the autumn after
123  // the current year has finished). FN, 20/5-2003.
124  if (!m_ev->m_first_year) d1 += 365;
125  }
126  }//if
127  m_field->SetLastSownVeg( m_field->GetVegType() ); //Force last sown, needed for goose habitat classification
128  d1 = g_date->OldDays() + m_first_date+365;
129 
130 
131  SimpleEvent( d1, cgg2_ferti_zero, false );
132  SimpleEvent( d1, cgg2_ferti_one, false );
133 #ifdef __EcoSol_01
134  // THIS CODE IS ONLY NEEDED IF WE ARE TESTING A HERBICIDE WITH THE PESTICIDE ENGINE
135  /* */
136  if ( g_landscape_p->SupplyShouldSpray() ) {
137  d1 = g_date->OldDays() + cfg_pest_productapplic_startdate.value();
138  if (g_date->Date() >= d1) d1 += 365;
139  SimpleEvent( d1, cgg2_productapplic_one, false );
140  }
141  /* */
142 #endif
143  break;
144 
146  if ( m_ev->m_lock || m_farm->DoIt( 100 ))
147  {
148  if (!m_farm->ProductApplication( m_field, 0.0,(cfg_pest_productapplic_startdate.value()+cfg_pest_productapplic_period.value()) - g_date->DayInYear(), cfg_pest_product_1_amount.value(), ppp_1)) {
149  // We didn't do it today, try again tomorrow.
150  SimpleEvent( g_date->Date() + 1, cgg2_productapplic_one, true );
151  break;
152  }
153  }
154  break;
155 
156  case cgg2_ferti_zero:
157  if ( m_ev->m_lock || m_farm->DoIt( 30 )) {
158  if (!m_farm->FA_Slurry( m_field, 0.0,
159  g_date->DayInYear( 25, 4 ) -
160  g_date->DayInYear())) {
161  // We didn't do it today, try again tomorrow.
162  SimpleEvent( g_date->Date() + 1, cgg2_ferti_zero, true );
163  break;
164  }
165  }
166  break;
167 
168  case cgg2_ferti_one:
169  if ( m_ev->m_lock || m_farm->DoIt( 80 )) {
170  if (!m_farm->FA_NPK( m_field, 0.0,
171  g_date->DayInYear( 25, 4 ) -
172  g_date->DayInYear())) {
173  // We didn't do it today, try again tomorrow.
174  SimpleEvent( g_date->Date() + 1, cgg2_ferti_one, true );
175  break;
176  }
177  }
178 
179  ChooseNextCrop (2);
180 
181 
182  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 1,5 ),
183  cgg2_cattle_out, false );
184 // SimpleEvent( g_date->OldDays() + g_date->DayInYear( 25,5 ),
185 // cgg2_cut_to_silage, false );
186 
187  // Start a watering thread
188  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 15, 5 ),
189  cgg2_water_zero, false );
190  break;
191 
192 
193  case cgg2_cattle_out:
194  if ( m_ev->m_lock || m_farm->DoIt( (int) (100- ((cfg_silage_prop.value()*40) )))) {
195  if (m_field->GetMConstants(1)==0) {
196  if (!m_farm->CattleOut( m_field, 0.0, -1)) { //raise an error
197  g_msg->Warn( WARN_BUG, "CloverGrassGrazed2::Do(): failure in 'CattleOut' execution", "" );
198  exit( 1 );
199  }
200  }
201  else {
202  if (!m_farm->CattleOut( m_field, 0.0, m_field->GetMDates(1,1) - g_date->DayInYear())) {
203  SimpleEvent( g_date->Date() + 1, cgg2_cattle_out, true );
204  break;
205  }
206  }
207  // Success
208  // Keep them out there
209  SimpleEvent( g_date->Date() + m_field->GetMConstants(1), cgg2_cattle_is_out, false );
210  break;
211  }
212  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 25,5 ), cgg2_cut_to_silage, true ); // Must do this
213  break;
214 
215  case cgg2_cattle_is_out: // Keep the cattle out there
216  //CattleIsOut() returns false if it is not time to stop grazing
217  /*
218  HERE I CANNOT SEE WHY WE NEED THE FORCING OF a_days to be -1
219  if (m_field->GetMConstants(1)==0) {
220  if (!m_farm->CattleIsOut( m_field, 0.0, -1, m_field->GetMDates(1,1))) {
221  //added 27.08 - issue a warning only if we fail on the last day that this can be done, i.e. MDate
222  if(g_date->Date() == m_field->GetMDates(1,1)){
223  g_msg->Warn( WARN_BUG, "CloverGrassGrazed2::Do(): failure in 'CattleIsOut' execution", "" );
224  exit( 1 );
225  }
226  SimpleEvent( g_date->Date()+1, cgg2_cattle_is_out, false );
227  break;
228  }
229  }
230  else {
231  if ( !m_farm->CattleIsOut( m_field, 0.0, m_field->GetMDates(1,1) - g_date->DayInYear(), m_field->GetMDates(1,1))) {
232  SimpleEvent( g_date->Date() + 1, cgg2_cattle_is_out, false );
233  break;
234  }
235  }
236  */
237  if (!m_farm->CattleIsOut(m_field, 0.0, m_field->GetMDates(1, 1) - g_date->DayInYear(), m_field->GetMDates(1, 1))) {
238  //added 27.08 - issue a warning only if we fail on the last day that this can be done, i.e. MDate
239  if (g_date->Date() == m_field->GetMDates(1, 1)){
240  g_msg->Warn(WARN_BUG, "CloverGrassGrazed2::Do(): failure in 'CattleIsOut' execution", "Over-stepped the last possible date");
241  exit(1);
242  }
243  SimpleEvent(g_date->Date() + 1, cgg2_cattle_is_out, false);
244  break;
245  }
246  done = true;
247  break;
248 
249  case cgg2_cut_to_silage:
250  if ( m_ev->m_lock ) {
251  if ( g_date->Date() < CGG2_WATER_DATE + 7 ) {
252  SimpleEvent( g_date->Date() + 1, cgg2_cut_to_silage, true );
253  break;
254  }
255  if (!m_farm->CutToSilage( m_field, 0.0,
256  g_date->DayInYear( 25, 6 ) -
257  g_date->DayInYear())) {
258  // We didn't do it today, try again tomorrow.
259  SimpleEvent( g_date->Date() + 1, cgg2_cut_to_silage, true );
260  break;
261  }
262  CGG2_CUT_DATE = g_date->Date();
263  SimpleEvent(g_date->OldDays() + m_field->GetMDates(0,1), cgg2_stubble_harrow, false );
264  // But we need to graze too
265  SimpleEvent( g_date->Date()+14, cgg2_cattle_out, true );
266  }
267  break;
268 
269  case cgg2_stubble_harrow:
270  if ( m_ev->m_lock || m_farm->DoIt( 20 )) {
271  // But first if we are grazing then we must stop this
272  //
273  if (m_field->GetMConstants(1)==0) {
274  if (!m_farm->StubbleHarrowing( m_field, 0.0, -1)) { //raise an error
275  g_msg->Warn( WARN_BUG, "CloverGrassGrazed2::Do(): failure in 'StubbleHarrowing' execution", "" );
276  exit( 1 );
277  }
278  }
279  else {
280  if (!m_farm->StubbleHarrowing( m_field, 0.0, m_field->GetMDates(1,1) - g_date->DayInYear())) {
281  // We didn't do it today, try again tomorrow.
282  SimpleEvent( g_date->Date() + 1, cgg2_stubble_harrow, true );
283  break;
284  }
285  }
286  // If we ran, then we also happen to be the last event,
287  // so terminate the program by stopping grazing
288  m_field->SetMDates(1,1,g_date->DayInYear()-1);
289  }
290  break;
291 
292  case cgg2_water_zero:
293  if ( m_ev->m_lock || m_farm->DoIt( 25 )) {
294  if ( g_date->Date() < CGG2_CUT_DATE + 3 ) {
295  // Try again tomorrow, too close to silage cutting.
296  SimpleEvent( g_date->Date() + 1, cgg2_water_zero, true );
297  break;
298  }
299  if (!m_farm->Water( m_field, 0.0,
300  g_date->DayInYear( 30, 5 ) -
301  g_date->DayInYear())) {
302  // We didn't do it today, try again tomorrow.
303  SimpleEvent( g_date->Date() + 1, cgg2_water_zero, true );
304  break;
305  }
306  CGG2_WATER_DATE = g_date->Date();
307 
308  long newdate1 = g_date->OldDays() + g_date->DayInYear( 1,6 );
309  long newdate2 = g_date->Date() + 7;
310  if ( newdate2 > newdate1 )
311  newdate1 = newdate2;
312  SimpleEvent( newdate1, cgg2_water_one, false );
313  }
314  break;
315 
316  case cgg2_water_one:
317  if ( m_ev->m_lock || m_farm->DoIt( 25 )) {
318  if ( g_date->Date() < CGG2_CUT_DATE + 3 ) {
319  // Try again tomorrow, too close to silage cutting.
320  SimpleEvent( g_date->Date() + 1, cgg2_water_one, true );
321  break;
322  }
323  if (!m_farm->Water( m_field, 0.0,
324  g_date->DayInYear( 15, 6 ) -
325  g_date->DayInYear())) {
326  // We didn't do it today, try again tomorrow.
327  SimpleEvent( g_date->Date() + 1, cgg2_water_one, true );
328  break;
329  }
330  CGG2_WATER_DATE = g_date->Date();
331  }
332  break;
333  // End of watering thread.
334 
335  default:
336  g_msg->Warn( WARN_BUG, "CloverGrassGrazed2::Do(): "
337  "Unknown event type! ", "" );
338  exit( 1 );
339  }
340  return done;
341 }
342 //---------------------------------------------------------------------------
cfg_pest_productapplic_startdate
CfgInt cfg_pest_productapplic_startdate
Landscape::SupplyShouldSpray
bool SupplyShouldSpray()
Definition: Landscape.h:357
FarmEvent
A struct to hold the information required to trigger a farm event.
Definition: farm.h:463
tof_OptimisingFarm
Definition: farm.h:273
CGG2_DO_STUBBLE
#define CGG2_DO_STUBBLE
Definition: CloverGrassGrazed2.h:33
Landscape
The landscape class containing all environmental and topographical data.
Definition: Landscape.h:112
g_landscape_p
Landscape * g_landscape_p
Definition: Landscape.cpp:258
cgg2_cattle_is_out
Definition: CloverGrassGrazed2.h:46
cfg_pest_product_1_amount
CfgFloat cfg_pest_product_1_amount
cgg2_water_zero
Definition: CloverGrassGrazed2.h:43
cgg2_stubble_harrow
Definition: CloverGrassGrazed2.h:47
cgg2_water_one
Definition: CloverGrassGrazed2.h:44
cgg2_cattle_out
Definition: CloverGrassGrazed2.h:45
ppp_1
Definition: farm.h:422
cgg2_productapplic_one
Definition: CloverGrassGrazed2.h:48
cfg_pest_productapplic_period
CfgInt cfg_pest_productapplic_period
Farm
The base class for all farm types.
Definition: farm.h:767
CGG2_CUT_DATE
#define CGG2_CUT_DATE
Definition: CloverGrassGrazed2.h:31
cgg2_ferti_one
Definition: CloverGrassGrazed2.h:40
cgg2_ferti_zero
Definition: CloverGrassGrazed2.h:39
CGG2_WATER_DATE
#define CGG2_WATER_DATE
Definition: CloverGrassGrazed2.h:32
CGG2_STOP_CATTLE
#define CGG2_STOP_CATTLE
Definition: CloverGrassGrazed2.h:34
cgg2_start
Definition: CloverGrassGrazed2.h:38
cfg_silage_prop
CfgFloat cfg_silage_prop
CloverGrassGrazed2::Do
bool Do(Farm *a_farm, LE *a_field, FarmEvent *a_ev)
Definition: CloverGrassGrazed2.cpp:40
cgg2_cut_to_silage
Definition: CloverGrassGrazed2.h:42