ALMaSS Rabbit ODdox  1.00
The rabbit model description following ODdox protocol
Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
Pesticide Class Reference

#include <pesticide.h>

Public Member Functions

void Tick (void)
 
void DailyQueueAdd (LE *a_element_sprayed, double a_amount)
 
bool GetAnythingToDecay ()
 
double SupplyPesticide (int a_x, int a_y)
 
double SupplyPesticide (int a_polyref)
 
 Pesticide (RasterMap *a_land, Landscape *a_map)
 
virtual ~Pesticide (void)
 
bool SavePPM (double *a_map, int a_beginx, int a_width, int a_beginy, int a_height, char *a_filename)
 
void DiffusionMaskInitTest (void)
 

Protected Member Functions

void DailyQueueClear (void)
 
void DailyQueueProcess (void)
 
bool ElementIsWater (int a_x, int a_y)
 
void MainMapDecay (void)
 
void TwinMapClear (int a_minx, int a_miny, int a_maxx, int a_maxy)
 
void TwinMapSpray (LE *a_element_spryaed, double a_amount, int a_minx, int a_miny, int a_maxx, int a_maxy)
 
void TwinMapSprayPixel (int a_large_map_x, int a_large_map_y, double a_fractional_amount)
 
void TwinMapSprayCorrectBorders (void)
 
void TwinMapDiffusion (int a_minx, int a_miny, int a_maxx, int a_maxy, double a_cover)
 
void DiffusionMaskInit (void)
 
double DiffusionFunction (double a_dist_meters)
 
void DiffusionSprayPixel (int a_x, int a_limit_x, int a_y, int a_limit_y, double a_amount, double a_cover)
 
void CalcRainWashOffFactors ()
 Pre-calculates the constants required for rain wash off with increasing rainfall and stores this in m_RainWashoffFactor. More...
 

Protected Attributes

bool m_something_to_decay
 
int m_x_excess
 
int m_y_excess
 
double m_prop
 
double m_corr_x
 
double m_corr_y
 
int m_wind
 
double m_pest_daily_decay_frac
 
double m_pest_daily_decay_frac_Veg
 
double m_pest_daily_decay_frac_Soil
 
RasterMapm_land
 
Landscapem_map
 
double * m_pest_map_main
 
double * m_pest_map_twin
 
unsigned int m_pest_map_size
 
unsigned int m_pest_map_width
 
unsigned int m_pest_map_height
 
double m_RainWashoffFactor [10000]
 a structure to hold pre-calculated pesticide rain wash off factor (Rw) More...
 
unsigned m_rainfallcategory
 Daily rainfall saved here * 100 to use as an indext to the Pesticide::m_RainWashoffFactor array - an optimisation to stop repeated calls to Landscape::SupplyRain. More...
 
Diffusion_mask m_diffusion_mask [4]
 Pre-calculated square diffusion map, assuming wind directions (4)
Used after spraying an element in the pesticide map to determine how much of the sprayed material spreads into the surroundings. More...
 
vector< PesticideEvent * > m_daily_spray_queue
 

Detailed Description

Definition at line 107 of file pesticide.h.

Constructor & Destructor Documentation

Pesticide::Pesticide ( RasterMap a_land,
Landscape a_map 
)

For vegetation fraction, the decay is based on ln(2)/DT50

For soil fraction, the decay is based on 10^(log10(0.5) /DT50)

Definition at line 490 of file pesticide.cpp.

References CalcRainWashOffFactors(), DiffusionMaskInit(), DiffusionMaskInitTest(), g_msg, l_pest_ai_half_life, l_pest_ai_half_life_Soil, l_pest_ai_half_life_Veg, l_pest_enable_pesticide_engine, m_corr_x, m_corr_y, m_land, m_map, m_pest_daily_decay_frac, m_pest_daily_decay_frac_Soil, m_pest_daily_decay_frac_Veg, m_pest_map_height, m_pest_map_main, m_pest_map_size, m_pest_map_twin, m_pest_map_width, m_prop, m_something_to_decay, m_x_excess, m_y_excess, RasterMap::MapHeight(), RasterMap::MapWidth(), PEST_GRIDAREA, PEST_GRIDSIZE, PEST_GRIDSIZE_POW2, CfgFloat::value(), CfgBool::value(), MapErrorMsg::Warn(), and WARN_FATAL.

