ALMaSS Hare ODDox  1.1
The hare model description following ODdox protocol
OCloverGrassGrazed2.cpp
Go to the documentation of this file.
1 //
2 // OCloverGrassGrazed2.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/OCloverGrassGrazed2.h"
30 
31 
32 
33 using namespace std;
34 
35 extern CfgBool cfg_organic_extensive;
36 extern CfgFloat cfg_silage_prop;
37 
38 bool OCloverGrassGrazed2::Do( Farm *a_farm, LE *a_field, FarmEvent *a_ev )
39 {
40  m_farm = a_farm;
41  m_field = a_field;
42  m_ev = a_ev;
43  bool done = false;
44  long d1 = 0;
45  int noDates= 2;
46 
47  switch ( m_ev->m_todo ) {
48  case ocgg2_start:
49  OCGG2_CUT_DATE = 0;
50  OCGG2_WATER_DATE = 0;
51 
52  // Set up the date management stuff
53  // Could save the start day in case it is needed later
54  // m_field->m_startday = m_ev->m_startday;
55  m_last_date=g_date->DayInYear(10,10);
56  // Start and stop dates for all events after harvest
57  m_field->SetMDates(0,0,g_date->DayInYear(27,7));
58  // Determined by harvest date - used to see if at all possible
59  m_field->SetMDates(1,0,g_date->DayInYear(10,10));
60  m_field->SetMDates(0,1,g_date->DayInYear(1,9));
61  m_field->SetMDates(1,1,g_date->DayInYear(1,10));
62  // Check the next crop for early start, unless it is a spring crop
63  // in which case we ASSUME that no checking is necessary!!!!
64  // So DO NOT implement a crop that runs over the year boundary
65  if (m_ev->m_startday>g_date->DayInYear(1,7))
66  {
67  if (m_field->GetMDates(0,0) >=m_ev->m_startday)
68  {
69  g_msg->Warn( WARN_BUG, "OCloverGrassGrazed2::Do(): "
70  "Harvest too late for the next crop to start!!!", "" );
71  exit( 1 );
72  }
73  // Now fix any late finishing problems
74  for (int i=0; i<noDates; i++)
75  {
76  if (m_field->GetMDates(0,i)>=m_ev->m_startday) m_field->SetMDates(0,i,m_ev->m_startday-1);
77  if (m_field->GetMDates(1,i)>=m_ev->m_startday) 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. FN, 19/5-2003.
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, "OCloverGrassGrazed2::Do(): "
88  "Crop start attempt between 1st Jan & 1st July", "" );
89  exit( 1 );
90  } else {
91  d1 = g_date->OldDays() + m_first_date+365; // Add 365 for spring crop
92  if (g_date->Date() > d1) {
93  // Yes too late - should not happen - raise an error
94  g_msg->Warn( WARN_BUG, "OCloverGrassGrazed2::Do(): "
95  "Crop start attempt after last possible start date",
96  "" );
97  exit( 1 );
98  }
99  }
100  } else {
101  // First (invisible) year or testing. Force the correct starting date.
102  d1 = g_date->OldDays() + g_date->DayInYear( 1, 4 );
103  // If testing and not the first year, then push all events
104  // into next year (start event is called in the autumn after
105  // the current year has finished). FN, 20/5-2003.
106  if (!m_ev->m_first_year) d1 += 365;
107  }
108  m_field->SetLastSownVeg( m_field->GetOwner()->GetNextCrop( m_field->GetRotIndex() ) );
109  // OK, let's go.
110  OCGG2_CUT_DATE=0;
111  SimpleEvent( d1, ocgg2_ferti_zero, false );
112  break;
113  case ocgg2_ferti_zero:
114  if ( m_ev->m_lock || m_farm->DoIt( 50 ))
115  {
116  if (!m_farm->FA_Slurry( m_field, 0.0,
117  g_date->DayInYear( 30, 4 ) - g_date->DayInYear())) {
118  // We didn't do it today, try again tomorrow.
119  SimpleEvent( g_date->Date() + 1, ocgg2_ferti_zero, true );
120  break;
121  }
122  }
123  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 1,5 ),
124  ocgg2_cattle_out, false );
125 // SimpleEvent( g_date->OldDays() + g_date->DayInYear( 25,5 ),
126 // cgg2_cut_to_silage, false );
127 
128 // Start a watering thread
129  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 15, 5 ),
130  ocgg2_water_zero, false );
131  break;
132 
133 
134 case ocgg2_cattle_out:
135  if ( m_ev->m_lock || m_farm->DoIt( (int) (100-(cfg_silage_prop.value()*40) ))) {
136  if (cfg_organic_extensive.value()) {
137  if (!m_farm->CattleOutLowGrazing( m_field, 0.0,
138  m_field->GetMDates(1,1) -
139  g_date->DayInYear())) {
140  SimpleEvent( g_date->Date() + 1, ocgg2_cattle_out, true );
141  break;
142  }
143  }
144  else {
145  if (!m_farm->CattleOut( m_field, 0.0,
146  m_field->GetMDates(1,1) -
147  g_date->DayInYear())) {
148  SimpleEvent( g_date->Date() + 1, ocgg2_cattle_out, true );
149  break;
150  }
151  }
152  // Success
153  // Keep them out there
154  SimpleEvent( g_date->Date() + 1, ocgg2_cattle_is_out, false );
155  break;
156  }
157  SimpleEvent( g_date->OldDays() + g_date->DayInYear( 25,5 ),
158  ocgg2_cut_to_silage, false );
159  break;
160 
161 case ocgg2_cattle_is_out: // Keep the cattle out there
162  // CattleIsOut() returns false if it is not time to stop grazing
163  if (cfg_organic_extensive.value()) {
164  if (!m_farm->CattleIsOutLow( m_field, 0.0, m_field->GetMDates(1,1) -
165  g_date->DayInYear(),m_field->GetMDates(1,1))) {
166  SimpleEvent( g_date->Date() + 1, ocgg2_cattle_is_out, false );
167  break;
168  }
169  }
170  else {
171  if ( !m_farm->CattleIsOut( m_field, 0.0,
172  m_field->GetMDates(1,1) -
173  g_date->DayInYear(),m_field->GetMDates(1,1)))
174  {
175  SimpleEvent( g_date->Date() + 1, ocgg2_cattle_is_out, false );
176  break;
177  }
178  }
179  done=true;
180  break;
181 
183 if ( m_ev->m_lock || m_farm->DoIt( 100 )) {
184  if ( g_date->Date() < OCGG2_WATER_DATE + 7 ) {
185  SimpleEvent( g_date->Date() + 1, ocgg2_cut_to_silage, true );
186  break;
187  }
188  if (!m_farm->CutToSilage( m_field, 0.0,
189  g_date->DayInYear( 25, 6 ) -
190  g_date->DayInYear())) {
191  // We didn't do it today, try again tomorrow.
192  SimpleEvent( g_date->Date() + 1, ocgg2_cut_to_silage, true );
193  break;
194  }
195  OCGG2_CUT_DATE = g_date->Date();
196  SimpleEvent(g_date->OldDays() + m_field->GetMDates(0,1), ocgg2_stubble_harrow, false );
197  // But we need to graze too
198  SimpleEvent( g_date->Date()+14, ocgg2_cattle_out, true );
199 }
200 break;
201 
203 if ( m_ev->m_lock || m_farm->DoIt( 20 )) {
204  // But first if we are grazing then we must stop this
205  //
206  if (!m_farm->StubbleHarrowing( m_field, 0.0,
207  m_field->GetMDates(1,1) -
208  g_date->DayInYear())) {
209  // We didn't do it today, try again tomorrow.
210  SimpleEvent( g_date->Date() + 1, ocgg2_stubble_harrow, true );
211  break;
212  }
213  // If we ran, then we also happen to be the last event,
214  // so terminate the program by stopping grazing
215  m_field->SetMDates(1,1,g_date->DayInYear()-1);
216 }
217 break;
218 
219 case ocgg2_water_zero:
220  if ( m_ev->m_lock || m_farm->DoIt( 25 )) {
221  if ( g_date->Date() < OCGG2_CUT_DATE + 3 ) {
222  // Try again tomorrow, too close to silage cutting.
223  SimpleEvent( g_date->Date() + 1, ocgg2_water_zero, true );
224  break;
225  }
226  if (!m_farm->Water( m_field, 0.0,
227  g_date->DayInYear( 30, 5 ) -
228  g_date->DayInYear())) {
229  // We didn't do it today, try again tomorrow.
230  SimpleEvent( g_date->Date() + 1, ocgg2_water_zero, true );
231  break;
232  }
233  OCGG2_WATER_DATE = g_date->Date();
234 
235  long newdate1 = g_date->OldDays() + g_date->DayInYear( 1,6 );
236  long newdate2 = g_date->Date() + 7;
237  if ( newdate2 > newdate1 )
238  newdate1 = newdate2;
239  SimpleEvent( newdate1, ocgg2_water_one, false );
240  }
241  break;
242 
243 case ocgg2_water_one:
244  if ( m_ev->m_lock || m_farm->DoIt( 25 )) {
245  if ( g_date->Date() < OCGG2_CUT_DATE + 3 ) {
246  // Try again tomorrow, too close to silage cutting.
247  SimpleEvent( g_date->Date() + 1, ocgg2_water_one, true );
248  break;
249  }
250  if (!m_farm->Water( m_field, 0.0,
251  g_date->DayInYear( 15, 6 ) -
252  g_date->DayInYear())) {
253  // We didn't do it today, try again tomorrow.
254  SimpleEvent( g_date->Date() + 1, ocgg2_water_one, true );
255  break;
256  }
257  OCGG2_WATER_DATE = g_date->Date();
258  }
259  break;
260  // End of watering thread.
261 
262 
263  default:
264  g_msg->Warn( WARN_BUG, "OCloverGrassGrazed2::Do(): "
265  "Unknown event type! ", "" );
266  exit( 1 );
267  }
268 
269  return done;
270 }
271 //---------------------------------------------------------------------------
FarmEvent
A struct to hold the information required to trigger a farm event.
Definition: farm.h:463
ocgg2_start
Definition: OCloverGrassGrazed2.h:36
OCGG2_WATER_DATE
#define OCGG2_WATER_DATE
Definition: OCloverGrassGrazed2.h:32
OCGG2_CUT_DATE
#define OCGG2_CUT_DATE
Definition: OCloverGrassGrazed2.h:31
cfg_organic_extensive
CfgBool cfg_organic_extensive
ocgg2_water_zero
Definition: OCloverGrassGrazed2.h:39
cfg_silage_prop
CfgFloat cfg_silage_prop
ocgg2_stubble_harrow
Definition: OCloverGrassGrazed2.h:43
ocgg2_ferti_zero
Definition: OCloverGrassGrazed2.h:37
ocgg2_cut_to_silage
Definition: OCloverGrassGrazed2.h:38
ocgg2_cattle_is_out
Definition: OCloverGrassGrazed2.h:42
Farm
The base class for all farm types.
Definition: farm.h:767
OCloverGrassGrazed2::Do
bool Do(Farm *a_farm, LE *a_field, FarmEvent *a_ev)
Definition: OCloverGrassGrazed2.cpp:38
ocgg2_cattle_out
Definition: OCloverGrassGrazed2.h:41
ocgg2_water_one
Definition: OCloverGrassGrazed2.h:40