/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation
\\/ 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 3 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, see .
\*---------------------------------------------------------------------------*/
#include "mapNearestMethod.H"
#include "pointIndexHit.H"
#include "indexedOctree.H"
#include "treeDataCell.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(mapNearestMethod, 0);
addToRunTimeSelectionTable(meshToMeshMethod, mapNearestMethod, components);
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
bool Foam::mapNearestMethod::findInitialSeeds
(
const labelList& srcCellIDs,
const boolList& mapFlag,
const label startSeedI,
label& srcSeedI,
label& tgtSeedI
) const
{
const cellList& srcCells = src_.cells();
const faceList& srcFaces = src_.faces();
const pointField& srcPts = src_.points();
for (label i = startSeedI; i < srcCellIDs.size(); i++)
{
label srcI = srcCellIDs[i];
if (mapFlag[srcI])
{
const pointField
pts(srcCells[srcI].points(srcFaces, srcPts).xfer());
const point& pt = pts[0];
pointIndexHit hit = tgt_.cellTree().findNearest(pt, GREAT);
if (hit.hit())
{
srcSeedI = srcI;
tgtSeedI = hit.index();
return true;
}
else
{
FatalErrorIn
(
"bool Foam::mapNearestMethod::findInitialSeeds"
"("
"const labelList&, "
"const boolList&, "
"const label, "
"label&, "
"label&"
") const"
)
<< "Unable to find nearest target cell"
<< " for source cell " << srcI
<< " with centre "
<< srcCells[srcI].centre(srcPts, srcFaces)
<< abort(FatalError);
}
break;
}
}
if (debug)
{
Pout<< "could not find starting seed" << endl;
}
return false;
}
void Foam::mapNearestMethod::calculateAddressing
(
labelListList& srcToTgtCellAddr,
scalarListList& srcToTgtCellWght,
labelListList& tgtToSrcCellAddr,
scalarListList& tgtToSrcCellWght,
const label srcSeedI,
const label tgtSeedI,
const labelList& srcCellIDs,
boolList& mapFlag,
label& startSeedI
)
{
List > srcToTgt(src_.nCells());
List > tgtToSrc(tgt_.nCells());
const scalarField& srcVc = src_.cellVolumes();
const scalarField& tgtVc = tgt_.cellVolumes();
label srcCellI = srcSeedI;
label tgtCellI = tgtSeedI;
do
{
// find nearest tgt cell
findNearestCell(src_, tgt_, srcCellI, tgtCellI);
// store src/tgt cell pair
srcToTgt[srcCellI].append(tgtCellI);
tgtToSrc[tgtCellI].append(srcCellI);
// mark source cell srcCellI and tgtCellI as matched
mapFlag[srcCellI] = false;
// accumulate intersection volume
V_ += srcVc[srcCellI];
// find new source cell
setNextNearestCells
(
startSeedI,
srcCellI,
tgtCellI,
mapFlag,
srcCellIDs
);
}
while (srcCellI >= 0);
// for the case of multiple source cells per target cell, select the
// nearest source cell only and discard the others
const vectorField& srcCc = src_.cellCentres();
const vectorField& tgtCc = tgt_.cellCentres();
forAll(tgtToSrc, targetCellI)
{
if (tgtToSrc[targetCellI].size() > 1)
{
const vector& tgtC = tgtCc[tgtCellI];
DynamicList