491 {
493  {
494  m_map = a_map;
495  m_land = a_land;
496  m_something_to_decay = false;
497 
498  // Figure out critical border coordinates,
499  // proportional fractions etc.
500  m_prop = 1.0 / ((double)(PEST_GRIDAREA));
502  if ( m_x_excess ) {
503  m_corr_x = (double)PEST_GRIDSIZE /(double)m_x_excess;
504  }
506  if ( m_y_excess ) {
507  m_corr_y = (double)PEST_GRIDSIZE / (double)m_y_excess;
508  }
509 
511  if ( m_land->MapWidth() & (PEST_GRIDSIZE-1))
513 
515  if ( m_land->MapHeight() & (PEST_GRIDSIZE-1))
517 
519 
520  m_pest_map_twin = (double*)malloc(sizeof(double)* m_pest_map_size);
521 
522 #ifdef __DETAILED_PESTICIDE_FATE
523  m_pest_map_vegcanopy = (double*)malloc(sizeof(double)* m_pest_map_size);
524  m_pest_map_soil = (double*)malloc(sizeof(double)* m_pest_map_size);
525  if (l_pest_enable_pesticide_engine.value() && ((m_pest_map_twin == NULL) || (m_pest_map_vegcanopy == NULL) || (m_pest_map_soil == NULL)))
526  {
527  g_msg->Warn(WARN_FATAL,"Pesticide::Pesticide(): Out of memory.", "" );
528  exit(1);
529  }
530 #else
531  m_pest_map_main = (double*)malloc(sizeof(double)* m_pest_map_size);
532  if (l_pest_enable_pesticide_engine.value() && ((m_pest_map_twin == NULL) || (m_pest_map_main == NULL)))
533  {
534  g_msg->Warn(WARN_FATAL,"Pesticide::Pesticide(): Out of memory.", "" );
535  exit(1);
536  }
537 #endif
538  for ( unsigned int i=0; i<m_pest_map_size; i++ ) {
539 #ifdef __DETAILED_PESTICIDE_FATE
540  m_pest_map_vegcanopy[i] = 0.0;
541  m_pest_map_soil[i] = 0.0;;
542 #else
543  m_pest_map_main[i] = 0.0;
544 #endif
545  m_pest_map_twin[i] = 0.0;
546  }
547 
548  m_pest_daily_decay_frac = pow(10.0, log10(0.5) / l_pest_ai_half_life.value());
550 #ifdef __BORLANDC__
552 #else
553  m_pest_daily_decay_frac_Veg = log(2.0)/l_pest_ai_half_life_Veg.value();
554 #endif
555 
556  m_pest_daily_decay_frac_Soil = pow(10.0, log10(0.5) / l_pest_ai_half_life_Soil.value());
557  // This calculates
561  }
562 }
static CfgFloat l_pest_ai_half_life_Soil("PEST_AI_HALF_LIFE_SOIL", CFG_CUSTOM, 10.0)
CfgBool l_pest_enable_pesticide_engine("PEST_ENABLE_PESTICIDE_ENGINE", CFG_CUSTOM, false)
int MapWidth(void)
Definition: rastermap.h:57
unsigned int m_pest_map_width
Definition: pesticide.h:178
double m_pest_daily_decay_frac_Soil
Definition: pesticide.h:160
void DiffusionMaskInit(void)
Definition: pesticide.cpp:295
int MapHeight(void)
Definition: rastermap.h:58
RasterMap * m_land
Definition: pesticide.h:163
int m_x_excess
Definition: pesticide.h:149
#define PEST_GRIDSIZE_POW2
Turns on code for detailed pesticide fate handling.
Definition: pesticide.h:42
double m_prop
Definition: pesticide.h:151
double * m_pest_map_twin
Definition: pesticide.h:176
static CfgFloat l_pest_ai_half_life("PEST_AI_HALF_LIFE", CFG_CUSTOM, 10.0)
double value(void)
Definition: configurator.h:107
void CalcRainWashOffFactors()
Pre-calculates the constants required for rain wash off with increasing rainfall and stores this in m...
Definition: pesticide.cpp:565
double m_pest_daily_decay_frac_Veg
Definition: pesticide.h:159
class MapErrorMsg * g_msg
Definition: maperrormsg.cpp:38
bool value(void)
Definition: configurator.h:123
void DiffusionMaskInitTest(void)
Definition: pesticide.cpp:618
int m_y_excess
Definition: pesticide.h:150
#define PEST_GRIDSIZE
Definition: pesticide.h:43
double m_corr_x
Definition: pesticide.h:152
static CfgFloat l_pest_ai_half_life_Veg("PEST_AI_HALF_LIFE_VEG", CFG_CUSTOM, 10.0)
unsigned int m_pest_map_size
Definition: pesticide.h:177
bool m_something_to_decay
Definition: pesticide.h:144
unsigned int m_pest_map_height
Definition: pesticide.h:179
void Warn(MapErrorState a_level, std::string a_msg1, std::string a_msg2)
Definition: maperrormsg.cpp:56
Landscape * m_map
Definition: pesticide.h:166
double m_pest_daily_decay_frac
Definition: pesticide.h:158
double * m_pest_map_main
Definition: pesticide.h:174
double m_corr_y
Definition: pesticide.h:153
#define PEST_GRIDAREA
Definition: pesticide.h:44
Pesticide::~Pesticide ( void  )
virtual

Definition at line 587 of file pesticide.cpp.

References DailyQueueClear(), l_pest_enable_pesticide_engine, m_diffusion_mask, m_pest_map_main, m_pest_map_twin, and CfgBool::value().

588 {
589 #ifdef __DETAILED_PESTICIDE_FATE
591  free( m_pest_map_soil );
592  free(m_pest_map_vegcanopy);
593  }
594 #else
596  free( m_pest_map_main );
597  }
598 #endif
600  free( m_pest_map_twin );
601  //free( m_pest_map_mask );
602  }
603 
604  for (int w=0; w<4; w++)
605  {
606  for ( unsigned int i=0; i<m_diffusion_mask[w].size(); i++ )
607  {
608  delete m_diffusion_mask[w][i];
609  }
610  m_diffusion_mask[w].resize(0);
611  }
612  DailyQueueClear();
613 }
CfgBool l_pest_enable_pesticide_engine("PEST_ENABLE_PESTICIDE_ENGINE", CFG_CUSTOM, false)
void DailyQueueClear(void)
Definition: pesticide.cpp:93
double * m_pest_map_twin
Definition: pesticide.h:176
Diffusion_mask m_diffusion_mask[4]
Pre-calculated square diffusion map, assuming wind directions (4) Used after spraying an element in...
Definition: pesticide.h:188
bool value(void)
Definition: configurator.h:123
double * m_pest_map_main
Definition: pesticide.h:174

Member Function Documentation

void Pesticide::CalcRainWashOffFactors ( )
protected

Pre-calculates the constants required for rain wash off with increasing rainfall and stores this in m_RainWashoffFactor.

Calculates the proportion of pesticide that is washed off the canopy for 0.1 to 10mm of rain and for 0 to 100% cover in 1% steps.

Definition at line 565 of file pesticide.cpp.

References m_RainWashoffFactor.

Referenced by Pesticide().

