#include "SzlFileLoader.h"
#include "OrthogonalBisection.h"
#include "AltTecUtil.h"
#include "ThirdPartyHeadersBegin.h"
#include <algorithm>
#include <cmath>
#include <fstream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/make_shared.hpp>
#include <boost/unordered_set.hpp>
#include "ThirdPartyHeadersEnd.h"
#include "zoneUtil.h"
using namespace std; namespace tecplot { namespace ___3933 { OrthogonalBisection::OrthogonalBisection( ___4636               zone, BisectionType_e           bisectionType, ___2090::ItemOffset_t maxDomainSize) : ___2677(zone) , m_bisectionType(bisectionType) , m_maxDomainSize(maxDomainSize) , m_numItems(0) , m_numGhostItems(0) , m_numRecursionDepths(0) { REQUIRE(bisectionType == BisectionType_ZoneCells || bisectionType == BisectionType_ZoneNodes); ___937(); } OrthogonalBisection::~OrthogonalBisection(void) { } void OrthogonalBisection::___937(void) { m_numItems = 0; m_numGhostItems = 0; m_numRecursionDepths = 0; m_numDomains = 0; m_itemList.___937(); m_nodalFieldDataPtrs.___937(); m_ccFieldDataPtrs.___937(); m_reducedPrecisionSortDataArrays.___937(); } namespace {
 #ifdef WIN32
 #pragma warning(disable:4512) 
 #endif
class ZoneCellOrNodeSorter { private: ___1352&        m_fieldData; UInt8Array const& m_reducedPrecisionSortData; public: ZoneCellOrNodeSorter(___1352&        ___1351, UInt8Array const& reducedPrecisionSortData) : m_fieldData(___1351) , m_reducedPrecisionSortData(reducedPrecisionSortData) { } bool operator()(___81 aIndex, ___81 bIndex) const { if ( m_reducedPrecisionSortData[aIndex] != m_reducedPrecisionSortData[bIndex] ) { return m_reducedPrecisionSortData[aIndex] < m_reducedPrecisionSortData[bIndex]; } else { double const aVal = m_fieldData.___1780(aIndex+1); double const bVal = m_fieldData.___1780(bIndex+1); if ( aVal == bVal ) return aIndex < bIndex; else return aVal < bVal; } } }; } namespace { void STDCALL executeBoostFunction(___90 ___2123) { boost::function<void(void)> *___1438 = reinterpret_cast<boost::function<void(void)>* >(___2123); (*___1438)(); delete ___1438; } } ___372 OrthogonalBisection::splitDomain( ___37&                  ___36, ___81                   domainStart, ___81                   domainSize, ___4352                   axisDirToSplit, ___2090::SubzoneOffset_t recursionDepth, ___2120                ___2119) { ___372 ___2039 = ___4226; REQUIRE(domainStart < m_numItems); REQUIRE(domainStart+domainSize <= m_numItems); REQUIRE(axisDirToSplit < NUM_BISECTION_DIRECTIONS); REQUIRE(recursionDepth <= m_numRecursionDepths); REQUIRE(VALID_REF(___2119)); if ( domainSize > m_maxDomainSize ) { ___2039 = calcReducedPrecisionValues(___36, domainStart, domainSize, axisDirToSplit, recursionDepth); ___81 leftOffset; ___81 leftSize; ___81 rightOffset; ___81 rightSize; getSubdomainInfo(domainStart, domainSize, leftOffset, leftSize, rightOffset, rightSize); if ( m_bisectionType == BisectionType_ZoneCells ) { ZoneCellOrNodeSorter zoneCellSorter(*m_ccFieldDataPtrs[axisDirToSplit], m_reducedPrecisionSortDataArrays[axisDirToSplit]); std::nth_element(m_itemList.begin()+domainStart, m_itemList.begin()+domainStart+leftSize, m_itemList.begin()+domainStart+domainSize, zoneCellSorter); } else { ___478(m_bisectionType == BisectionType_ZoneNodes); ZoneCellOrNodeSorter zoneNodeSorter(*m_nodalFieldDataPtrs[axisDirToSplit], m_reducedPrecisionSortDataArrays[axisDirToSplit]); std::nth_element(m_itemList.begin()+domainStart, m_itemList.begin()+domainStart+leftSize, m_itemList.begin()+domainStart+domainSize, zoneNodeSorter); } ___4352 const nextDirection = (axisDirToSplit+1) % NUM_BISECTION_DIRECTIONS; ___2090::SubzoneOffset_t const nextRecursionDepth = recursionDepth+1; if ( recursionDepth < m_maxRecursion && leftSize > m_maxDomainSize ) { boost::function<void(void)>* leftFunction = new boost::function<void(void)>( boost::bind(&OrthogonalBisection::splitDomain, this, boost::ref(___36), leftOffset, leftSize, nextDirection, nextRecursionDepth, ___2119)); ___36.___4156( executeBoostFunction, reinterpret_cast<___90>(leftFunction), ___2119); boost::function<void(void)>* rightFunction = new boost::function<void(void)>( boost::bind(&OrthogonalBisection::splitDomain, this, boost::ref(___36), rightOffset, rightSize, nextDirection, nextRecursionDepth, ___2119)); ___36.___4156( executeBoostFunction, reinterpret_cast<___90>(rightFunction), ___2119); } else { ___2039 = ___2039 && splitDomain(___36, leftOffset, leftSize, nextDirection, nextRecursionDepth, ___2119); ___2039 = ___2039 && splitDomain(___36, rightOffset, rightSize, nextDirection, nextRecursionDepth, ___2119); }
 #if 0 
if ( rightOffset+rightSize == m_numItems ) { boost::function<void(void)>* updateStatusLineFunction = new boost::function<void(void)>( boost::bind(&OrthogonalBisection::updateStatusLine, this, nextRecursionDepth)); TecUtilMainlineInvoke( executeBoostFunction, reinterpret_cast<___90>(updateStatusLineFunction)); }
 #endif
} else { std::sort(m_itemList.begin()+domainStart, m_itemList.begin()+domainStart+domainSize); } return ___2039; } ___372 OrthogonalBisection::updateStatusLine(___37& ___36, ___2090::SubzoneOffset_t recursionDepth) { REQUIRE(m_numRecursionDepths>0); ___372 ___2039 = ___36.___3769(100*recursionDepth/m_numRecursionDepths); return ___2039; } ___372 OrthogonalBisection::loadCoordinateVarZoneFieldData(___37& ___36, char axis) { REQUIRE(axis=='X' || axis=='Y' || axis=='Z'); REQUIRE(m_nodalFieldDataPtrs.size() == size_t(NUM_BISECTION_DIRECTIONS) && m_ccFieldDataPtrs.size() == size_t(NUM_BISECTION_DIRECTIONS)); ___4352 dir = ___4352(axis - 'X'); ___478(dir < NUM_BISECTION_DIRECTIONS); if (___36.___910(___2677 + 1, dir + 1) == ___4330) { m_nodalFieldDataPtrs[dir] = boost::make_shared<___1352>(&___36, ___2677 + 1, dir + 1); m_ccFieldDataPtrs[dir] = boost::make_shared<___1352>(&___36, ___2677 + 1, dir + 1, false  , true /* ___964 */); } else { m_ccFieldDataPtrs[dir] = boost::make_shared<___1352>(&___36, ___2677 + 1, dir + 1); m_nodalFieldDataPtrs[dir] = boost::make_shared<___1352>(&___36, ___2677 + 1, dir + 1, false  , true /* ___964 */); } ___372 ___2039 = (m_nodalFieldDataPtrs[dir] != NULL && m_nodalFieldDataPtrs[dir]->___2067() && m_ccFieldDataPtrs[dir] != NULL && m_ccFieldDataPtrs[dir]->___2067()); return ___2039; } void OrthogonalBisection::getMinMaxWeightOverRange( ___81                   rangeStart, ___81                   ___3268, ___2090::SubzoneOffset_t ___2118, ___2090::SubzoneOffset_t numJobs, ___4352                   axisDirToSplit, ___2479&                      weightMinMax) { REQUIRE(rangeStart < m_numItems); REQUIRE(___3268 > 0 && rangeStart+___3268 <= m_numItems); REQUIRE(___2118 < numJobs); REQUIRE(numJobs > 0); REQUIRE(axisDirToSplit < NUM_BISECTION_DIRECTIONS); REQUIRE("weightMinMax isn't required to be initialized"); ___81 jobStart; ___81 jobEnd; getJobStartEndForRange(rangeStart, ___3268, ___2118, numJobs, jobStart, jobEnd); FieldDataPtr fieldDataPtr; if (m_bisectionType == BisectionType_ZoneCells) fieldDataPtr = m_ccFieldDataPtrs[axisDirToSplit]; else fieldDataPtr = m_nodalFieldDataPtrs[axisDirToSplit]; ___1352& ___1351 = *fieldDataPtr; ___2479 minMax; for (___81 ___2085 = jobStart; ___2085 < jobEnd; ___2085++) { double const weight = ___1351.___1780(m_itemList[___2085] + 1); minMax.include(weight); } weightMinMax = minMax; } void OrthogonalBisection::rescaleWeightsOverRange( ___81                   rangeStart, ___81                   ___3268, ___2090::SubzoneOffset_t ___2118, ___2090::SubzoneOffset_t numJobs, ___4352                   axisDirToSplit, double                       scale, double                       ___2865) { REQUIRE(rangeStart < m_numItems); REQUIRE(___3268 > 0 && rangeStart+___3268 <= m_numItems); REQUIRE(___2118 < numJobs); REQUIRE(numJobs > 0); REQUIRE(axisDirToSplit < NUM_BISECTION_DIRECTIONS); REQUIRE(scale >= 0.0); ___81 jobStart; ___81 jobEnd; getJobStartEndForRange(rangeStart, ___3268, ___2118, numJobs, jobStart, jobEnd); FieldDataPtr fieldDataPtr; if (m_bisectionType == BisectionType_ZoneCells) fieldDataPtr = m_ccFieldDataPtrs[axisDirToSplit]; else fieldDataPtr = m_nodalFieldDataPtrs[axisDirToSplit]; ___1352& ___1351 = *fieldDataPtr; UInt8Array& reducedPrecisionSortData = m_reducedPrecisionSortDataArrays[axisDirToSplit]; ___478(static_cast<___81>(reducedPrecisionSortData.size()) == m_numItems + m_numGhostItems); for (___81 ___2085 = jobStart; ___2085 < jobEnd; ___2085++) { ___2718 const index = ___2718( m_itemList[___2085] ); double const weight = ___1351.___1780(index + 1); double const scaledVal = scale*(weight + ___2865); ___478(0.0 <= scaledVal && scaledVal < 256.0); uint8_t const int8Val = int8_t(scaledVal); reducedPrecisionSortData[index] = int8Val; } } ___372 OrthogonalBisection::calcReducedPrecisionValues( ___37&                  ___36, ___81                   rangeStart, ___81                   ___3268, ___4352                   axisDirToSplit, ___2090::SubzoneOffset_t recursionDepth) { ___372 ___2039 = ___4226; REQUIRE(rangeStart < m_numItems); REQUIRE(___3268 > 0 && rangeStart+___3268 <= m_numItems); REQUIRE(axisDirToSplit < NUM_BISECTION_DIRECTIONS); REQUIRE(recursionDepth < m_numRecursionDepths); static ___2090::SubzoneOffset_t const REDUCED_PRECISION_RECALC_FREQUENCY = 3; if ( recursionDepth % (REDUCED_PRECISION_RECALC_FREQUENCY*NUM_BISECTION_DIRECTIONS) == ___2090::SubzoneOffset_t(axisDirToSplit) ) { ___1352& ___1351 = *m_nodalFieldDataPtrs[axisDirToSplit]; static double const maxNewRange = 255.99; ___478(uint8_t(maxNewRange)==255); ___2479 itemWeightMinMax; if ( recursionDepth < ___2090::SubzoneOffset_t(NUM_BISECTION_DIRECTIONS) ) { double minVal; double maxVal; ___1351.___1759(&minVal, &maxVal); itemWeightMinMax.___3499(minVal, maxVal); } else
{ ___81 const maxThreadsAvailable = (m_maxThreadedJobs >> recursionDepth); ___81 const maxPossibleJobs = ___3268/MIN_THREADED_ITEM_RANGE_SIZE; ___2090::SubzoneOffset_t const numJobs = ___2090::SubzoneOffset_t( std::min(maxThreadsAvailable, maxPossibleJobs) ); if ( numJobs > 1 ) { ___2120 ___2119 = ___36.___4158(); ___2481 jobMinMaxes; if ( ___2119 && jobMinMaxes.alloc(numJobs) ) { try { for ( ___2090::SubzoneOffset_t ___2118 = 0; ___2118 < numJobs; ___2118++ ) { boost::function<void(void)>* getMinMaxFunction = new boost::function<void(void)>( boost::bind(&OrthogonalBisection::getMinMaxWeightOverRange, this, rangeStart, ___3268, ___2118, numJobs, axisDirToSplit, boost::ref(jobMinMaxes[___2118]))); ___36.___4156( executeBoostFunction, reinterpret_cast<___90>(getMinMaxFunction), ___2119); } } catch (...) { ___2039 = ___1305; } ___36.___4161(___2119); ___36.___4159(&___2119); } if ( ___2039 ) { for ( ___2090::SubzoneOffset_t ___2118 = 0; ___2118 < numJobs; ___2118++ ) itemWeightMinMax.include(jobMinMaxes[___2118]); } } else { getMinMaxWeightOverRange(rangeStart, ___3268, 0 , 1/*numJobs*/, axisDirToSplit, itemWeightMinMax); } } if ( ___2039 ) { double const ___2865 = -itemWeightMinMax.minValue(); double const scale = (itemWeightMinMax.maxValue() > itemWeightMinMax.minValue()+___3628) ? maxNewRange / ( itemWeightMinMax.maxValue() - itemWeightMinMax.minValue() ) : 0.; ___81 const maxThreadsAvailable = (m_maxThreadedJobs >> recursionDepth); ___81 const maxPossibleJobs = ___3268/MIN_THREADED_ITEM_RANGE_SIZE; ___2090::SubzoneOffset_t const numJobs = ___2090::SubzoneOffset_t( std::min(maxThreadsAvailable, maxPossibleJobs) ); if ( numJobs > 1 ) { ___2120 ___2119 = ___36.___4158(); if ( ___2119 ) { try { for ( ___2090::SubzoneOffset_t ___2118 = 0; ___2118 < numJobs; ___2118++ ) { boost::function<void(void)>* rescaleFunction = new boost::function<void(void)>( boost::bind(&OrthogonalBisection::rescaleWeightsOverRange, this, rangeStart, ___3268, ___2118, numJobs, axisDirToSplit, scale, ___2865)); ___36.___4156( executeBoostFunction, reinterpret_cast<___90>(rescaleFunction), ___2119); } } catch (...) { ___2039 = ___1305; } ___36.___4161(___2119); ___36.___4159(&___2119); } } else { rescaleWeightsOverRange(rangeStart, ___3268, 0 , 1/*numJobs*/, axisDirToSplit, scale, ___2865); } } } ENSURE(VALID_BOOLEAN(___2039)); return ___2039; } ___372 OrthogonalBisection::performBisection(___37& ___36) { ___372 ___2039 = ___4226; ___36.___858(); double maxThreads = ___36.___4157() * MAX_THREADS_PER_CORE; m_maxRecursion = static_cast<___2090::SubzoneOffset_t>(std::max(1.0, log(maxThreads) / log(2.0))); m_maxThreadedJobs = 1 << m_maxRecursion; ___1844 ___4632; ___36.___4615(___2677 + 1, ___4632); GhostInfo_pa ghostInfo = NULL; if ( m_bisectionType == BisectionType_ZoneCells ) { m_numItems = ___4632.___1668(); ghostInfo = ___36.zoneGhostCellInfoGetRef(___2677 + 1); ___2684 = ___36.___4620(___2677 + 1); ___478(___3894(___2684)); } else { ___478(m_bisectionType == BisectionType_ZoneNodes); m_numItems = ___4632.___1670(); ghostInfo = ___36.zoneGhostNodeInfoGetRef(___2677 + 1); ___2684 = ___4703; } if (ghostInfo) m_numGhostItems = ___36.ghostInfoGetNumItemsByRef(ghostInfo); else m_numGhostItems = 0; m_numItems -= m_numGhostItems; m_numRecursionDepths = calcNumRecursionDepths(); m_numDomains = calcNumDomains(); ___2039 = ___2039 && m_nodalFieldDataPtrs.alloc(NUM_BISECTION_DIRECTIONS); ___2039 = ___2039 && m_ccFieldDataPtrs.alloc(NUM_BISECTION_DIRECTIONS); ___2039 = ___2039 && loadCoordinateVarZoneFieldData(___36, 'X'); ___2039 = ___2039 && loadCoordinateVarZoneFieldData(___36, 'Y'); ___2039 = ___2039 && loadCoordinateVarZoneFieldData(___36, 'Z'); ___2039 = ___2039 && m_itemList.alloc(m_numItems + m_numGhostItems); if ( ___2039 ) { if ( m_numGhostItems > 0 ) { boost::unordered_set<___81> ghostItemSet; for(___81 ___1841 = 0; ___1841 < m_numGhostItems; ++___1841) ghostItemSet.insert(___36.ghostInfoGetItemByRef(ghostInfo, ___1841 + 1) - 1); ___81 realIndex = 0; ___81 ghostIndex = m_numItems; for (___81 ___1841 = 0; ___1841 < m_numItems + m_numGhostItems; ___1841++) { if (ghostItemSet.find(___1841) != ghostItemSet.end()) m_itemList[ghostIndex++] = ___1841; else m_itemList[realIndex++] = ___1841; } ___478(realIndex == static_cast<___81>(m_numItems)); ___478(ghostIndex == m_numItems + m_numGhostItems); } else { for (___81 ___1841 = 0; ___1841 < m_numItems; ___1841++) m_itemList[___1841] = ___1841; } } ___2039 = ___2039 && m_reducedPrecisionSortDataArrays.alloc(NUM_BISECTION_DIRECTIONS); for ( ___4352 dir = 0; ___2039 && dir < NUM_BISECTION_DIRECTIONS; dir++ ) ___2039 = ___2039 && m_reducedPrecisionSortDataArrays[dir].alloc(m_numItems + m_numGhostItems); if ( ___2039 ) { ___2120 ___2119 = ___36.___4158();
if ( ___2119 ) { try { boost::function<void(void)>* splitFunction = new boost::function<void(void)>( boost::bind(&OrthogonalBisection::splitDomain, this, boost::ref(___36), 0 , m_numItems/*size*/, 0/*axisDir*/, 0/*recursionDepth*/, ___2119)); ___36.___4156( executeBoostFunction, reinterpret_cast<___90>(splitFunction), ___2119); } catch (...) { ___2039 = ___1305; } } ___36.___4161(___2119); ___36.___4159(&___2119); } m_reducedPrecisionSortDataArrays.___937(); ___36.___859(); m_nodalFieldDataPtrs.___937(); m_ccFieldDataPtrs.___937(); return ___2039; } void OrthogonalBisection::getSzCoordsByRange( ___81                   rangeStart, ___81                   ___3268, ___2090::SubzoneOffset_t ___2118, ___2090::SubzoneOffset_t numJobs, ItemAddressArray&            szCoordArray) { REQUIRE(rangeStart < m_numItems); REQUIRE(___3268 > 0 && rangeStart+___3268 <= m_numItems); REQUIRE(___2118 < numJobs); REQUIRE(numJobs > 0); REQUIRE(szCoordArray.size()==size_t(m_numItems + m_numGhostItems)); ___81 jobStart; ___81 jobEnd; getJobStartEndForRange(rangeStart, ___3268, ___2118, numJobs, jobStart, jobEnd); ___2090::SubzoneOffset_t const szStart = ___2090::SubzoneOffset_t(jobStart); ___2090::SubzoneOffset_t const szEnd = ___2090::SubzoneOffset_t(jobEnd); ___81 newItem = jobStart*___81(m_maxDomainSize); for ( ___2090::SubzoneOffset_t ___3880 = szStart; ___3880 < szEnd; ___3880++ ) { ___2090::ItemOffset_t subzoneSize = getDomainSize(___3880); for ( ___2090::ItemOffset_t ___2865 = 0; ___2865 < subzoneSize; ___2865++ ) { ___81 const orgItem = queryPositionbyOffset(newItem); szCoordArray[orgItem] = ___2090(___2677, ___3880, ___2865); newItem++; } } } ___372 OrthogonalBisection::getSzCoordByOriginalItemArray(___37& ___36, ItemAddressArray& szCoordByOriginalItem) { REQUIRE(szCoordByOriginalItem.empty()); REQUIRE(m_numItems>0); ___372 ___2039 = szCoordByOriginalItem.alloc(m_numItems + m_numGhostItems); if ( ___2039 ) { ___81 const maxThreadsAvailable = m_maxThreadedJobs; ___81 const maxPossibleJobs = m_numDomains/MIN_THREADED_SUBZONE_RANGE_SIZE; ___2090::SubzoneOffset_t const numJobs = ___2090::SubzoneOffset_t( std::min(maxThreadsAvailable, maxPossibleJobs) ); if ( numJobs > 1 ) { ___2120 ___2119 = ___36.___4158(); if ( ___2119 ) { try { for ( ___2090::SubzoneOffset_t ___2118 = 0; ___2118 < numJobs; ___2118++ ) { boost::function<void(void)>* updateFunction = new boost::function<void(void)>( boost::bind(&OrthogonalBisection::getSzCoordsByRange, this, 0 , m_numDomains/*size*/, ___2118, numJobs, boost::ref(szCoordByOriginalItem))); ___36.___4156( executeBoostFunction, reinterpret_cast<___90>(updateFunction), ___2119); } } catch (...) { ___2039 = ___1305; } ___36.___4161(___2119); ___36.___4159(&___2119); } } else { getSzCoordsByRange(0 , m_numDomains/*___3268*/, 0/*___2118*/, 1/*numJobs*/, szCoordByOriginalItem); } } return ___2039; } }}
