/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA \*---------------------------------------------------------------------------*/ #include "hierarchGeomDecomp.H" #include "addToRunTimeSelectionTable.H" #include "PstreamReduceOps.H" #include "SortableList.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { defineTypeNameAndDebug(hierarchGeomDecomp, 0); addToRunTimeSelectionTable ( decompositionMethod, hierarchGeomDecomp, dictionary ); addToRunTimeSelectionTable ( decompositionMethod, hierarchGeomDecomp, dictionaryMesh ); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void Foam::hierarchGeomDecomp::setDecompOrder() { word order(geomDecomDict_.lookup("order")); if (order.size() != 3) { FatalIOErrorIn ( "hierarchGeomDecomp::hierarchGeomDecomp" "(const dictionary& decompositionDict)", decompositionDict_ ) << "number of characters in order (" << order << ") != 3" << exit(FatalIOError); } for (label i = 0; i < 3; i++) { if (order[i] == 'x') { decompOrder_[i] = 0; } else if (order[i] == 'y') { decompOrder_[i] = 1; } else if (order[i] == 'z') { decompOrder_[i] = 2; } else { FatalIOErrorIn ( "hierarchGeomDecomp::hierarchGeomDecomp" "(const dictionary& decompositionDict)", decompositionDict_ ) << "Illegal decomposition order " << order << endl << "It should only contain x, y or z" << exit(FatalError); } } } Foam::label Foam::hierarchGeomDecomp::findLower ( const List& l, const scalar t, const label initLow, const label initHigh ) { if (initHigh <= initLow) { return initLow; } label low = initLow; label high = initHigh; while ((high - low) > 1) { label mid = (low + high)/2; if (l[mid] < t) { low = mid; } else { high = mid; } } // high and low can still differ by one. Choose best. label tIndex = -1; if (l[high-1] < t) { tIndex = high; } else { tIndex = low; } return tIndex; } // Create a mapping between the index and the weighted size. // For convenience, sortedWeightedSize is one size bigger than current. This // avoids extra tests. void Foam::hierarchGeomDecomp::calculateSortedWeightedSizes ( const labelList& current, const labelList& indices, const scalarField& weights, const label globalCurrentSize, scalarField& sortedWeightedSizes ) { // Evaluate cumulative weights. sortedWeightedSizes[0] = 0; forAll(current, i) { label pointI = current[indices[i]]; sortedWeightedSizes[i + 1] = sortedWeightedSizes[i] + weights[pointI]; } // Non-dimensionalise and multiply by size. scalar globalCurrentLength = returnReduce ( sortedWeightedSizes[current.size()], sumOp() ); // Normalise weights by global sum of weights and multiply through // by global size. sortedWeightedSizes *= (globalCurrentSize/globalCurrentLength); } // Find position in values so between minIndex and this position there // are wantedSize elements. void Foam::hierarchGeomDecomp::findBinary ( const label sizeTol, const List& values, const label minIndex, // index of previous value const scalar minValue, // value at minIndex const scalar maxValue, // global max of values const scalar wantedSize, // wanted size label& mid, // index where size of bin is // wantedSize (to within sizeTol) scalar& midValue // value at mid ) { label low = minIndex; scalar lowValue = minValue; scalar highValue = maxValue; // (one beyond) index of highValue label high = values.size(); // Safeguards to avoid infinite loop. scalar midValuePrev = VGREAT; while (true) { label size = returnReduce(mid-minIndex, sumOp