566 {
570  double rainsteps = 0.1; // mm, multiply rainfall by 100 to get this, save result as integer
571  double coversteps = 1.0; // %, multiply cover by 100 to get this, save result as integer
572  for (int i = 0; i < 100; i++)
573  {
574  double SC = i * coversteps;
575  double LAI = log(0 - (1 - SC))*1.666666667; // This is the inverse of Beer's Law
576  for (int r = 0; r < 100; r++)
577  {
578  double P = r * rainsteps;
579  double Pi = LAI*(1 - (1 / ((1 + SC * P) / LAI)));
580  double Rw = 0.25*(SC * P - Pi); // Rw is a proportion of canopy pesticide washed off.
581  m_RainWashoffFactor[r * 100 + i] = Rw;
582  }
583  }
584 }
double m_RainWashoffFactor[10000]
a structure to hold pre-calculated pesticide rain wash off factor (Rw)
Definition: pesticide.h:182
void Pesticide::DailyQueueAdd ( LE a_element_sprayed,
double  a_amount 
)

Definition at line 105 of file pesticide.cpp.

References m_daily_spray_queue.

Referenced by Orchard::DoDevelopment(), OrchardBand::DoDevelopment(), Farm::ProductApplication0(), Farm::ProductApplication1(), and Farm::Trial_PesticideTreat_DateLimited().

106 {
107  PesticideEvent *l_event = new PesticideEvent( a_element_sprayed, a_amount );
108 
109  m_daily_spray_queue.resize( m_daily_spray_queue.size() + 1 );
111  l_event;
112 }
vector< PesticideEvent * > m_daily_spray_queue
Definition: pesticide.h:191
void Pesticide::DailyQueueClear ( void  )
protected

Empties and resets the pesticide action queue. On calling any event not yet carried out will be deleted.

Definition at line 93 of file pesticide.cpp.

References m_daily_spray_queue.

Referenced by Tick(), and ~Pesticide().

94 {
98  for ( unsigned int i=0; i<m_daily_spray_queue.size(); i++ ) {
99  delete m_daily_spray_queue[i];
100  }
101  m_daily_spray_queue.resize( 0 );
102 }
vector< PesticideEvent * > m_daily_spray_queue
Definition: pesticide.h:191
void Pesticide::DailyQueueProcess ( void  )
protected

If we are spraying at least one field. Force the main pesticide map which forces the decay method to run tomorrow. First we add the amount in m_amount to the twin map (all squares covered with the polygon get m_amount added) using TwinMapSpray
Next this twin map is added to the main map and if necessary it is here we sort out the allocation between vegetation canopy and soil fractions. This is done by TwinMapDiffusion

Definition at line 115 of file pesticide.cpp.

References m_daily_spray_queue, m_something_to_decay, m_wind, Landscape::SupplyWindDirection(), TwinMapClear(), TwinMapDiffusion(), and TwinMapSpray().

Referenced by Tick().

116 {
123  if (0 == m_daily_spray_queue.size())
124  // Event queue empty, nobody sprayed anything today.
125  return;
126 
127  // Spraying at least one field. Force the main pesticide map
128  // decay method to run tomorrow.
129  m_something_to_decay = true;
130 
131  for ( unsigned int i=0; i<m_daily_spray_queue.size(); i++ )
132  {
134  int minx=m_daily_spray_queue[i]->m_sprayed_elem->GetMinX();
135  int maxx=m_daily_spray_queue[i]->m_sprayed_elem->GetMaxX();
136  int miny=m_daily_spray_queue[i]->m_sprayed_elem->GetMinY();
137  int maxy=m_daily_spray_queue[i]->m_sprayed_elem->GetMaxY();
138  // For cover we use the crop, and save this for later
139  double cover = m_daily_spray_queue[i]->m_sprayed_elem->GetVegCover();
140  TwinMapClear(minx, miny, maxx, maxy);
141  // Add the amount in m_amount to the twin map (all squares covered with the polygon get m_amount added.
142  TwinMapSpray( m_daily_spray_queue[i]->m_sprayed_elem, m_daily_spray_queue[i]->m_amount, minx, miny, maxx, maxy);
143  // This adds it to the main map and if necessary sorts out the allocation between veg and soil.
144  TwinMapDiffusion(minx, miny, maxx, maxy, cover);
145  }
146 }
void TwinMapClear(int a_minx, int a_miny, int a_maxx, int a_maxy)
Definition: pesticide.cpp:149
void TwinMapDiffusion(int a_minx, int a_miny, int a_maxx, int a_maxy, double a_cover)
Definition: pesticide.cpp:250
int SupplyWindDirection(void)
Definition: landscape.h:1349
int m_wind
Definition: pesticide.h:154
vector< PesticideEvent * > m_daily_spray_queue
Definition: pesticide.h:191
Landscape * g_land
void TwinMapSpray(LE *a_element_spryaed, double a_amount, int a_minx, int a_miny, int a_maxx, int a_maxy)
Definition: pesticide.cpp:162
bool m_something_to_decay
Definition: pesticide.h:144
double Pesticide::DiffusionFunction ( double  a_dist_meters)
protected

The equation provided here is the one that determines the drift of pesticides with distance. It is important that if the drift is set to zero that the result of the equation is unity.

Definition at line 412 of file pesticide.cpp.

References l_pest_diffusion_slope, l_pest_zero_threshold, and CfgFloat::value().

Referenced by DiffusionMaskInit().

413 {
414  double pp;
419 // y=(2.753767)*(x+(1.86976))**(-2.121563)
420 #ifdef __WithinOrchardPesticideSim__
421  if (a_dist_meters==0) pp=0.7784;
422  else pp=0.0277;
423 #else
424 // pp=2.753767 * pow(( a_dist_meters+1.86976 ), -2.121563);
425  pp= exp( l_pest_diffusion_slope.value() * a_dist_meters );
426  //pp=pow(( a_dist_meters+1 ), l_pest_diffusion_slope.value() );
427  //pp = (2.7593 * pow(a_dist_meters,-0.9778)) * 0.001;
428  if (pp<(l_pest_zero_threshold.value()/10)) pp=0; // Don't bother with the little ones
429 #endif
430  return pp;
431 }
double value(void)
Definition: configurator.h:107
static CfgFloat l_pest_diffusion_slope("PEST_DRIFT_SLOPE", CFG_CUSTOM,-0.6122)
static CfgFloat l_pest_zero_threshold("PEST_ZERO_THRESHOLD", CFG_CUSTOM, 0.00001)
void Pesticide::DiffusionMaskInit ( void  )
protected

