ALMaSS Vole ODDox  1.1
The vole model description following ODdox protocol
setaside.cpp
Go to the documentation of this file.
1 /*
2 *******************************************************************************************************
3 Copyright (c) 2011, Christopher John Topping, Aarhus University
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 */
37 //
38 // setaside.cpp
39 //
40 /*
41 
42 Copyright (c) 2003, National Environmental Research Institute, Denmark (NERI)
43 
44 All rights reserved.
45 
46 
47 Redistribution and use in source and binary forms, with or without
48 modification, are permitted provided that the following conditions are met:
49 
50 *) Redistributions of source code must retain the above copyright notice, this
51 list of conditions and the following disclaimer.
52 *) Redistributions in binary form must reproduce the above copyright notice,
53 this list of conditions and the following disclaimer in the documentation
54 and/or other materials provided with the distribution.
55 *) Neither the name of the NERI nor the names of its contributors
56 may be used to endorse or promote products derived from this software without
57 specific prior written permission.
58 
59 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
60 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
63 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
64 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
65 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
66 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
67 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
68 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
69 POSSIBILITY OF SUCH DAMAGE.
70 
71 */
72 //#include "stdafx.h"
73 
74 #include "../../Landscape/ls.h"
75 #include "../../Landscape/cropprogs/setaside.h"
76 
77 
86 bool SetAside::Do( Farm *a_farm, LE *a_field, FarmEvent *a_ev )
87 {
88  m_farm = a_farm;
89  m_field = a_field;
90  m_ev = a_ev;
91  int d1 = 0;
92  int noDates = 3;
93  bool done = false;
94 
95  switch ( m_ev->m_todo ) {
96  case sa_start:
97  // Special for set-aside:
98  m_field->SetVegPatchy( true );
99  // Set up the date management stuff
100  // Could save the start day in case it is needed later
101  // m_field->m_startday = m_ev->m_startday;
102  m_last_date=g_date->DayInYear(10,10);
103  // Start and stop dates for all events after harvest
104  m_field->SetMDates(0,0,g_date->DayInYear(30,6));
105  // Determined by harvest date - used to see if at all possible
106  m_field->SetMDates(1,0,g_date->DayInYear(25,8));
107  m_field->SetMDates(0,1,g_date->DayInYear(1,9));
108  m_field->SetMDates(1,1,g_date->DayInYear(15,9));
109  m_field->SetMDates(0,2,g_date->DayInYear(1,9));
110  m_field->SetMDates(1,2,g_date->DayInYear(10,10));
111  // Check the next crop for early start, unless it is a spring crop
112  // in which case we ASSUME that no checking is necessary!!!!
113  // So DO NOT implement a crop that runs over the year boundary
114 
115  //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)
116  if(!(m_farm->GetType() == tof_OptimisingFarm && g_date->GetYearNumber()>0)){
117 
118  if (m_ev->m_startday>g_date->DayInYear(1,7)) {
119  if (m_field->GetMDates(0,0) >=m_ev->m_startday) {
120  g_msg->Warn( WARN_BUG, "Setaside::Do(): "
121  "Harvest too late for the next crop to start!!!", "" );
122  exit( 1 );
123  }
124  // Now fix any late finishing problems
125  for (int i=0; i<noDates; i++) {
126  if(m_field->GetMDates(0,i)>=m_ev->m_startday) {
127  m_field->SetMDates(0,i,m_ev->m_startday-1); //move the starting date
128  }
129  if(m_field->GetMDates(1,i)>=m_ev->m_startday){
130  m_field->SetMConstants(i,0);
131  m_field->SetMDates(1,i,m_ev->m_startday-1); //move the finishing date
132  }
133  }
134  }
135 
136  // Now no operations can be timed after the start of the next crop.
137  if ( ! m_ev->m_first_year ) {
138  // Are we before July 1st?
139  d1 = g_date->OldDays() + g_date->DayInYear( 1,7 );
140  if (g_date->Date() < d1) {
141  // Yes, too early. We assumme this is because the last crop was late
142  g_msg->Warn( WARN_BUG, "Setaside::Do(): "
143  "Crop start attempt between 1st Jan & 1st July", "" );
144  exit( 1 );
145  } else {
146  d1 = g_date->OldDays() + m_first_date+365; // Add 365 for spring crop
147  if (g_date->Date() > d1) {
148  // Yes too late - should not happen - raise an error
149  g_msg->Warn( WARN_BUG, "SetAside::Do(): "
150  "Crop start attempt after last possible start date",
151  "" );
152  exit( 1 );
153  }
154  }
155  }
156  }//if
157 
158  // New begin.
159  d1 = g_date->OldDays() + m_first_date;
160 
161  if ( ! m_ev->m_first_year ) {
162  d1 +=365 ;
163  }
164  if ( g_date->Date() > d1 ) {
165  d1 = g_date->Date();
166  }
167 
168  // ***CJT*** altered 16 August 2004 to be more similar to non-managed set-aside
169  // SimpleEvent( d1, sa_wait, false );
170  // break;
171 
172  SimpleEvent( d1, sa_cut_to_hay, false );
173  break;
174 
175  case sa_cut_to_hay:
176  if (!m_farm->CutToHay( m_field, 0.0, g_date->DayInYear( 30, 7 ) - g_date->DayInYear())) {
177  SimpleEvent( g_date->Date() + 1, sa_cut_to_hay, false );
178  break;
179  }
180  if ( !m_farm->IsStockFarmer())
181  {
182 
183  ChooseNextCrop (3);
184 
185  SimpleEvent( g_date->Date() + 1, sa_wait, false );
186  break;
187  }
188 
189  SimpleEvent( g_date->OldDays() + m_field->GetMDates(0,1),
190  sa_cattle_out, false );
191  break;
192 
193  case sa_cattle_out:
194  if ( m_ev->m_lock || m_farm->DoIt( 15 )) {
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, "Setaside::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, sa_cattle_out, true );
204  break;
205  }
206  }
207  SimpleEvent( g_date->Date() + m_field->GetMConstants(2), sa_cattle_is_out, false );
208  break;
209  }
210  SimpleEvent( g_date->OldDays() + m_field->GetMDates(0,1), sa_cut_to_silage, false );
211  break;
212 
213  case sa_cattle_is_out:
214  if (m_field->GetMConstants(2)==0) {
215  if (!m_farm->CattleIsOut( m_field, 0.0, -1, m_field->GetMDates(1,2))) { //raise an error
216  //added 28.08 - issue a warning only if we fail on the last day that this can be done, i.e. MDate
217  if(g_date->Date() == m_field->GetMDates(1,2)){
218  g_msg->Warn( WARN_BUG, "Setaside::Do(): failure in 'CattleIsOut' execution", "" );
219  exit( 1 );
220  }
221  }
222  }
223  else {
224  if (!m_farm->CattleIsOut( m_field, 0.0, m_field->GetMDates(1,2) - g_date->DayInYear(), m_field->GetMDates(1,2))) {
225  SimpleEvent( g_date->Date() + 1, sa_cattle_is_out, false );
226  break;
227  }
228  }
229  ChooseNextCrop (3);
230 
231  SimpleEvent( g_date->Date() + 1, sa_wait, false );
232  break;
233 
234  case sa_cut_to_silage:
235  if ( m_ev->m_lock || m_farm->DoIt( 15 )) {
236  if (m_field->GetMConstants(0)==0) {
237  if (!m_farm->CutToSilage( m_field, 0.0, -1)) { //raise an error
238  g_msg->Warn( WARN_BUG, "Setaside::Do(): failure in 'CutToSilage' execution", "" );
239  exit( 1 );
240  }
241  }
242  else {
243  if (!m_farm->CutToSilage( m_field, 0.0, m_field->GetMDates(1,0) - g_date->DayInYear())) {
244  SimpleEvent( g_date->Date() + 1, sa_cut_to_silage, true );
245  break;
246  }
247  }
248  }
249 
250  ChooseNextCrop (3);
251 
252  SimpleEvent( g_date->Date() + 1, sa_wait, false );
253  break;
254 
255  case sa_wait:
256  // Cannot terminate too early otherwise will cause a rotation loop
257 
258  if ((g_date->DayInYear()-m_field->GetMDates(1,2))>=0)
259  {
260  //m_farm->Glyphosate(m_field,0.0,0);
261  // Special for set-aside:
262  m_field->SetVegPatchy( false );
263  done = true;
264  }
265  else // queue this up again
266  SimpleEvent( g_date->Date() + 1, sa_wait, true );
267  break;
268 
269  default:
270  g_msg->Warn( WARN_BUG, "SetAside::Do(): "
271  "Unknown event type! ", "" );
272  exit( 1 );
273  }
274 
275  return done;
276 }
277 
278 
279 
280 
281 
sa_start
Definition: setaside.h:49
Farm::IsStockFarmer
bool IsStockFarmer(void)
Definition: farm.h:905
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
Farm::CattleIsOut
virtual bool CattleIsOut(LE *a_field, double a_user, int a_days, int a_max)
Generate a 'cattle_out' event for every day the cattle are on a_field.
Definition: farmfuncs.cpp:1974
Farm::CutToSilage
virtual bool CutToSilage(LE *a_field, double a_user, int a_days)
Cut vegetation for silage on a_field.
Definition: farmfuncs.cpp:2329
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
Farm::GetType
TTypesOfFarm GetType(void)
Definition: farm.h:901
Farm::CutToHay
virtual bool CutToHay(LE *a_field, double a_user, int a_days)
Carry out hay cutting on a_field.
Definition: farmfuncs.cpp:2269
Crop::m_first_date
int m_first_date
Definition: farm.h:540
FarmEvent::m_startday
int m_startday
Definition: farm.h:466
sa_cut_to_hay
Definition: setaside.h:50
Crop::SimpleEvent
void SimpleEvent(long a_date, int a_todo, bool a_lock)
Adds an event to this crop management.
Definition: farm.cpp:307
sa_cattle_is_out
Definition: setaside.h:52
sa_cattle_out
Definition: setaside.h:51
Crop::m_farm
Farm * m_farm
Definition: farm.h:537
Crop::m_field
LE * m_field
Definition: farm.h:538
sa_cut_to_silage
Definition: setaside.h:53
SetAside::Do
bool Do(Farm *a_farm, LE *a_field, FarmEvent *a_ev)
The one and only method for a crop management plan. All farm actions go through here.
Definition: setaside.cpp:86
FarmEvent::m_todo
int m_todo
Definition: farm.h:469
sa_wait
Definition: setaside.h:54
Crop::m_last_date
int m_last_date
Definition: farm.h:542
Farm
The base class for all farm types.
Definition: farm.h:767
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
Farm::CattleOut
virtual bool CattleOut(LE *a_field, double a_user, int a_days)
Start a grazing event on a_field today.
Definition: farmfuncs.cpp:1910