2a3
> #include <vector>
4d4
< #include <cstdlib> /* exit() */
5a6
> #include <cassert>
7d7
< 
9,11d8
< 
< #include "func.h"
< #include "regen_functions.h"
13,14d9
< #include "road.h"
< #include "report.h"
15a11,13
> #include "HarvestAxsConstraints.h"
> #include "Candidate.h"
> 
20c18
<     void derive_percentage_target(int period)
---
>     void derive_percentage_target()
22,24d19
<         ZONE* zone = 0;
<         AU* au = 0;
<         TIMBER_CLASS* timber_class = 0;
26d20
<         double TotalGS = 0.0;
29a24,25
>         int period = pApp->m_currentPeriod;
> 
32d27
<             /* printf("\nderive_percentage_target(): Period(%d)<=pApp->m_lastPeriodTarget(%d) - NO ACTION", period, pApp->m_lastPeriodTarget); */
36c31
<         TotalGS = 0.0;
---
>         double TotalGS = 0.0;
38,40c33,34
<         pApp->m_zoneList=(LIST_PTR *)List::reset(pApp->m_zoneList);
<         zone = (ZONE *)List::next(pApp->m_zoneList);
<         while (zone!= 0)
---
>         typedef vector<ZoneStruct*>::iterator ZI;
>         for (ZI zoneIter = pApp->m_zoneList.begin(); zoneIter != pApp->m_zoneList.end(); ++zoneIter)
42c36
<             if (zone!=pApp->m_zone0)
---
>             if (*zoneIter != pApp->m_zone0)
44,46c38,39
<                 zone->aulist = (LIST_PTR *)List::reset(zone->aulist);
<                 au = static_cast<AU*>(List::next(zone->aulist));
<                 while (au!= 0)
---
>                 typedef vector<AUStruct*>::iterator AI;
>                 for (AI auIter = (*zoneIter)->aulist.begin(); auIter != (*zoneIter)->aulist.end(); ++auIter)
48,50c41,42
<                     au->classlist = (LIST_PTR *)List::reset(au->classlist);
<                     timber_class = (TIMBER_CLASS *)List::next(au->classlist);
<                     while (timber_class!= 0)
---
>                     typedef multimap<int, TimberClassStruct*>::iterator CI;
>                     for (CI classIter = (*auIter)->classlist.begin(); classIter != (*auIter)->classlist.end(); ++classIter)
52c44,52
<                         if (timber_class->class_type==FssimApp::OPERABLE)
---
>                         TimberClassStruct* pCurrentTimberClass = classIter->second;
> 
> #ifdef _TSB_AGE_DEBUG
>                     cout << endl << "derive_percentage_target: age: " << pCurrentTimberClass->age << endl;
> #endif
> 
>                         assert(pCurrentTimberClass->parent_au != 0);
> 
>                         if (pCurrentTimberClass->class_type == GroupDefStruct::OPERABLE)
54c54,55
<                             vph=func_vph(timber_class->parent_au->table, timber_class->age);
---
>                             vph = pCurrentTimberClass->parent_au->table->getVph(pCurrentTimberClass->age);
> 
58c59,60
<                             TotalGS += timber_class->area*vph;
---
> 
>                             TotalGS += pCurrentTimberClass->area * vph;
60d61
<                         timber_class = (TIMBER_CLASS *)List::next(au->classlist);
62d62
<                     au = static_cast<AU*>(List::next(zone->aulist));
65d64
<             zone = (ZONE *)List::next(pApp->m_zoneList);
67d65
< 
69,73c67
<         pApp->m_zone0->target->max_area[period] = FssimApp::DUMMYINPUT;
<         /*
<         printf("\nderive_percentage_target(): Period(%d)>pApp->m_lastPeriodTarget(%d) - RESETTING pApp->m_zone0 TARGET", period, pApp->m_lastPeriodTarget);
<         printf("\nTotalGS: %.2lf; Percent: %.2lf; NewTarget: %.2lf", TotalGS, pApp->m_GSPercentTarget, pApp->m_zone0->target->max_volume[period]);
<         */
---
>         pApp->m_zone0->target->max_area[period] = FssimUtil::DUMMY_INPUT;
76c70,71
<     void harvest_update_activity(TIMBER_CLASS *timber_class, double harea, double vph, int period)
---
> 
>     void harvest_update_group_list(TimberClassStruct* pTimberClass, const double volume, const double area)
78,80c73,74
<         GROUP		*group;
<         double		hvol = 0;
<         AGEDIST		*ad;
---
>         FssimApp* pApp = FssimApp::getApp();
>         int period = pApp->m_currentPeriod;
82c76,89
<         if (timber_class->class_type==FssimApp::INACTIVE) return;
---
>         list<GroupStruct*>* pGroupList = 0;
>         for (int i = 0; i < 2; ++i)
>         {
>             switch (i)
>             {
>                 case 0 : // do float_group_list first
>                     pGroupList = &(pTimberClass->float_group_list);
>                     break;
>                 case 1 : // do static_group_list second
>                     pGroupList = &(pTimberClass->static_group_list);
>                     break;
>                 default : // for loop should never get here
>                     break;
>             }
84,85c91
<         /* Derive harvest volume */
<         hvol = harea*vph;
---
>             assert (0 != pGroupList);
87,90c93,97
<         FssimApp* pApp = FssimApp::getApp();
<         /* Update harvest records */
<         pApp->m_zone0->achieved->volume += hvol;
<         pApp->m_zone0->achieved->area += harea;
---
>             // NOTE: if the map container class were working properly, we wouldn't have to do this check ;-(
>             if (pGroupList->empty())
>             {
>                 continue; // jump to next iteration
>             }
92,97c99,103
< #ifdef _TSB_HARVEST_DEBUG
<         cout << endl << "harvest update activity: harvest area: " << harea
<              << endl << "vph: " << vph
<              << endl << "achieved->volume: " << pApp->m_zone0->achieved->volume
<              << endl << "hvol: " << hvol << endl;
< #endif
---
>             typedef list<GroupStruct*>::iterator GI;
>             for (GI groupIter = pGroupList->begin(); //!pGroupList->empty() &&
>                     groupIter != pGroupList->end(); ++groupIter)
>             {
>                 GroupStruct* pCurrentGroup = (*groupIter);
99,100c105
<         timber_class->parent_zone->achieved->volume += hvol;
<         timber_class->parent_zone->achieved->area += harea;
---
>                 assert (0 != pCurrentGroup->achieved);
102,106c107,108
< #ifdef _TSB_HARVEST_DEBUG
<         cout << endl << "harvest update activity: parent zone area: "
<              << timber_class->parent_zone->achieved->area
<              << endl << "parent zone volume: " << timber_class->parent_zone->achieved->volume << endl;
< #endif
---
>                 pCurrentGroup->achieved->volume += volume;
>                 pCurrentGroup->achieved->area += area;
108,118c110,113
<         timber_class->float_group_list = (LIST_PTR *)List::reset(timber_class->float_group_list);
<         group = (GROUP *)List::next(timber_class->float_group_list);
<         while (group != 0)
<         {
<             group->achieved->volume += hvol;
<             group->achieved->area += harea;
< 
< #ifdef _TSB_HARVEST_DEBUG
<         cout << endl << "harvest update activity: group area: "
<              << group->achieved->area
<              << endl << "group volume: " << group->achieved->volume << endl;
---
> #ifdef _TSB_DEBUG_OFF
>                 cout << endl << "harvest update activity: group area: "
>                      << pCurrentGroup->achieved->area
>                      << endl << "group volume: " << pCurrentGroup->achieved->volume << endl;
121,126c116,118
<             if ( (group->reportFlags!= 0) &&
<                 (period>=group->reportFlags->hage_rep_start) &&
<                 (period<=group->reportFlags->hage_rep_end) )
<             {
<                 ad = (AGEDIST *)List::find(group->achieved->AgeDist, timber_class->age);
<                 if (ad== 0)
---
>                 if ( (pCurrentGroup->reportFlags != 0) &&
>                      (period >= pCurrentGroup->reportFlags->hage_rep_start) &&
>                      (period <= pCurrentGroup->reportFlags->hage_rep_end) )
128,138c120
<                     ad = new AGEDIST;
<                     if (ad == 0)
<                     {
<                         printf("\n\nERROR: harvest_update_activity(): Could not allocate new AGEDIST structure\n\n");
<                         exit(1);
<                     }
<                     ad->age = timber_class->age;
<                     ad->width = timber_class->width;
<                     ad->area = 0.0;
<                     ad->volume = 0.0;
<                     group->achieved->AgeDist = (LIST_PTR *)List::insert(group->achieved->AgeDist, ad, ad->age);
---
>                     harvest_insert_agedist(pTimberClass, &(pCurrentGroup->achieved->AgeDist), volume, area);
140,162d121
<                 // we just assigned: ad->width = timber_class->width, so following should be "else if"
<                 else if ( ad->width != timber_class->width )
<                 {
<                     ad = new AGEDIST;
<                     if (ad == 0)
<                     {
<                         printf("\n\nERROR: harvest_update_activity(): Could not allocate new AGEDIST structure\n\n");
<                         exit(1);
<                     }
<                     ad->age = timber_class->age;
<                     ad->width = timber_class->width;
<                     ad->area = 0.0;
<                     ad->volume = 0.0;
<                     group->achieved->AgeDist = (LIST_PTR *)List::insert(group->achieved->AgeDist, ad, ad->age);
<                 }
<                 ad->area += harea;
<                 ad->volume += hvol;
< 
< #ifdef _TSB_HARVEST_DEBUG
<                 cout << endl << "harvest update activity: agedist area: "
<                      << ad->area << endl << "agedist volume: " << ad->volume << endl;
< #endif
< 
164d122
<             group = (GROUP *)List::next(timber_class->float_group_list);
165a124
>     }
167,172c126,128
<         timber_class->static_group_list = (LIST_PTR *)List::reset(timber_class->static_group_list);
<         group = (GROUP *)List::next(timber_class->static_group_list);
<         while (group != 0)
<         {
<             group->achieved->volume += hvol;
<             group->achieved->area += harea;
---
>     void harvest_update_activity(TimberClassStruct *pTimberClass, const double harea, const double vph)
>     {
>         if (pTimberClass->class_type == GroupDefStruct::INACTIVE) return;
174,178c130,131
< #ifdef _TSB_HARVEST_DEBUG
<         cout << endl << "harvest update activity: group area: "
<              << group->achieved->area
<              << endl << "group volume: " << group->achieved->volume << endl;
< #endif
---
>         // Derive harvest volume
>         double hvol = harea * vph;
180,214c133
<             if ( (group->reportFlags!= 0) &&
<                 (period>=group->reportFlags->hage_rep_start) &&
<                 (period<=group->reportFlags->hage_rep_end) )
<             {
<                 ad = (AGEDIST *)List::find(group->achieved->AgeDist, timber_class->age);
<                 if (ad== 0)
<                 {
<                     ad = new AGEDIST;
<                     if (ad== 0)
<                     {
<                         printf("\n\nERROR: harvest_update_activity(): Could not allocate new AGEDIST structure\n\n");
<                         exit(1);
<                     }
<                     ad->age = timber_class->age;
<                     ad->width = timber_class->width;
<                     ad->area = 0.0;
<                     ad->volume = 0.0;
<                     group->achieved->AgeDist = (LIST_PTR *)List::insert(group->achieved->AgeDist, ad, ad->age);
<                 }
<                 if ( ad->width != timber_class->width )
<                 {
<                     ad = new AGEDIST;
<                     if (ad== 0)
<                     {
<                         printf("\n\nERROR: harvest_update_activity(): Could not allocate new AGEDIST structure\n\n");
<                         exit(1);
<                     }
<                     ad->age = timber_class->age;
<                     ad->width = timber_class->width;
<                     ad->area = 0.0;
<                     ad->volume = 0.0;
<                     group->achieved->AgeDist = (LIST_PTR *)List::insert(group->achieved->AgeDist, ad, ad->age);
<                 }
<                 ad->area += harea;
<                 ad->volume += hvol;
---
>         FssimApp* pApp = FssimApp::getApp();
216,218c135,143
< #ifdef _TSB_HARVEST_DEBUG
<                 cout << endl << "harvest update activity: agedist area: "
<                      << ad->area << endl << "agedist volume: " << ad->volume << endl;
---
>         // Update harvest records
>         pApp->m_zone0->achieved->volume += hvol;
>         pApp->m_zone0->achieved->area += harea;
> 
> #ifdef _TSB_DEBUG_OFF
>         cout << endl << "harvest update activity: harvest area: " << harea
>              << endl << "vph: " << vph
>              << endl << "achieved->volume: " << pApp->m_zone0->achieved->volume
>              << endl << "hvol: " << hvol << endl;
221,224c146,147
<             }
<             group = (GROUP *)List::next(timber_class->static_group_list);
<         }
<     }
---
>         pTimberClass->parent_zone->achieved->volume += hvol;
>         pTimberClass->parent_zone->achieved->area += harea;
226,232c149,153
<     /* inlined
<     double harvest_adjacency(TIMBER_CLASS *timber_class, int period)
<     {
<         if (timber_class->parent_block->AdjacencyDelay > FssimApp::getApp()->m_periodLength[period])
<         {
<             return(0.0);
<         }
---
> #ifdef _TSB_DEBUG_OFF
>         cout << endl << "harvest update activity: parent zone area: "
>              << pTimberClass->parent_zone->achieved->area
>              << endl << "parent zone volume: " << pTimberClass->parent_zone->achieved->volume << endl;
> #endif
234c155
<         return (timber_class->MerchArea);
---
>         harvest_update_group_list(pTimberClass, hvol, harea);
236d156
<     */
238c158,159
<     double harvest_volume_shortfall(TIMBER_CLASS *timber_class, double vph, int period)
---
> 
>     double harvest_volume_shortfall(TimberClassStruct *timber_class, double vph)
240d160
<         GROUP* group = 0;
245c165
<         if (timber_class->class_type==FssimApp::INACTIVE)
---
>         if (timber_class->class_type == GroupDefStruct::INACTIVE)
251,253c171,176
<         /* Zone0; overall */
<         if ( func_compare_float(static_cast<float>(pApp->m_zone0->target->max_volume[period]),
<              FssimApp::DUMMYINPUT) == true )
---
> 
>         int period = pApp->m_currentPeriod;
> 
>         // Zone0; overall
>         if ( func_compare_float( static_cast<float>(pApp->m_zone0->target->max_volume[period]),
>                                  FssimUtil::DUMMY_INPUT ) == true )
255c178
<             shortfall = FssimApp::m_kMaxFloat;
---
>             shortfall = FLT_MAX;
259c182
<             shortfall = (double)pApp->m_zone0->target->max_volume[period] - pApp->m_zone0->achieved->volume;
---
>             shortfall = pApp->m_zone0->target->max_volume[period] - pApp->m_zone0->achieved->volume;
261c184,185
< #ifdef _TSB_HARVEST_DEBUG
---
> 
> #ifdef _TSB_VOLUME_SHORTFALL_DEBUG
267c191,192
<         if (shortfall <= FssimApp::m_kRoundError)
---
> 
>         if (shortfall <= FssimUtil::m_kRoundError)
269c194
<             return(0.0);
---
>             return(0);
271c196,197
<         /* Parent zone */
---
> 
>         // Parent zone
275c201
<                                      FssimApp::DUMMYINPUT ) == true )
---
>                                      FssimUtil::DUMMY_INPUT ) == true )
277c203
<                 tmp = FssimApp::m_kMaxFloat;
---
>                 tmp = FLT_MAX;
284c210
<                                           FssimApp::DUMMYINPUT ) != true )
---
>                                           FssimUtil::DUMMY_INPUT ) != true )
286,287c212,214
<                 tmp = (double)timber_class->parent_zone->target->max_volume[period] - timber_class->parent_zone->achieved->volume;
<                 if (tmp <= FssimApp::m_kRoundError)
---
>                 tmp = timber_class->parent_zone->target->max_volume[period] - timber_class->parent_zone->achieved->volume;
> 
>                 if (tmp <= FssimUtil::m_kRoundError)
296,300c223,228
< #ifdef _TSB_HARVEST_DEBUG
<             cout << "harvest_volume_shortfall (2) " << endl;
<             cout << setw(20) << "Max Volume = "<< setw(5) << timber_class->parent_zone->target->max_volume[period]
<                  << setw(20) << "Achieved = " << setw(5) << timber_class->parent_zone->achieved->volume
<                  << setw(20) << "Shortfall = "<< setw(5) << shortfall << endl;
---
> 
> #ifdef _TSB_VOLUME_SHORTFALL_DEBUG
>         cout << "harvest_volume_shortfall (2) " << endl;
>         cout << setw(20) << "Max Volume = "<< setw(5) << timber_class->parent_zone->target->max_volume[period]
>              << setw(20) << "Achieved = " << setw(5) << timber_class->parent_zone->achieved->volume
>              << setw(20) << "Shortfall = "<< setw(5) << shortfall << endl;
301a230
> 
304,307c233,235
<         /* Groups */
<         timber_class->float_group_list = (LIST_PTR *)List::reset(timber_class->float_group_list);
<         group = (GROUP *)List::next(timber_class->float_group_list);
<         while (group != 0)
---
>         // Groups
>         list<GroupStruct*>* pGroupList = 0;
>         for (int i = 0; i < 2; ++i)
309,310c237
< 
<             if (group->target != 0)
---
>             switch (i)
312,333c239,246
<                 if ( func_compare_float( static_cast<float>(group->target->max_volume[period]),
<                                          FssimApp::DUMMYINPUT ) == true )
<                 {
<                     tmp = FssimApp::m_kMaxFloat;
<                     if (tmp<shortfall)
<                     {
<                         shortfall = tmp;
<                     }
<                 }
<                 else if ( func_compare_float( static_cast<float>(group->target->max_volume[period]),
<                                               FssimApp::DUMMYINPUT ) != true )
<                 {
<                     tmp = (double)group->target->max_volume[period] - group->achieved->volume;
<                     if (tmp <= FssimApp::m_kRoundError)
<                     {
<                         return(0.0);
<                     }
<                     else if (tmp < shortfall)
<                     {
<                         shortfall = tmp;
<                     }
<                 }
---
>                 case 0 : // do float_group_list first
>                     pGroupList = &(timber_class->float_group_list);
>                     break;
>                 case 1 : // do static_group_list second
>                     pGroupList = &(timber_class->static_group_list);
>                     break;
>                 default : // for loop should never get here
>                     break;
335,341c248,250
<             group = (GROUP *)List::next(timber_class->float_group_list);
<         }
<         timber_class->static_group_list = (LIST_PTR *)List::reset(timber_class->static_group_list);
<         group = (GROUP *)List::next(timber_class->static_group_list);
<         while (group != 0)
<         {
<             if (group->target!= 0)
---
>             typedef list<GroupStruct*>::iterator GI;
>             for (GI groupIter = pGroupList->begin(); //!pGroupList->empty() &&
>                     groupIter != pGroupList->end(); ++groupIter)
343,344c252,254
<                 if ( func_compare_float( static_cast<float>(group->target->max_volume[period]),
<                                          FssimApp::DUMMYINPUT) == true )
---
>                 GroupStruct* pCurrentGroup = (*groupIter);
> 
>                 if (pCurrentGroup->target != 0)
346,347c256,257
<                     tmp = FssimApp::m_kMaxFloat;
<                     if (tmp<shortfall)
---
>                     if ( func_compare_float( static_cast<float>(pCurrentGroup->target->max_volume[period]),
>                                              FssimUtil::DUMMY_INPUT ) == true )
349c259,263
<                         shortfall = tmp;
---
>                         tmp = FLT_MAX;
>                         if (tmp<shortfall)
>                         {
>                             shortfall = tmp;
>                         }
351,356c265,266
<                 }
<                 else if ( func_compare_float( static_cast<float>(group->target->max_volume[period]),
<                                               FssimApp::DUMMYINPUT ) != true )
<                 {
<                     tmp = (double)group->target->max_volume[period] - group->achieved->volume;
<                     if (tmp <= FssimApp::m_kRoundError)
---
>                     else if ( func_compare_float( static_cast<float>(pCurrentGroup->target->max_volume[period]),
>                                                   FssimUtil::DUMMY_INPUT ) != true )
358c268,277
<                         return(0.0);
---
>                         tmp = pCurrentGroup->target->max_volume[period] - pCurrentGroup->achieved->volume;
> 
>                         if (tmp <= FssimUtil::m_kRoundError)
>                         {
>                             return 0;
>                         }
>                         else if (tmp < shortfall)
>                         {
>                             shortfall = tmp;
>                         }
360,365c279,280
<                     else if (tmp < shortfall)
<                     {
<                         shortfall = tmp;
<                     }
<                 }
< #ifdef _TSB_HARVEST_DEBUG
---
> 
> #ifdef _TSB_VOLUME_SHORTFALL_DEBUG
367,368c282,283
<                 cout << setw(20) << "Max Volume = "<< setw(5) << group->target->max_volume[period]
<                      << setw(20) << "Achieved = " << setw(5) << group->achieved->volume
---
>                 cout << setw(20) << "Max Volume = "<< setw(5) << pCurrentGroup->target->max_volume[period]
>                      << setw(20) << "Achieved = " << setw(5) << pCurrentGroup->achieved->volume
370a286
>                 }
372d287
<             group = (GROUP *)List::next(timber_class->static_group_list);
374c289,290
<         /* Function returns harvestable area; shortfall is in volume, convert to area using vph */
---
> 
>         // Function returns harvestable area; shortfall is in volume, convert to area using vph
380c296,297
< #ifdef _TSB_HARVEST_DEBUG
---
> 
> #ifdef _TSB_VOLUME_SHORTFALL_DEBUG
382a300
>              << setw(20) << "vph = "<< setw(5) << vph
385a304
> 
389c308
<     double harvest_area_shortfall(TIMBER_CLASS *timber_class, int period)
---
>     double harvest_area_shortfall(TimberClassStruct *timber_class)
391,392c310,311
<         GROUP	*group;
<         double	tmp, shortfall=FssimApp::DUMMYINPUT;
---
>         double tmp = 0.0;
> 	    double shortfall = FssimUtil::DUMMY_INPUT;
394c313
<         if (timber_class->class_type==FssimApp::INACTIVE) return(0.0);
---
>         if (timber_class->class_type == GroupDefStruct::INACTIVE) return(0);
397,400c316,320
<         /* Zone0; overall */
<         if ( (pApp->m_zone0->target!= 0) &&
<             (func_compare_float(static_cast<float>(pApp->m_zone0->target->max_area[period]),
<             FssimApp::DUMMYINPUT)==true) )
---
> 
>         int period = pApp->m_currentPeriod;
> 
>         // Zone0; overall
>         if (pApp->m_zone0->target!= 0)
402,408c322,323
<             shortfall = FssimApp::m_kMaxFloat;
<         } else if ( (pApp->m_zone0->target!= 0) &&
<             (func_compare_float(static_cast<float>(pApp->m_zone0->target->max_area[period]),
<             FssimApp::DUMMYINPUT)!=true) )
<         {
<             shortfall = static_cast<double>(pApp->m_zone0->target->max_area[period]) - pApp->m_zone0->achieved->area;
<             if (shortfall <= FssimApp::m_kRoundError)
---
>             if ( func_compare_float( static_cast<float>(pApp->m_zone0->target->max_area[period]),
>                                      FssimUtil::DUMMY_INPUT ) == true )
410c325
<                 return(0.0);
---
>                 shortfall = FLT_MAX;
412,425c327,328
<         }
<         /* Parent zone */
<         if ( (timber_class->parent_zone->target!= 0) &&
<             (func_compare_float(static_cast<float>(timber_class->parent_zone->target->max_area[period]),
<             FssimApp::DUMMYINPUT)==true) )
<         {
<             tmp = FssimApp::m_kMaxFloat;
<             if (tmp<shortfall) shortfall=tmp;
<         } else if ( (timber_class->parent_zone->target!= 0) &&
<             (func_compare_float(static_cast<float>(timber_class->parent_zone->target->max_area[period]),
<             FssimApp::DUMMYINPUT)!=true) )
<         {
<             tmp = (double)timber_class->parent_zone->target->max_area[period] - timber_class->parent_zone->achieved->area;
<             if (tmp <= FssimApp::m_kRoundError)
---
>             else if ( func_compare_float( static_cast<float>(pApp->m_zone0->target->max_area[period]),
>                                           FssimUtil::DUMMY_INPUT ) != true )
427,449c330,332
<                 return(0.0);
<             } else if (tmp < shortfall)
<             {
<                 shortfall = tmp;
<             }
<         }
<         /* Groups */
<         timber_class->float_group_list = (LIST_PTR *)List::reset(timber_class->float_group_list);
<         group = (GROUP *)List::next(timber_class->float_group_list);
<         while (group != 0)
<         {
<             if ( (group->target!= 0) &&
<                 (func_compare_float(static_cast<float>(group->target->max_area[period]),
<                 FssimApp::DUMMYINPUT)==true) )
<             {
<                 tmp = FssimApp::m_kMaxFloat;
<                 if (tmp<shortfall) shortfall=tmp;
<             } else if ( (group->target!= 0) &&
<                 (func_compare_float(static_cast<float>(group->target->max_area[period]),
<                 FssimApp::DUMMYINPUT)!=true) )
<             {
<                 tmp = (double)group->target->max_area[period] - group->achieved->area;
<                 if (tmp <= FssimApp::m_kRoundError)
---
>                 shortfall = /*static_cast<double>(*/pApp->m_zone0->target->max_area[period]//)
>                             - pApp->m_zone0->achieved->area;
>                 if (shortfall <= FssimUtil::m_kRoundError)
452,454d334
<                 } else if (tmp < shortfall)
<                 {
<                     shortfall = tmp;;
457d336
<             group = (GROUP *)List::next(timber_class->float_group_list);
459,461c338,340
<         timber_class->static_group_list = (LIST_PTR *)List::reset(timber_class->static_group_list);
<         group = (GROUP *)List::next(timber_class->static_group_list);
<         while (group != 0)
---
> 
>         // Parent zone
>         if (timber_class->parent_zone->target!= 0)
463,465c342,343
<             if ( (group->target!= 0) &&
<                 (func_compare_float(static_cast<float>(group->target->max_area[period]),
<                 FssimApp::DUMMYINPUT)==true) )
---
>             if ( func_compare_float( static_cast<float>(timber_class->parent_zone->target->max_area[period]),
>                                      FssimUtil::DUMMY_INPUT ) == true )
467,468c345,349
<                 tmp = FssimApp::m_kMaxFloat;
<                 if (tmp<shortfall) shortfall=tmp;
---
>                 tmp = FLT_MAX;
>                 if (tmp < shortfall)
>                 {
>                     shortfall = tmp;
>                 }
470,472c351,352
<             else if ( (group->target!= 0) &&
<                 (func_compare_float(static_cast<float>(group->target->max_area[period]),
<                 FssimApp::DUMMYINPUT)!=true) )
---
>             else if ( func_compare_float( static_cast<float>(timber_class->parent_zone->target->max_area[period]),
>                                           FssimUtil::DUMMY_INPUT ) != true )
474,475c354,356
<                 tmp = (double)group->target->max_area[period] - group->achieved->area;
<                 if (tmp <= FssimApp::m_kRoundError)
---
>                 tmp = timber_class->parent_zone->target->max_area[period] - timber_class->parent_zone->achieved->area;
> 
>                 if (tmp <= FssimUtil::m_kRoundError)
478c359,360
<                 } else if (tmp < shortfall)
---
>                 }
>                 else if (tmp < shortfall)
480c362
<                     shortfall = tmp;;
---
>                     shortfall = tmp;
483d364
<             group = (GROUP *)List::next(timber_class->static_group_list);
485,490d365
<         if (shortfall>timber_class->MerchArea)
<         {
<             shortfall=timber_class->MerchArea;
<         }
<         return(shortfall);
<     }
492,497c367,369
<     /* inlined
<     double calculate_green_up(AXSDEF *axs, TIMBER_CLASS *timber_class, int period)
<     {
<         double tmp = 0.0;
<         FssimApp* pApp = FssimApp::getApp();
<         if (axs->Age<pApp->m_periodLength[period])
---
>         // Groups
>         list<GroupStruct*>* pGroupList = 0;
>         for (int i = 0; i < 2; ++i)
499,524c371
<             cout << endl << "WARNING: axs->age(" << axs->Age << ") < PeriodLength("
<                  << pApp->m_periodLength[period] << "); Constraint will not be applied" << endl;
< 
<             tmp = timber_class->MerchArea;
<         }
<         else
<         {
<             tmp = (axs->BaseArea*axs->Percent/100.0) - func_area_lt(axs->AgeArea,
<                    axs->Age-pApp->m_periodLength[period], period);
<         }
< #ifdef _TSB_GREENUP_DEBUG
<         cout << endl << "BaseArea (calculate_green_up): " << axs->BaseArea << endl
<                      << "Percent: " << axs->Percent << endl
<                      << "Age: " << axs->Age;
< #endif
<         return tmp;
<     }
< 
<     void debug_display_agearea(AXSDEF *axs, char *where)
<     {
<         int i = 0;
<         FssimApp* pApp = FssimApp::getApp();
<         fprintf(pApp->m_pFileTrace, "\nBEGIN debug_display_agearea(%s)", where);
<         for( i=0; i<axs->NumAgeAreaElements; ++i )
<         {
<             if ( axs->AgeArea[i] > 0.0f )
---
>             switch (i)
526c373,380
<                 fprintf(pApp->m_pFileTrace, "\nAgeArea[%3d]: %8.2f", i, axs->AgeArea[i]);
---
>                 case 0 : // do float_group_list first
>                     pGroupList = &(timber_class->float_group_list);
>                     break;
>                 case 1 : // do static_group_list second
>                     pGroupList = &(timber_class->static_group_list);
>                     break;
>                 default : // for loop should never get here
>                     break;
528,565c382,384
<         }
<         fprintf(pApp->m_pFileTrace, "\nEND debug_display_agearea(%s)\n", where);
<     }
< 
<     double calculate_old_growth(AXSDEF *axs, TIMBER_CLASS *timber_class, int period)
<     {
<         FssimApp* pApp = FssimApp::getApp();
< 
<         //v4.0.2, Kevin Belanger moved outside to just before harvest function calls calculate_old_growth
<         //double totalMatureAxsArea = func_area_ge(axs->AgeArea, axs->NumAgeAreaElements,
<         //                                 (axs->Age - pApp->m_periodLength[period]),
<         //                                 period, timber_class->width);
< 
<         // moved back into function from doAxsListLessThanGreaterThan
<         double totalMatureAxsArea = func_area_ge(axs->AgeArea, axs->NumAgeAreaElements,
<                                                  (axs->Age - pApp->m_periodLength[period]), period);
< 
<         double desiredArea = axs->BaseArea * axs->Percent / 100.0;
< 
<         double currentClassAndOlderArea = func_area_ge(axs->AgeArea, axs->NumAgeAreaElements,
<                                                         (timber_class->age - timber_class->width + 1),
<                                                         period);
< 
< 
< #ifdef _TSB_AXS_DEBUG
<         cout << endl << setw(20) << "age = " << setw(3) << timber_class->age
<              << setw(20) << "width = " << setw(3) << timber_class->width
< 
<              << setw(20) << "axs->NumAgeAreaElements = " << setw(3) << axs->NumAgeAreaElements
<              << setw(20) << "axs->Age = " << setw(3) << axs->Age
<              << setw(20) << "axs->BaseArea = " << setw(3) << axs->BaseArea
<              << setw(20) << "axs->Percent = " << setw(3) << axs->Percent
<              << setw(20) << "period = " << setw(3) << period << endl << endl;
< #endif
< #ifdef _TSB_AXS_DEBUG
<         for( int i = 0 ; i < axs->NumAgeAreaElements ; ++i)
<         {
<             if (axs->AgeArea[i] > 0)
---
>             typedef list<GroupStruct*>::iterator GI;
>             for (GI groupIter = pGroupList->begin(); //!pGroupList->empty() &&
>                     groupIter != pGroupList->end(); ++groupIter)
567,571c386
<                 cout << setw(24) << "AgeArea["  << i << "] = "
<                      << setw(3) << axs->AgeArea[i] << endl;
<             }
<         }
< #endif
---
>                 GroupStruct* pCurrentGroup = (*groupIter);
573,624c388
<         double harvestableArea = 0.0;
<         if ( ( (totalMatureAxsArea - desiredArea) > FssimApp::m_kRoundError ) &&
<              ( (totalMatureAxsArea - currentClassAndOlderArea) > FssimApp::m_kRoundError ) )
<         {
<             // if there is enough old growth, harvest oldest trees from current class
<             // or if there is enough younger old growth elsewhere, preserve it
<             // and harvest current class (and older classes) first
<             harvestableArea = totalMatureAxsArea - desiredArea;
<         }
<         else
<         {
<             // if not enough total old growth, harvest younger trees from current class
<             // or if there is not enough younger old growth elsewhere, preserve
<             // the required old growth within the current class
<             harvestableArea = currentClassAndOlderArea - desiredArea;
<         }
< 
< #ifdef _TSB_AXS_DEBUG
<         cout << setw(30) << "totalMatureAxsArea = " << setw(3) << totalMatureAxsArea
<              << setw(30) << "desiredArea = " << setw(3) << desiredArea << endl
<              << setw(30) << "currentClassAndOlderArea = " << setw(3) << currentClassAndOlderArea
<              << setw(30) << "harvestableArea = " << setw(3) << harvestableArea << endl;
< #endif
< 
<         return harvestableArea;
<     }
<     */
< 
<     double doAxsListLessThanGreaterThan(TIMBER_CLASS *timber_class, LIST_PTR* axsList, int period, double result)
<     {
<         //FssimApp* pApp = FssimApp::getApp();
< 
<         double tempResult = 0;
< 
< #ifdef _TSB_AXS_DEBUG//_TSB_VERBOSE
<         cout << "size of axslist: " << axsList->size << endl;
< #endif
< 
<         AXSDEF* axs = (AXSDEF *)List::next(axsList);
< 
<         /* bug introduced in v4.0.2: this should be called inside calculate_old_growth for each element of the axslist
<         double totalMatureAxsArea = func_area_ge(axs->AgeArea, axs->NumAgeAreaElements,
<                                                  (axs->Age - pApp->m_periodLength[period]),
<                                                  period);
<         */
< 
<         while (axs != 0)
<         {
< #ifdef _TSB_AGEAREA_DEBUG
<             for( int i = 0 ; i < axs->NumAgeAreaElements ; ++i)
<             {
<                 if ( axs->AgeArea[i] > 0  )
---
>                 if (pCurrentGroup->target!= 0)
626,640c390,391
<                     cout << setw(24) << "axs->AgeArea[" << i << "] = "
<                          << setw(3) << axs->AgeArea[i] << endl;
<                 }
<             }
< #endif
< #ifdef _TSB_AXS_DEBUG
<             cout << endl << "axs start_period/end_period/age/percent: "
<                  << axs->start_period << "/" << axs->end_period << "/"
<                  << axs->Age << "/" << axs->Percent << endl;
< #endif
<             if ((period>=axs->start_period)&&(period<=axs->end_period))
<             {
<                 if (axs->Sign==FssimApp::AXS_LT)
<                 {
<                     if ((axs->Age>=0)&&(axs->Percent>=0.0))
---
>                     if ( func_compare_float( static_cast<float>(pCurrentGroup->target->max_area[period]),
>                                              FssimUtil::DUMMY_INPUT ) == true )
642,649c393,394
< #ifdef _TSB_AXS_DEBUG
<                         cout << endl << "calculate_green_up: " << timber_class->age << endl;
< #endif
<                         tempResult = calculate_green_up(axs, timber_class, period);
< #ifdef _TSB_AXS_DEBUG
<                         cout << endl << "doAxsListLessThanGreaterThan: tempResult: " << tempResult << endl;
< #endif
<                         if (tempResult < FssimApp::m_kRoundError)
---
>                         tmp = FLT_MAX;
>                         if (tmp < shortfall)
651c396
<                             return (FssimApp::DUMMYINPUT);
---
>                             shortfall = tmp;
653,657d397
<                         if (tempResult < result)
<                         {
<                             result = tempResult;
<                         }
< 
659,662c399,400
<                 }
<                 else if (axs->Sign==FssimApp::AXS_GT)
<                 {
<                     if ((axs->Age>=0)&&(axs->Percent>=0.0))
---
>                     else if ( func_compare_float( static_cast<float>(pCurrentGroup->target->max_area[period]),
>                                                     FssimUtil::DUMMY_INPUT ) != true )
664,668c402,404
< #ifdef _TSB_AXS_DEBUG
<                         cout << endl << "calculate_old_growth: " << timber_class->age << endl;
< #endif
<                         tempResult = calculate_old_growth(axs, timber_class, period/*, totalMatureAxsArea*/);
<                         if (tempResult < FssimApp::m_kRoundError)
---
>                         tmp = pCurrentGroup->target->max_area[period] - pCurrentGroup->achieved->area;
> 
>                         if (tmp <= FssimUtil::m_kRoundError)
670,673c406
< #ifdef _TSB_AXS_DEBUG
<                             cout << endl << "harvest_constraints: tempResult (3): " << tempResult << endl;
< #endif
<                             return (FssimApp::DUMMYINPUT);
---
>                             return 0.0;
675c408
<                         if (tempResult < result)
---
>                         else if (tmp < shortfall)
677,680c410
<                             result = tempResult;
< #ifdef _TSB_AXS_DEBUG
<                             cout << endl << "harvest_constraints: hresult (3): " << result << endl;
< #endif
---
>                             shortfall = tmp;;
682d411
< 
685,689d413
<                 else
<                 {
<                     printf("\n\nERROR: harvest_constraints(): Invalid Sign(%d)\n\n", axs->Sign);
<                     exit(1);
<                 }
691d414
<             axs = (AXSDEF *)List::next(axsList);
693c416,420
<         return result;
---
>         if (shortfall > timber_class->MerchArea)
>         {
>             shortfall = timber_class->MerchArea;
>         }
>         return shortfall;
696c423,424
<     double harvest_constraints(TIMBER_CLASS* timber_class, int period)
---
> 
>     void doAxsListLessThanGreaterThan(TimberClassStruct* timber_class, vector<AxsDefStruct*>& axsList, double& result)
698c426,433
<         GROUP* group = 0;
---
>         HarvestAxsConstraints doAgeArea(timber_class, result);
>         for_each( axsList.begin(), axsList.end(), doAgeArea );
> 
>         return;
>     }
> 
>     double harvest_constraints(TimberClassStruct* timber_class)
>     {
701c436
<         if (timber_class->class_type==FssimApp::INACTIVE)
---
>         if (timber_class->class_type == GroupDefStruct::INACTIVE)
702a438
> 
706c442,443
<             return (0.0);
---
> 
>             return 0.0;
709a447
> 
711c449
<         cout << endl << endl << "harvest_constraints: hresult (1): " << result << endl;
---
>         cout << endl << "harvest_constraints: hresult (1): " << result << endl;
713c451,452
<         if (timber_class->parent_zone->axslist != 0)
---
> 
>         if ( !timber_class->parent_zone->axslist.empty() )
715,717c454,457
<             timber_class->parent_zone->axslist = (LIST_PTR *)List::reset(timber_class->parent_zone->axslist);
<             result = tsb::doAxsListLessThanGreaterThan(timber_class, timber_class->parent_zone->axslist, period, result);
<             if (result == (FssimApp::DUMMYINPUT))
---
>             // result of calculations will be stored in result parameter
>             tsb::doAxsListLessThanGreaterThan(timber_class, timber_class->parent_zone->axslist, result);
> 
>             if (result == FssimUtil::DUMMY_INPUT)
718a459
> 
722c463,464
<                 return (result = 0);
---
> 
>                 return 0.0;
724a467,468
> 
> #ifdef _TSB_AXS_DEBUG
727,730c471,472
< #ifdef _TSB_AXS_DEBUG
<         cout << endl << "timber_class->parent_zone->axslist is empty for zone: "
<              << timber_class->parent_zone->label << endl;
< #endif
---
>             cout << endl << "timber_class->parent_zone->axslist is empty for zone: "
>                  << timber_class->parent_zone->label << endl;
732,734c474
< 
< #ifdef _TSB_GROUP_DEBUG
<                         cout << endl << "harvest_constraints: float group list" << endl;
---
>         cout << endl << "harvest_constraints: doing group axslist" << endl;
736,737d475
<         timber_class->float_group_list = (LIST_PTR *)List::reset(timber_class->float_group_list);
<         group = (GROUP *)List::next(timber_class->float_group_list);
739c477,478
<         while (group != 0)
---
>         list<GroupStruct*>* pGroupList = 0;
>         for (int i = 0; i < 2; ++i)
741,745c480
< #ifdef _TSB_HARVEST_DEBUG
<                     cout << endl << "group (id : label): "
<                          << group->id << " : " << group->label << endl;
< #endif
<             if (group->axslist != 0)
---
>             switch (i)
747c482,483
<                 group->axslist = (LIST_PTR *)List::reset(group->axslist);
---
>                 case 0 : // do float_group_list first
>                     pGroupList = &(timber_class->float_group_list);
749,754c485,486
<                 result = tsb::doAxsListLessThanGreaterThan(timber_class, group->axslist, period, result);
<                 if (result == (FssimApp::DUMMYINPUT))
<                 {
< #ifdef _TSB_GROUP_DEBUG
<                         cout << endl << "harvest_constraints: dummy input for group (id : label): "
<                              << group->id << " : " << group->label << endl;
---
> #ifdef _TSB_DEBUG_OFF
>                         cout << endl << "harvest_constraints: float group list" << endl;
756,767c488,490
<                     return (result = 0);
<                 }
<             }
<             else
<             {
< #ifdef _TSB_GROUP_DEBUG
<                 cout << endl << "pCurrentGroup->axslist is empty for group: "
<                      << group->label << endl;
< #endif
<             }
<             group = (GROUP *)List::next(timber_class->float_group_list);
<         }
---
>                     break;
>                 case 1 : // do static_group_list second
>                     pGroupList = &(timber_class->static_group_list);
769c492
< #ifdef _TSB_GROUP_DEBUG
---
> #ifdef _TSB_DEBUG_OFF
772,780c495,501
<         timber_class->static_group_list = (LIST_PTR *)List::reset(timber_class->static_group_list);
<         group = (GROUP *)List::next(timber_class->static_group_list);
<         while (group != 0)
<         {
< #ifdef _TSB_HARVEST_DEBUG
<                      cout << endl << "group (id : label): "
<                           << group->id << " : " << group->label << endl;
< #endif
<             if (group->axslist != 0)
---
>                     break;
>                 default : // for loop should never get here
>                     break;
>             }
>             typedef list<GroupStruct*>::iterator GI;
>             for (GI groupIter = pGroupList->begin(); //!pGroupList->empty() &&
>                     groupIter != pGroupList->end(); ++groupIter)
782,784c503,510
<                 group->axslist = (LIST_PTR *)List::reset(group->axslist);
<                 result = tsb::doAxsListLessThanGreaterThan(timber_class, group->axslist, period, result);
<                 if (result == (FssimApp::DUMMYINPUT))
---
>                 GroupStruct* pCurrentGroup = (*groupIter);
> 
> #ifdef _TSB_DEBUG_OFF
>                     cout << endl << "group (id : label): "
>                          << pCurrentGroup->id << " : " << pCurrentGroup->label << endl;
> #endif
> 
>                 if ( !pCurrentGroup->axslist.empty() )
785a512,517
>                     // result of calculations will be stored in result parameter
>                     tsb::doAxsListLessThanGreaterThan(timber_class, pCurrentGroup->axslist, result);
> 
>                     if (result == FssimUtil::DUMMY_INPUT)
>                     {
> 
788c520
<                              << group->id << " : " << group->label << endl;
---
>                              << pCurrentGroup->id << " : " << pCurrentGroup->label << endl;
790c522,523
<                     return (result = 0);
---
>                         return (0.0);
>                     }
792,794c525
<             }
<             else
<             {
---
> 
796,797c527,531
<                 cout << endl << "pCurrentGroup->axslist is empty for group: "
<                      << group->label << endl;
---
>                 else
>                 {
>                     cout << endl << "pCurrentGroup->axslist is empty for group: "
>                         << pCurrentGroup->label << endl;
>                 }
800d533
<             group = (GROUP *)List::next(timber_class->static_group_list);
802,803d534
< 
< 
807,816d537
<     void harvest(int period)
<     {
<         HASHREC* hashrec = 0;
<         TIMBER_CLASS* timber_class = 0;
<         //double hvol = 0.0;
<         //double harea = 0.0;
<         //double haxs = 0.0;
<         //double hadj = 0.0;
<         //double harvest = 0.0;
<         //double vph = 0.0;
817a539,540
>     void harvest()
>     {
820,822c543,547
<         printf("\nPeriod : %3d - Harvesting", period);
< /*
<         if ( period >= 24 )
---
>         int period = pApp->m_currentPeriod;
> 
>         cout << "Period : " << period << " - Harvesting" << endl;
> 
>         if (pApp->m_enableTrace == true)
824,830d548
<             pApp->m_enableTrace = true;
<         } else {
<             pApp->m_enableTrace = false;
<         }
< */
<         if (pApp->m_enableTrace==true)
<         {
834,838d551
< #ifdef _TSB_HARVEST_DEBUG
<         int classCounter = 0;
< #endif
<         pApp->m_candidateList = (LIST_PTR *)List::reset(pApp->m_candidateList);
<         hashrec = (HASHREC *)List::next(pApp->m_candidateList);
841,844d553
<         while (hashrec != 0)
<         {
<             hashrec->candidates = (LIST_PTR *)List::reset(hashrec->candidates);
<             timber_class = (TIMBER_CLASS *)List::next(hashrec->candidates);
846,853c555,558
<             while (timber_class != 0)
<             {
<                 if (timber_class->class_type != FssimApp::INACTIVE)
<                 {
< #ifdef _TSB_HARVEST_DEBUG
<                     ++classCounter;
<                     cout << endl << "processing candidate # " << classCounter << " with age = " << timber_class->age << endl
<                          << " and priority: " << (hashrec->id) << endl;
---
> #ifdef _TSB_CANDIDATE_HARVEST_DEBUG
>         int classCounter = 0;
>         cout << endl << "harvest: size of candidate list = " << pApp->m_candidateList.size() << endl;
> #endif
855,862c560,564
<                     // abort to shorten debug time and file length
<                     /*
<                     if (classCounter == 9)
<                     {
<                         cout << endl << " done ten classes - exiting..." << endl;
<                         exit(0);
<                     }
<                     */
---
>         // process the priority queue of candidates
>         while(!pApp->m_candidateList.empty())
>         {
>             // get candidate at top of queue
>             const Candidate& currentCandidate = pApp->m_candidateList.top();
863a566,572
>             TimberClassStruct* pCurrentTimberClass = currentCandidate.m_pClass;
> 
>             int currentAge = pCurrentTimberClass->age;
> #ifdef _TSB_CANDIDATE_HARVEST_DEBUG
>             ++classCounter;
>             cout << endl << "processing candidate # " << classCounter << " with age = " << currentAge << endl
>                  << " and priority: " << currentCandidate.m_priority << endl;
865,870c574,575
<                     double harvest = 0;
<                     double hadj = timber_class->MerchArea;
<                     double hvol = hadj;
<                     double harea = hadj;
<                     double haxs = hadj;
<                     double vph = func_vph_recovered(timber_class);
---
>             // now that we have a TimberClassStruct pointer, pop the candidate off the queue
>             pApp->m_candidateList.pop();
871a577,585
>             if (pCurrentTimberClass->class_type != GroupDefStruct::INACTIVE)
>             {
>                 double harvest = 0.0;
>                 double hadj = pCurrentTimberClass->MerchArea;
>                 double hvol = hadj;
>                 double harea = hadj;
>                 double haxs = hadj;
>                 double vph = pCurrentTimberClass->vphRecovered();
> 
873c587
<                     cout << endl << "harvest: vph: " << vph << endl;
---
>                 cout << endl << "harvest: vph: " << vph << endl;
876d589
< 
882,883c595,596
<                          << setw(10) << "haxs = " << setw(3) << haxs
<                          << setw(12) << "harvest = " << setw(3) << harvest << endl;
---
>                          << setw(10) << "haxs = " << setprecision(5) << setw(4) << haxs
>                          << setw(12) << "harvest = " << setw(4) << harvest << endl;
885,888d597
<                     if (vph>FssimApp::m_kRoundError)
<                     {
<                         hadj = harvest_adjacency(timber_class, period);
<                         harvest = hadj;
889a599,602
>                 if (vph > FssimUtil::m_kRoundError)
>                 {
>                     hadj = harvest_adjacency(pCurrentTimberClass);
>                     harvest = hadj;
893,897c606,610
<                     cout //<< setw(10) << "hadj = "<< setw(3) << hadj
<                          //<< setw(10) << "hvol = " << setw(3) << hvol
<                          //<< setw(10) << "harea = "<< setw(3) << harea
<                          << setw(10) << "haxs = " << setw(3) << haxs
<                          << setw(12) << "harvest = " << setw(3) << harvest << endl;
---
>                     cout //<< setw(10) << "hadj = "<< setw(5) << hadj
>                          //<< setw(10) << "hvol = " << setw(5) << hvol
>                          //<< setw(10) << "harea = "<< setw(5) << harea
>                          << setw(10) << "haxs = " << setprecision(5) << setw(4) << haxs
>                          << setw(12) << "harvest = " << setw(4) << harvest << endl;
899c612,615
<                         if (harvest>FssimApp::m_kRoundError)
---
>                     if (harvest > FssimUtil::m_kRoundError)
>                     {
>                         hvol = harvest_volume_shortfall(pCurrentTimberClass, vph);
>                         if (hvol < harvest)
901,906c617
<                             hvol = harvest_volume_shortfall(timber_class, vph, period);
<                             if (hvol < harvest)
<                             {
<                                 harvest = hvol;
< 
<                             }
---
>                             harvest = hvol;
908,911c619,623
<                         else
<                         {
<                             hvol = harvest;
<                         }
---
>                     }
>                     else
>                     {
>                         hvol = harvest;
>                     }
915,919c627,631
<                     cout //<< setw(10) << "hadj = "<< setw(3) << hadj
<                          //<< setw(10) << "hvol = " << setw(3) << hvol
<                          //<< setw(10) << "harea = "<< setw(3) << harea
<                          << setw(10) << "haxs = " << setw(3) << haxs
<                          << setw(12) << "harvest = " << setw(3) << harvest << endl;
---
>                     cout //<< setw(10) << "hadj = "<< setw(5) << hadj
>                          //<< setw(10) << "hvol = " << setw(5) << hvol
>                          //<< setw(10) << "harea = "<< setw(5) << harea
>                          << setw(10) << "haxs = " << setprecision(5) << setw(4) << haxs
>                          << setw(12) << "harvest = " << setw(4) << harvest << endl;
921,922c633,637
< 
<                         if (harvest>FssimApp::m_kRoundError)
---
>                     if (harvest > FssimUtil::m_kRoundError)
>                     {
>                         harea = harvest_area_shortfall(pCurrentTimberClass);
>                         if ( (func_compare_float(static_cast<float>(harea), FssimUtil::DUMMY_INPUT) != true) &&
>                              (harea < hvol) )
924,931c639
<                             harea = harvest_area_shortfall(timber_class, period);
<                             if ( (func_compare_float(static_cast<float>(harea),
<                                                      FssimApp::DUMMYINPUT)!=true) &&
<                                 (harea<hvol) )
<                             {
<                                 harvest=harea;
< 
<                             }
---
>                             harvest = harea;
933,936c641,645
<                         else
<                         {
<                             harea=harvest;
<                         }
---
>                     }
>                     else
>                     {
>                         harea = harvest;
>                     }
939,944c648,653
<                     cout << endl << "after harvest_area_shortfall: " << endl;
<                     cout //<< setw(10) << "hadj = "<< setw(3) << hadj
<                          //<< setw(10) << "hvol = " << setw(3) << hvol
<                          //<< setw(10) << "harea = "<< setw(3) << harea
<                          << setw(10) << "haxs = " << setw(3) << haxs
<                          << setw(12) << "harvest = " << setw(3) << harvest << endl;
---
>                     cout << "after harvest_area_shortfall: " << endl;
>                     cout //<< setw(10) << "hadj = "<< setw(5) << hadj
>                          //<< setw(10) << "hvol = " << setw(5) << hvol
>                          //<< setw(10) << "harea = "<< setw(5) << harea
>                          << setw(10) << "haxs = " << setprecision(5) << setw(4) << haxs
>                          << setw(12) << "harvest = " << setw(4) << harvest << endl;
946c655,658
<                         if (harvest>FssimApp::m_kRoundError)
---
>                     if (harvest > FssimUtil::m_kRoundError)
>                     {
>                         haxs = harvest_constraints(pCurrentTimberClass);
>                         if (haxs < harvest)
948,954c660
<                             haxs = harvest_constraints(timber_class, period);
< 
<                             if (haxs < harvest)
<                             {
<                                 harvest=haxs;
< 
<                             }
---
>                             harvest = haxs;
956,959c662,666
<                         else
<                         {
<                             haxs=harvest;
<                         }
---
>                     }
>                     else
>                     {
>                         haxs = harvest;
>                     }
961d667
< 
964,968c670,674
<                     cout //<< setw(10) << "hadj = "<< setw(3) << hadj
<                          //<< setw(10) << "hvol = " << setw(3) << hvol
<                          //<< setw(10) << "harea = "<< setw(3) << harea
<                          << setw(10) << "haxs = " << setw(3) << haxs
<                          << setw(12) << "harvest = " << setw(3) << harvest << endl;
---
>                     cout //<< setw(10) << "hadj = "<< setw(5) << hadj
>                          //<< setw(10) << "hvol = " << setw(5) << hvol
>                          //<< setw(10) << "harea = "<< setw(5) << harea
>                          << setw(10) << "haxs = " << setprecision(5) << setw(4) << haxs
>                          << setw(12) << "harvest = " << setw(4) << harvest << endl << endl;
971,981c677,687
<                         if (pApp->m_enableBlockReport==true)
<                         {
<                                 if ( ( (pApp->m_enableClassSplit == false) && (harvest+FssimApp::m_kRoundError >= timber_class->area) )
<                                         || (pApp->m_enableClassSplit==true) && (harvest > 0) )
<                                 {
<                                     fprintf(pApp->m_pFileBlockReport, "\n%6d %10s %10s %10s %8.2f",
<                                             period,
<                                             timber_class->parent_zone->label,
<                                             timber_class->parent_au->label,
<                                             timber_class->parent_block->label,
<                                             harvest);
---
>                     if (pApp->m_enableBlockReport == true)
>                     {
>                             if ( ( (pApp->m_enableClassSplit == false) && (harvest+FssimUtil::m_kRoundError >= pCurrentTimberClass->area) )
>                                     || (pApp->m_enableClassSplit == true) && (harvest > 0) )
>                             {
>                                 fprintf(pApp->m_pFileBlockReport, "\n%6d %10s %10s %10s %8.2f",
>                                         period,
>                                         pCurrentTimberClass->parent_zone->label,
>                                         pCurrentTimberClass->parent_au->label,
>                                         pCurrentTimberClass->parent_block->label,
>                                         harvest);
983d688
<                                 }
984a690
>                     }
986c692,719
<                         if (pApp->m_enableTrace==true)
---
>                     if (pApp->m_enableTrace == true)
>                     {
>                         fprintf(pApp->m_pFileTrace, "\n%6d %10s %10s %10s %6d %8.1f %8.1f | %8.1f %8.1f %8.1f %8.1f || %8.1f <%8.1f>",
>                             period,
>                             pCurrentTimberClass->parent_zone->label,
>                             pCurrentTimberClass->parent_au->label,
>                             pCurrentTimberClass->parent_block->label,
>                             pCurrentTimberClass->age,
>                             pCurrentTimberClass->area,
>                             pCurrentTimberClass->MerchArea,
>                             hadj,
>                             hvol,
>                             harea,
>                             haxs,
>                             harvest,
>                             (pCurrentTimberClass->MerchArea - harvest));
>                     }
> #ifdef _TSB_CANDIDATE_HARVEST_DEBUG
>                     cout << endl << "harvest: trace: candidate->age: " << pCurrentTimberClass->age << endl;
> #endif
> 
>                     if (pApp->m_enableClassSplit == true)
>                     {
>                         // class splitting ENABLED; do not create or leave candidateIter->second area < pApp->m_minSplitThreshold
>                         if ((harvest + FssimUtil::m_kRoundError >= pApp->m_minSplitThreshold) &&
>                             (harvest>FssimUtil::m_kRoundError) &&
>                             ((pCurrentTimberClass->area - harvest >= pApp->m_minSplitThreshold) ||
>                              (pCurrentTimberClass->area - harvest <= FssimUtil::m_kRoundError)))
988,1001c721,723
<                             fprintf(pApp->m_pFileTrace, "\n%6d %10s %10s %10s %6d %8.1f %8.1f | %8.1f %8.1f %8.1f %8.1f || %8.1f <%8.1f>",
<                                 period,
<                                 timber_class->parent_zone->label,
<                                 timber_class->parent_au->label,
<                                 timber_class->parent_block->label,
<                                 timber_class->age,
<                                 timber_class->area,
<                                 timber_class->MerchArea,
<                                 hadj,
<                                 hvol,
<                                 harea,
<                                 haxs,
<                                 harvest,
<                                 (timber_class->MerchArea-harvest));
---
>                             harvest_update_activity(pCurrentTimberClass, harvest, vph);
>                             harvest = pCurrentTimberClass->road(harvest);
>                             pCurrentTimberClass->regenerate(harvest);
1003,1004c725
< 
<                         if (pApp->m_enableClassSplit==true)
---
>                         else
1006,1018c727,728
<                             /* timber_class splitting ENABLED; do not create or leave timber_class area < pApp->m_minSplitThreshold */
<                             if ((harvest+FssimApp::m_kRoundError>=pApp->m_minSplitThreshold)&&(harvest>FssimApp::m_kRoundError)&&
<                                 ((timber_class->area-harvest>=pApp->m_minSplitThreshold)||(timber_class->area-harvest<=FssimApp::m_kRoundError)))
<                             {
<                                 harvest_update_activity(timber_class, harvest, vph, period);
<                                 harvest = road_class(timber_class, harvest, period);
< 
<                                 regen_class(timber_class, harvest, period);
<                             }
<                             else
<                             {
< #ifdef _TSB_HARVEST_DEBUG
<                                 cout << endl << "harvest area < pApp->m_minSplitThreshold; no harvest " << endl;
---
> #ifdef _TSB_AREA_DEBUG
>                            cout << endl << "harvest area < pApp->m_minSplitThreshold; no harvest " << endl;
1020,1021d729
<                                 /* harvest area < pApp->m_minSplitThreshold; no harvest */
<                             }
1022a731,740
>                     }
>                     else
>                     {
>                         // class splitting DISABLED
>                         if (harvest + FssimUtil::m_kRoundError >= pCurrentTimberClass->area)
>                         {
>                             harvest_update_activity(pCurrentTimberClass, harvest, vph);
>                             harvest = pCurrentTimberClass->road(harvest);
>                             pCurrentTimberClass->regenerate(harvest);
>                         }
1025,1038c743,744
<                             /* timber_class splitting DISABLED */
<                             if (harvest+FssimApp::m_kRoundError>=timber_class->area)
<                             {
< 
<                                 harvest_update_activity(timber_class, harvest, vph, period);
< 
<                                 harvest = road_class(timber_class, harvest, period);
< 
<                                 regen_class(timber_class, harvest, period);
<                             }
<                             else
<                             {
< #ifdef _TSB_HARVEST_DEBUG
<                                 cout << "class splitting disabled; no harvest " << endl;
---
> #ifdef _TSB_CLASS_SPLIT_DEBUG
>                            cout << "class splitting disabled; no harvest " << endl;
1040d745
<                             }
1042c747,748
< #ifdef _TSB_HARVEST_DEBUG
---
>                     }
> #ifdef _TSB_DEBUG_OFF
1044,1048c750,754
<                     cout //<< setw(10) << "hadj = "<< setw(3) << hadj
<                          << setw(10) << "hvol = " << setw(3) << hvol
<                          //<< setw(10) << "harea = "<< setw(3) << harea
<                          //<< setw(10) << "haxs = " << setw(3) << haxs
<                          << setw(12) << "harvest = " << setw(3) << harvest << endl;
---
>                     cout //<< setw(10) << "hadj = "<< setw(5) << hadj
>                          //<< setw(10) << "hvol = " << setw(5) << hvol
>                          //<< setw(10) << "harea = "<< setw(5) << harea
>                          //<< setw(10) << "haxs = " << setw(5) << haxs
>                          << setw(12) << "harvest = " << setw(4) << harvest << endl;
1050d755
<                     }
1052,1060d756
< #ifdef _TSB_HARVEST_DEBUG
<                 if (classCounter == 3)
<                 {
<                     exit(1);
<                 }
< #endif
<                 // apply old-growth axs constraint 'straddle factor' on first iteration only
<                 pApp->m_applyFactor = false;
<                 timber_class = (TIMBER_CLASS *)List::next(hashrec->candidates);
1062,1065c758,764
<             hashrec->candidates = (LIST_PTR *)List::done(hashrec->candidates);
<             hashrec->candidates = 0;
< #ifdef _TSB_MEMORY_DEBUG
<             cout << "deleting hashrec at address: " << hex << (hashrec) << endl;
---
>             // reset old-growth axs constraint 'straddle factor' for next timber class
>             pApp->m_applyFactor = false;
> #ifdef _TSB_DEBUG_OFF
>             if (classCounter == 3)
>             {
>                 exit(1);
>             }
1067,1072d765
<             delete hashrec;
<             hashrec = 0;
<             hashrec = (HASHREC *)List::next(pApp->m_candidateList);
< 
<             // apply old-growth axs constraint 'straddle factor' on first iteration only
<             //pApp->m_applyFactor = false;
1074,1077c767
<         pApp->m_candidateList = (LIST_PTR *)List::done(pApp->m_candidateList);
<         pApp->m_candidateList = 0;
< 
<         // apply old-growth axs constraint 'straddle factor' on first iteration only
---
>         // reset old-growth axs constraint 'straddle factor' for next timber class
1078a769,772
> 
>         // done harvest, clear candidate list (doesn't have custody of timber classes)
>         // don't have to clear an empty priority queue (should have popped all candidates by now)
>         //pApp->m_candidateList.clear();
1080a775
> 