l_pest_diffusion_grid_count contains the number of grid points to consider e.g. 1 will be a grid of 9 squares centred at the spray point, 2 will be 25 squares (2*2+1)^2 , 3 will be 49, etc..
The proportion of the applicationcation rate assuming it was sprayed in the centre square is calculated for each surrounding square. Wind direction is taken into account and the mask is created for four wind directions and saved.

Definition at line 295 of file pesticide.cpp.

References DiffusionFunction(), l_pest_diffusion_grid_count, m_diffusion_mask, and CfgInt::value().

Referenced by Pesticide().

296 {
304  int l_grid = l_pest_diffusion_grid_count.value();
305  const int l_side_length = l_grid * 2 + 1;
306  double* l_diff;
307  l_diff = new double[l_side_length];
308  int cells = 1;
309  double sum = 1.0;
310  l_diff[0] = 1.0;
311  for (int l=1; l<l_side_length; l++)
312  {
313  l_diff[l] = DiffusionFunction(l);
314  sum += l_diff[l];
315  }
316  for (int l=0; l<l_side_length; l++)
317  {
318  l_diff[l] /= sum;
319  l_diff[l] /= cells;
320  cells += 2; // 2 more cells per row away from centre square
321  }
322  // Calculated for 4 wind directions
323  for (int wind=0; wind < 4; wind ++)
324  {
325  m_diffusion_mask[wind].resize( l_side_length * l_side_length );
326  for ( int x = 0; x< l_side_length; x++ )
327  {
328  for ( int y= 0; y< l_side_length; y++ )
329  {
330  m_diffusion_mask[wind][x + y * l_side_length] = new Diffusor( x, y, 0); // first zero all values
331  }
332  }
333  }
334  int strtx = l_grid;
335  int strty = l_grid;
336  int fin = 1;
337  // North
338  for (int step = 0; step <= l_grid; step++)
339  {
340  for (int cc=0; cc<fin; cc++)
341  {
342  m_diffusion_mask[0][ strtx + (cc-step) + ((strty-step)*l_side_length)]->SetFraction(l_diff[step]);
343  }
344  fin += 2;
345  }
346  // South
347  fin = 1;
348  for (int step = 0; step <= l_grid; step++)
349  {
350  for (int cc=0; cc<fin; cc++)
351  {
352  m_diffusion_mask[2][ strtx + (cc-step) + ((strty+step)*l_side_length)]->SetFraction(l_diff[step]);
353  }
354  fin += 2;
355  }
356  // East
357  fin = 1;
358  for (int step = 0; step <= l_grid; step++)
359  {
360  for (int cc=0; cc<fin; cc++)
361  {
362  m_diffusion_mask[3][ (strtx + step) + ((strty+(cc-step))*l_side_length)]->SetFraction(l_diff[step]);
363  }
364  fin += 2;
365  }
366  // West
367  fin = 1;
368  for (int step = 0; step <= l_grid; step++)
369  {
370  for (int cc=0; cc<fin; cc++)
371  {
372  m_diffusion_mask[1][ (strtx - step) + ((strty+(cc-step))*l_side_length)]->SetFraction(l_diff[step]);
373  }
374  fin += 2;
375  }
376 
377  delete[] l_diff;
378 }
Diffusion_mask m_diffusion_mask[4]
Pre-calculated square diffusion map, assuming wind directions (4) Used after spraying an element in...
Definition: pesticide.h:188
double DiffusionFunction(double a_dist_meters)
Definition: pesticide.cpp:412
int value(void)
Definition: configurator.h:92
static CfgInt l_pest_diffusion_grid_count("PEST_DIFFUSION_GRID_COUNT", CFG_CUSTOM, 1)
void Pesticide::DiffusionMaskInitTest ( void  )

Definition at line 618 of file pesticide.cpp.

References l_pest_diffusion_grid_count, m_diffusion_mask, and CfgInt::value().

Referenced by Pesticide().

619 {
620  int l_grid = l_pest_diffusion_grid_count.value();
621  const int l_side_length = l_grid * 2 + 1;
622 
623  // Need a debug test, output all diffusion masks to file
624  ofstream ofile("diffusionmask.txt",ios::out);
625  for (int i=0; i<4; i++)
626  {
627  for ( int x = 0; x< l_side_length; x++ )
628  {
629  for ( int y= 0; y< l_side_length; y++ )
630  {
631  ofile << m_diffusion_mask[i][x+(y*l_side_length)]->GetFraction() << '\t';
632  }
633  ofile << endl;
634  }
635  ofile << endl;
636  ofile << endl;
637  }
638  ofile.close();
639  }
Diffusion_mask m_diffusion_mask[4]
Pre-calculated square diffusion map, assuming wind directions (4) Used after spraying an element in...
Definition: pesticide.h:188
int value(void)
Definition: configurator.h:92
static CfgInt l_pest_diffusion_grid_count("PEST_DIFFUSION_GRID_COUNT", CFG_CUSTOM, 1)
void Pesticide::DiffusionSprayPixel ( int  a_x,
int  a_limit_x,
int  a_y,
int  a_limit_y,
double  a_amount,
double  a_cover 
)
inlineprotected

This sprays the pesticide (a_amount) by placing this into a pesticide cell in the main map. If more detailed pesticide fate is needed then a_amount will be partitioned between soil and canopy.
First a test is made to ensure that the coordinates given are within the landscape. If not the pesticide is sprayed off world, and lost.
Partioning, if occuring, is done based on two components - the canopy and the soil. The pesticide is partioned between the two based on the asssumed vegetation cover of the crop based on Beer's Law.

Definition at line 272 of file pesticide.cpp.

References m_pest_map_main.

Referenced by TwinMapDiffusion().

273 {
281  // First we have to do the typical out of bounds checks - if these fail do nothing, the pesticide fell off the world
282  if (a_x < 0 || a_x >= a_limit_x || a_y < 0 || a_y >= a_limit_y) return;
283  // Now calculate the coordinate entry in the array and store this as l_coord
284  int l_coord = a_y * a_limit_x + a_x;
285 #ifdef __DETAILED_PESTICIDE_FATE
286  // Here we need to calculate the partition of pesticide into two compartments.
287  m_pest_map_vegcanopy[l_coord] += a_amount * a_cover;
288  m_pest_map_soil[l_coord] += a_amount - m_pest_map_vegcanopy[l_coord];
289 #else
290  m_pest_map_main[l_coord] += a_amount;
291 #endif
292 }
double * m_pest_map_main
Definition: pesticide.h:174
bool Pesticide::ElementIsWater ( int  a_x,
int  a_y 
)
inlineprotected

Definition at line 254 of file pesticide.h.

References PEST_GRIDSIZE_POW2, tole_FishFarm, tole_Freshwater, tole_Pond, tole_River, and tole_Saltwater.

255 {
256  TTypesOfLandscapeElement l_eletype =
257  m_map->SupplyElementType( a_x, a_y );
258 
259  if ( l_eletype == tole_Freshwater ||
260  l_eletype == tole_River ||
261  l_eletype == tole_Pond ||
262  l_eletype == tole_FishFarm ||
263  l_eletype == tole_Saltwater
264  )
265  return true;
266 
267  return false;
268 }
TTypesOfLandscapeElement SupplyElementType(int a_polyref)
Definition: landscape.h:1031
Landscape * m_map
Definition: pesticide.h:166
TTypesOfLandscapeElement
bool Pesticide::GetAnythingToDecay ( )
inline

Definition at line 219 of file pesticide.h.

Referenced by Landscape::SupplyPesticideDecay().

219 { return (m_something_to_decay); }
bool m_something_to_decay
Definition: pesticide.h:144
void Pesticide::MainMapDecay ( void  )
protected

This is where the environmental decay takes place. Here we assume a first order decay based on a daily proportion of the cell total. If using detailed fate modelling then is calculation is more complex.

This is where the environmental decay takes place. Here we assume a first order decay based on a daily proportion of the cell total. If using detailed fate modelling then is calculation is more complex.

Definition at line 434 of file pesticide.cpp.

References g_landscape_p, l_pest_zero_threshold, m_pest_daily_decay_frac, m_pest_daily_decay_frac_Soil, m_pest_daily_decay_frac_Veg, m_pest_map_main, m_pest_map_size, m_pest_map_width, m_rainfallcategory, m_RainWashoffFactor, m_something_to_decay, PEST_GRIDSIZE_POW2, Landscape::SupplyVegCover(), and CfgFloat::value().

Referenced by Tick().

435 {
436  if ( ! m_something_to_decay ) return;
441  double l_zero = l_pest_zero_threshold.value();
442  m_something_to_decay = false;
443  for ( unsigned int i=0; i<m_pest_map_size; i++ )
444  {
445 #ifdef __DETAILED_PESTICIDE_FATE
446  if ((m_pest_map_vegcanopy[i] > l_zero) )
447  {
448  //Calculate wash-off m_pest_map_width * m_pest_map_height y * m_pest_map_width + x
449  int x = ( i % m_pest_map_width ) << PEST_GRIDSIZE_POW2;
450  int y = ( i / m_pest_map_width ) << PEST_GRIDSIZE_POW2;
451  double cover = g_landscape_p->SupplyVegCover(x,y);
452  unsigned cov = 100 * cover; // Cover is steps of zero to 99, may need to check for bounds here (may get cover of 1.0 ?)
453  double Rwp = m_pest_map_vegcanopy[i] *= m_RainWashoffFactor[m_rainfallcategory+cov]; // m_RainWashoffFactor is the index to the array
454  m_pest_map_soil[i] = (m_pest_map_soil[i] + Rwp) * m_pest_daily_decay_frac_Soil;
455  m_pest_map_vegcanopy[i] -= Rwp;
456  m_pest_map_vegcanopy[i] *= m_pest_daily_decay_frac_Veg;
457  m_something_to_decay = true;
458  }
459  else
460  {
461  if (m_pest_map_soil[i] > l_zero)
462  {
463  m_pest_map_soil[i] = m_pest_map_soil[i] * m_pest_daily_decay_frac_Soil;
464  m_something_to_decay = true;
465  }
466  else
467  {
468  m_pest_map_vegcanopy[i] = 0.0;
469  m_pest_map_soil[i] = 0.0;
470  }
471 #else
472  if (m_pest_map_main[i] > l_zero)
473  {
479  m_something_to_decay = true;
480  }
481  else
482  {
483  m_pest_map_main[i] = 0.0;
484  }
485 #endif
486  }
487 }
unsigned int m_pest_map_width
Definition: pesticide.h:178
double m_pest_daily_decay_frac_Soil
Definition: pesticide.h:160
double m_RainWashoffFactor[10000]
a structure to hold pre-calculated pesticide rain wash off factor (Rw)
Definition: pesticide.h:182
#define PEST_GRIDSIZE_POW2
Turns on code for detailed pesticide fate handling.
Definition: pesticide.h:42
double value(void)
Definition: configurator.h:107
double m_pest_daily_decay_frac_Veg
Definition: pesticide.h:159
unsigned m_rainfallcategory
Daily rainfall saved here * 100 to use as an indext to the Pesticide::m_RainWashoffFactor array - an ...
Definition: pesticide.h:184
double SupplyVegCover(int a_polyref)
Definition: landscape.h:969
unsigned int m_pest_map_size
Definition: pesticide.h:177
bool m_something_to_decay
Definition: pesticide.h:144
double m_pest_daily_decay_frac
Definition: pesticide.h:158
double * m_pest_map_main
Definition: pesticide.h:174
static CfgFloat l_pest_zero_threshold("PEST_ZERO_THRESHOLD", CFG_CUSTOM, 0.00001)
class Landscape * g_landscape_p
Definition: Landscape.cpp:238
bool Pesticide::SavePPM ( double *  a_map,
int  a_beginx,
int  a_width,
int  a_beginy,
int  a_height,
char *  a_filename 
)

Definition at line 651 of file pesticide.cpp.

References g_msg, m_pest_map_height, m_pest_map_width, SV_UINT32, SV_UINT8, MapErrorMsg::Warn(), and WARN_FATAL.

655 {
656  a_beginx = 0;
657  a_width = m_pest_map_width;
658  a_beginy = 0;
659  a_height = m_pest_map_height;
660 
661  SV_UINT32 linesize = a_width*3;
662  SV_UINT8* linebuffer = (SV_UINT8*)malloc(sizeof(SV_UINT8)* linesize);
663 
664  if ( linebuffer == NULL ) {
666  "Pesticide::SavePPM(): Out of memory!", "" );
667  exit(1);
668  }
669 
670  FILE* l_file;
671  l_file=fopen(a_filename, "w" );
672  if ( !l_file ) {
673  printf("PesticideTest::SavePPM(): "
674  "Unable to open file for writing: %s\n",
675  a_filename );
676  exit(1);
677  }
678 
679  fprintf( l_file, "P6\n%d %d %d\n",
680  a_width,
681  a_height,
682  255 );
683 
684  for ( int line=a_beginy; line< a_beginy + a_height; line++ ) {
685  int i = 0;
686  for ( int column=a_beginx; column < a_beginx + a_width; column++ ) {
687  int localcolor = (int)( a_map[ line * m_pest_map_width + column ]
688  * 255.0);
689  if ( localcolor <= 255 ) {
690  linebuffer [ i++ ] = char (localcolor & 0xff);
691  linebuffer [ i++ ] = 0;
692  linebuffer [ i++ ] = 0;
693  } else {
694  linebuffer [ i++ ] = 255;
695  localcolor -= 255;
696  if ( localcolor <= 255 ) {
697  linebuffer [ i++ ] = char (localcolor);
698  linebuffer [ i++ ] = 0;
699  } else {
700  linebuffer [ i++ ] = 255;
701  localcolor -= 255;
702  if ( localcolor <= 255 ) {
703  linebuffer [ i++ ] = char (localcolor);
704  } else {
705  linebuffer [ i++ ] = 255;
706  }
707  }
708  }
709  }
710  fwrite( linebuffer, sizeof(SV_UINT8), linesize, l_file );
711  }
712 
713  fclose( l_file );
714  free( linebuffer );
715  return true;
716 }
#define SV_UINT8
Definition: pesticide.cpp:648
unsigned int m_pest_map_width
Definition: pesticide.h:178
#define SV_UINT32
Definition: pesticide.cpp:646
class MapErrorMsg * g_msg
Definition: maperrormsg.cpp:38
unsigned int m_pest_map_height
Definition: pesticide.h:179
void Warn(MapErrorState a_level, std::string a_msg1, std::string a_msg2)
Definition: maperrormsg.cpp:56
double Pesticide::SupplyPesticide ( int  a_x,
int  a_y 
)
inline
Parameters
a_xthe x-coord in landscape x units
a_ythe y-coord in landscape x units
Returns
Returns the value of the pesticide grid cell containing a_x,a_y

Definition at line 320 of file pesticide.h.

References PEST_GRIDSIZE_POW2.

Referenced by Landscape::SupplyPesticide(), Landscape::SupplyPesticideP(), and Landscape::SupplyPesticideS().

321 {
327 #ifdef PEST_WATER_CHECK
328  if (ElementIsWater(a_x, a_y))
329  return 0.0;
330 #endif
331 
332  int l_x = a_x >> PEST_GRIDSIZE_POW2;
333  int l_y = a_y >> PEST_GRIDSIZE_POW2;
334 
335  return m_pest_map_main[l_y * m_pest_map_width + l_x];
336 }
unsigned int m_pest_map_width
Definition: pesticide.h:178
#define PEST_GRIDSIZE_POW2
Turns on code for detailed pesticide fate handling.
Definition: pesticide.h:42
bool ElementIsWater(int a_x, int a_y)
Definition: pesticide.h:254
double * m_pest_map_main
Definition: pesticide.h:174
double Pesticide::SupplyPesticide ( int  a_polyref)
inline

Definition at line 338 of file pesticide.h.

339 {
340  // This is an approximation because we have no idea about the actual variation
341  // in pesticide concentrations within the polygon.
342  int l_c = m_map->SupplyPesticideCell(a_ele);
343  return m_pest_map_main[l_c];
344 }
int SupplyPesticideCell(int a_polyref)
Definition: landscape.h:1394
Landscape * m_map
Definition: pesticide.h:166
double * m_pest_map_main
Definition: pesticide.h:174
void Pesticide::Tick ( void  )

Definition at line 75 of file pesticide.cpp.

References DailyQueueClear(), DailyQueueProcess(), l_pest_enable_pesticide_engine, m_rainfallcategory, MainMapDecay(), Landscape::SupplyRain(), and CfgBool::value().

Referenced by Landscape::Tick().

76 {
77  // Get todays rainfall
78  m_rainfallcategory = (unsigned) floor(g_land->SupplyRain() * 100 + 0.5);
79  if (m_rainfallcategory >= 100) m_rainfallcategory = 99;
80  // Now make it an index to the 100x100 array.
81  m_rainfallcategory *= 100;
83  {
85  return;
86  }
87  MainMapDecay();
90 }
CfgBool l_pest_enable_pesticide_engine("PEST_ENABLE_PESTICIDE_ENGINE", CFG_CUSTOM, false)
void DailyQueueClear(void)
Definition: pesticide.cpp:93
bool value(void)
Definition: configurator.h:123
unsigned m_rainfallcategory
Daily rainfall saved here * 100 to use as an indext to the Pesticide::m_RainWashoffFactor array - an ...
Definition: pesticide.h:184
double SupplyRain(void)
Definition: landscape.h:1291
void DailyQueueProcess(void)
Definition: pesticide.cpp:115
Landscape * g_land
void MainMapDecay(void)
Definition: pesticide.cpp:434
void Pesticide::TwinMapClear ( int  a_minx,
int  a_miny,
int  a_maxx,
int  a_maxy 
)
protected

Definition at line 149 of file pesticide.cpp.

References m_pest_map_twin, and m_pest_map_width.

Referenced by DailyQueueProcess().

150 {
151  for ( int y=a_miny; y<=a_maxy; y++ )
152  {
153  int t = y * m_pest_map_width;
154  for ( int x=a_minx; x<=a_maxx; x++ )
155  {
156  m_pest_map_twin[t + x] = 0.0;
157  }
158  }
159 }
unsigned int m_pest_map_width
Definition: pesticide.h:178
double * m_pest_map_twin
Definition: pesticide.h:176
void Pesticide::TwinMapDiffusion ( int  a_minx,
int  a_miny,
int  a_maxx,
int  a_maxy,
double  a_cover 
)
protected

Definition at line 250 of file pesticide.cpp.

References DiffusionSprayPixel(), m_diffusion_mask, m_pest_map_height, m_pest_map_twin, m_pest_map_width, and m_wind.

Referenced by DailyQueueProcess().

251 {
252  for ( int y=a_miny; y<a_maxy; y++ )
253  {
254  int t = y*m_pest_map_width;
255  for ( int x=a_minx; x<a_maxx; x++ )
256  {
257  if ( m_pest_map_twin[ t + x ] > 0.0 )
258  {
259  double l_amount = m_pest_map_twin[ t + x ];
260  for ( unsigned int i=0; i<m_diffusion_mask[m_wind].size(); i++ )
261  {
262  // This adds the pesticide to the main map - simply adds the calculated amount.
263  DiffusionSprayPixel( x + m_diffusion_mask[m_wind][i]->Getdx(),m_pest_map_width,y + m_diffusion_mask[m_wind][i]->Getdy(),
264  m_pest_map_height,m_diffusion_mask[m_wind][i]->GetFraction() *l_amount, a_cover);
265  }
266  }
267  }
268  }
269 }
unsigned int m_pest_map_width
Definition: pesticide.h:178
double * m_pest_map_twin
Definition: pesticide.h:176
int m_wind
Definition: pesticide.h:154
Diffusion_mask m_diffusion_mask[4]
Pre-calculated square diffusion map, assuming wind directions (4) Used after spraying an element in...
Definition: pesticide.h:188
unsigned int m_pest_map_height
Definition: pesticide.h:179
void DiffusionSprayPixel(int a_x, int a_limit_x, int a_y, int a_limit_y, double a_amount, double a_cover)
Definition: pesticide.cpp:272
void Pesticide::TwinMapSpray ( LE a_element_spryaed,
double  a_amount,
int  a_minx,
int  a_miny,
int  a_maxx,
int  a_maxy 
)
protected

This is where the initial pesticide concentration is applied to the map. A twin of the real maps is used for spraying the amount of pesticide that is sprayed over each cell and then copied to the real one by using a 'diffusion' process to spread it out to all surrounding cells for drift.

Going through the whole landscape is very slow and unnecessary for small polygons. Since our polygons do not extend beyond the edge of the map ie do not wrap round, then we only need a measure of minx, maxx, miny, maxy. This is set up at the start of the simulation.

Definition at line 162 of file pesticide.cpp.

References RasterMap::Get(), LE::GetMapIndex(), m_land, m_prop, TwinMapSprayCorrectBorders(), and TwinMapSprayPixel().

Referenced by DailyQueueProcess().

163 {
173  /* Replaced with more detailed fate code for EFSA June 2014
174  if (l_pest_use_application_rate.value()) {
175  // We are applying a field rate. The actual residue needs to be calculated here
176  double biomass = a_element_sprayed->GetVegBiomass();
177  double cover = a_element_sprayed->GetVegCover();
178  // rate is in mg/m and needs to be converted to mg/kg
179  double residue = (a_amount/(biomass*0.001)) * 0.435855; // g to kg veg // 0.435855 is a specific calculation to obtain the same residue that Joe Crocker used for the scale of use study
180  a_amount = residue * cover;
181  }
182  */
183  double l_fractional_amount = a_amount * m_prop; // m_prop is a constant related to the grid area (i.e. how many squares are in one grid square).
184  int l_large_map_index = a_element_sprayed->GetMapIndex();
185  /*
186  * Going through the whole landscape is very slow and unnecessary for small polygons.
187  * Since our polygons do not extend beyond the edge of the map
188  * ie do not wrap round, then we only need a measure of minx, maxx, miny, maxy.
189  * This is set up at the start of the simulation.
190  */
191  for ( int y=a_miny; y<=a_maxy; y++ ) {
192  for ( int x=a_minx; x<=a_maxx; x++ ) {
193  if ( m_land->Get( x, y ) == l_large_map_index )
194  {
195  // This adds the l_fractional_amount to the twin map
196  TwinMapSprayPixel( x, y, l_fractional_amount );
197  }
198  }
199  }
201 }
RasterMap * m_land
Definition: pesticide.h:163
double m_prop
Definition: pesticide.h:151
int Get(int a_x, int a_y)
Definition: rastermap.h:86
void TwinMapSprayCorrectBorders(void)
Definition: pesticide.cpp:204
void TwinMapSprayPixel(int a_large_map_x, int a_large_map_y, double a_fractional_amount)
Definition: pesticide.h:348
void Pesticide::TwinMapSprayCorrectBorders ( void  )
protected

Definition at line 204 of file pesticide.cpp.

References m_corr_x, m_corr_y, m_pest_map_height, m_pest_map_size, m_pest_map_twin, m_pest_map_width, m_x_excess, m_y_excess, and PEST_GRIDAREA.

Referenced by TwinMapSpray().

205 {
206  if ( m_x_excess ) {
207  for ( unsigned int i=0; i<m_pest_map_width-1; i++ ) {
208  m_pest_map_twin[ i * m_pest_map_width + m_pest_map_height-1 ] *= m_corr_x;
209  }
210  }
211 
212  if ( m_y_excess ) {
213  unsigned int l_additive = (m_pest_map_height-1)*m_pest_map_width;
214  for ( unsigned int i=0; i<m_pest_map_height-1; i++ ) {
215  m_pest_map_twin[ i + l_additive ] *= m_corr_y;
216  }
217  }
218 
219  if ( m_x_excess && m_y_excess ) {
220  m_pest_map_twin[ m_pest_map_size-1 ] *= (((double)(PEST_GRIDAREA)) / ((double)(m_x_excess*m_y_excess)));
221  }
222 }
unsigned int m_pest_map_width
Definition: pesticide.h:178
int m_x_excess
Definition: pesticide.h:149
double * m_pest_map_twin
Definition: pesticide.h:176
int m_y_excess
Definition: pesticide.h:150
double m_corr_x
Definition: pesticide.h:152
unsigned int m_pest_map_size
Definition: pesticide.h:177
unsigned int m_pest_map_height
Definition: pesticide.h:179
double m_corr_y
Definition: pesticide.h:153
#define PEST_GRIDAREA
Definition: pesticide.h:44
void Pesticide::TwinMapSprayPixel ( int  a_large_map_x,
int  a_large_map_y,
double  a_fractional_amount 
)
inlineprotected

Definition at line 348 of file pesticide.h.

References PEST_GRIDSIZE_POW2.

Referenced by TwinMapSpray().

351 {
352  int l_x = a_large_map_x >> PEST_GRIDSIZE_POW2;
353  int l_y = a_large_map_y >> PEST_GRIDSIZE_POW2;
354 
355  m_pest_map_twin[l_y * m_pest_map_width + l_x] +=
356  a_fractional_amount;
357 }
unsigned int m_pest_map_width
Definition: pesticide.h:178
#define PEST_GRIDSIZE_POW2
Turns on code for detailed pesticide fate handling.
Definition: pesticide.h:42
double * m_pest_map_twin
Definition: pesticide.h:176

Member Data Documentation

double Pesticide::m_corr_x
protected

Definition at line 152 of file pesticide.h.

Referenced by Pesticide(), and TwinMapSprayCorrectBorders().

double Pesticide::m_corr_y
protected

Definition at line 153 of file pesticide.h.

Referenced by Pesticide(), and TwinMapSprayCorrectBorders().

vector<PesticideEvent*> Pesticide::m_daily_spray_queue
protected

Definition at line 191 of file pesticide.h.

Referenced by DailyQueueAdd(), DailyQueueClear(), and DailyQueueProcess().

Diffusion_mask Pesticide::m_diffusion_mask[4]
protected

Pre-calculated square diffusion map, assuming wind directions (4)
Used after spraying an element in the pesticide map to determine how much of the sprayed material spreads into the surroundings.

Definition at line 188 of file pesticide.h.

Referenced by DiffusionMaskInit(), DiffusionMaskInitTest(), TwinMapDiffusion(), and ~Pesticide().

RasterMap* Pesticide::m_land
protected

Definition at line 163 of file pesticide.h.

Referenced by Pesticide(), and TwinMapSpray().

Landscape* Pesticide::m_map
protected

Definition at line 166 of file pesticide.h.

Referenced by Pesticide().

double Pesticide::m_pest_daily_decay_frac
protected

Definition at line 158 of file pesticide.h.

Referenced by MainMapDecay(), and Pesticide().

double Pesticide::m_pest_daily_decay_frac_Soil
protected

Definition at line 160 of file pesticide.h.

Referenced by MainMapDecay(), and Pesticide().

double Pesticide::m_pest_daily_decay_frac_Veg
protected

Definition at line 159 of file pesticide.h.

Referenced by MainMapDecay(), and Pesticide().

unsigned int Pesticide::m_pest_map_height
protected

Definition at line 179 of file pesticide.h.

Referenced by Pesticide(), SavePPM(), TwinMapDiffusion(), and TwinMapSprayCorrectBorders().

double* Pesticide::m_pest_map_main
protected

Definition at line 174 of file pesticide.h.

Referenced by DiffusionSprayPixel(), MainMapDecay(), Pesticide(), and ~Pesticide().

unsigned int Pesticide::m_pest_map_size
protected

Definition at line 177 of file pesticide.h.

Referenced by MainMapDecay(), Pesticide(), and TwinMapSprayCorrectBorders().

double* Pesticide::m_pest_map_twin
protected
unsigned int Pesticide::m_pest_map_width
protected
double Pesticide::m_prop
protected

Definition at line 151 of file pesticide.h.

Referenced by Pesticide(), and TwinMapSpray().

unsigned Pesticide::m_rainfallcategory
protected

Daily rainfall saved here * 100 to use as an indext to the Pesticide::m_RainWashoffFactor array - an optimisation to stop repeated calls to Landscape::SupplyRain.

Definition at line 184 of file pesticide.h.

Referenced by MainMapDecay(), and Tick().

double Pesticide::m_RainWashoffFactor[10000]
protected

a structure to hold pre-calculated pesticide rain wash off factor (Rw)

Definition at line 182 of file pesticide.h.

Referenced by CalcRainWashOffFactors(), and MainMapDecay().

bool Pesticide::m_something_to_decay
protected

Definition at line 144 of file pesticide.h.

Referenced by DailyQueueProcess(), MainMapDecay(), and Pesticide().

int Pesticide::m_wind
protected

Definition at line 154 of file pesticide.h.

Referenced by DailyQueueProcess(), and TwinMapDiffusion().

int Pesticide::m_x_excess
protected

Definition at line 149 of file pesticide.h.

Referenced by Pesticide(), and TwinMapSprayCorrectBorders().

int Pesticide::m_y_excess
protected

Definition at line 150 of file pesticide.h.

Referenced by Pesticide(), and TwinMapSprayCorrectBorders().


The documentation for this class was generated from the following files: