mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: Refectored mesh-to-mesh interpolation methods - now run-time selectable
This commit is contained in:
@ -60,10 +60,14 @@ $(meshToMesh)/calculateMeshToMeshAddressing.C
|
||||
$(meshToMesh)/calculateMeshToMeshWeights.C
|
||||
|
||||
meshToMeshNew = meshToMeshInterpolation/meshToMeshNew
|
||||
$(meshToMeshNew)/calcDirect.C
|
||||
$(meshToMeshNew)/calcMapNearest.C
|
||||
$(meshToMeshNew)/calcCellVolumeWeight.C
|
||||
$(meshToMeshNew)/meshToMeshNew.C
|
||||
$(meshToMeshNew)/meshToMeshNewParallelOps.C
|
||||
meshToMeshNewMethods = meshToMeshInterpolation/meshToMeshNew/calcMethod
|
||||
$(meshToMeshNewMethods)/meshToMeshMethod/meshToMeshMethod.C
|
||||
$(meshToMeshNewMethods)/meshToMeshMethod/meshToMeshMethodNew.C
|
||||
$(meshToMeshNewMethods)/cellVolumeWeight/cellVolumeWeightMethod.C
|
||||
$(meshToMeshNewMethods)/direct/directMethod.C
|
||||
$(meshToMeshNewMethods)/mapNearest/mapNearestMethod.C
|
||||
|
||||
|
||||
LIB = $(FOAM_LIBBIN)/libsampling
|
||||
|
||||
@ -1,159 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2012-2013 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "meshToMeshNew.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::meshToMeshNew::calcDirect
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
const label srcSeedI,
|
||||
const label tgtSeedI
|
||||
)
|
||||
{
|
||||
// store a list of src cells already mapped
|
||||
boolList srcSeedFlag(src.nCells(), true);
|
||||
labelList srcTgtSeed(src.nCells(), -1);
|
||||
|
||||
List<DynamicList<label> > srcToTgt(src.nCells());
|
||||
List<DynamicList<label> > tgtToSrc(tgt.nCells());
|
||||
|
||||
DynamicList<label> srcSeeds;
|
||||
|
||||
const scalarField& srcVc = src.cellVolumes();
|
||||
const scalarField& tgtVc = tgt.cellVolumes();
|
||||
|
||||
label srcCellI = srcSeedI;
|
||||
label tgtCellI = tgtSeedI;
|
||||
|
||||
do
|
||||
{
|
||||
// store src/tgt cell pair
|
||||
srcToTgt[srcCellI].append(tgtCellI);
|
||||
tgtToSrc[tgtCellI].append(srcCellI);
|
||||
|
||||
// mark source cell srcSeedI as matched
|
||||
srcSeedFlag[srcCellI] = false;
|
||||
|
||||
// accumulate intersection volume
|
||||
V_ += srcVc[srcCellI];
|
||||
|
||||
// find new source seed cell
|
||||
appendToDirectSeeds
|
||||
(
|
||||
src,
|
||||
tgt,
|
||||
srcSeedFlag,
|
||||
srcTgtSeed,
|
||||
srcSeeds,
|
||||
srcCellI,
|
||||
tgtCellI
|
||||
);
|
||||
}
|
||||
while (srcCellI >= 0);
|
||||
|
||||
// transfer addressing into persistent storage
|
||||
forAll(srcToTgtCellAddr_, i)
|
||||
{
|
||||
scalar v = srcVc[i];
|
||||
srcToTgtCellAddr_[i].transfer(srcToTgt[i]);
|
||||
srcToTgtCellWght_[i] = scalarList(srcToTgtCellAddr_[i].size(), v);
|
||||
}
|
||||
|
||||
forAll(tgtToSrcCellAddr_, i)
|
||||
{
|
||||
scalar v = tgtVc[i];
|
||||
tgtToSrcCellAddr_[i].transfer(tgtToSrc[i]);
|
||||
tgtToSrcCellWght_[i] = scalarList(tgtToSrcCellAddr_[i].size(), v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::meshToMeshNew::appendToDirectSeeds
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
boolList& mapFlag,
|
||||
labelList& srcTgtSeed,
|
||||
DynamicList<label>& srcSeeds,
|
||||
label& srcSeedI,
|
||||
label& tgtSeedI
|
||||
) const
|
||||
{
|
||||
const labelList& srcNbr = src.cellCells()[srcSeedI];
|
||||
const labelList& tgtNbr = tgt.cellCells()[tgtSeedI];
|
||||
|
||||
const vectorField& srcCentre = src.cellCentres();
|
||||
|
||||
forAll(srcNbr, i)
|
||||
{
|
||||
label srcI = srcNbr[i];
|
||||
|
||||
if (mapFlag[srcI] && (srcTgtSeed[srcI] == -1))
|
||||
{
|
||||
// source cell srcI not yet mapped
|
||||
|
||||
// identfy if target cell exists for source cell srcI
|
||||
bool found = false;
|
||||
forAll(tgtNbr, j)
|
||||
{
|
||||
label tgtI = tgtNbr[j];
|
||||
|
||||
if (tgt.pointInCell(srcCentre[srcI], tgtI))
|
||||
{
|
||||
// new match - append to lists
|
||||
found = true;
|
||||
|
||||
srcTgtSeed[srcI] = tgtI;
|
||||
srcSeeds.append(srcI);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
// no match available for source cell srcI
|
||||
mapFlag[srcI] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (srcSeeds.size())
|
||||
{
|
||||
srcSeedI = srcSeeds.remove();
|
||||
tgtSeedI = srcTgtSeed[srcSeedI];
|
||||
}
|
||||
else
|
||||
{
|
||||
srcSeedI = -1;
|
||||
tgtSeedI = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,265 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2012-2013 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "meshToMeshNew.H"
|
||||
#include "ListOps.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::meshToMeshNew::calcMapNearest
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
const label srcSeedI,
|
||||
const label tgtSeedI,
|
||||
const labelList& srcCellIDs,
|
||||
boolList& mapFlag,
|
||||
label& startSeedI
|
||||
)
|
||||
{
|
||||
List<DynamicList<label> > srcToTgt(src.nCells());
|
||||
List<DynamicList<label> > 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,
|
||||
src,
|
||||
tgt,
|
||||
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<label>& srcCells = tgtToSrc[targetCellI];
|
||||
|
||||
label srcCellI = srcCells[0];
|
||||
scalar d = magSqr(tgtC - srcCc[srcCellI]);
|
||||
|
||||
for (label i = 1; i < srcCells.size(); i++)
|
||||
{
|
||||
label srcI = srcCells[i];
|
||||
scalar dNew = magSqr(tgtC - srcCc[srcI]);
|
||||
if (dNew < d)
|
||||
{
|
||||
d = dNew;
|
||||
srcCellI = srcI;
|
||||
}
|
||||
}
|
||||
|
||||
srcCells.clear();
|
||||
srcCells.append(srcCellI);
|
||||
}
|
||||
}
|
||||
|
||||
// If there are more target cells than source cells, some target cells
|
||||
// might not yet be mapped
|
||||
forAll(tgtToSrc, tgtCellI)
|
||||
{
|
||||
if (tgtToSrc[tgtCellI].empty())
|
||||
{
|
||||
label srcCellI = findMappedSrcCell(tgt, tgtCellI, tgtToSrc);
|
||||
|
||||
findNearestCell(tgt, src, tgtCellI, srcCellI);
|
||||
|
||||
tgtToSrc[tgtCellI].append(srcCellI);
|
||||
}
|
||||
}
|
||||
|
||||
// transfer addressing into persistent storage
|
||||
forAll(srcToTgtCellAddr_, i)
|
||||
{
|
||||
scalar v = srcVc[i];
|
||||
srcToTgtCellWght_[i] = scalarList(srcToTgt[i].size(), v);
|
||||
srcToTgtCellAddr_[i].transfer(srcToTgt[i]);
|
||||
}
|
||||
|
||||
forAll(tgtToSrcCellAddr_, i)
|
||||
{
|
||||
scalar v = tgtVc[i];
|
||||
tgtToSrcCellWght_[i] = scalarList(tgtToSrc[i].size(), v);
|
||||
tgtToSrcCellAddr_[i].transfer(tgtToSrc[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::meshToMeshNew::findNearestCell
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
const label srcCellI,
|
||||
label& tgtCellI
|
||||
)
|
||||
{
|
||||
const vectorField& srcC = src.cellCentres();
|
||||
const vectorField& tgtC = tgt.cellCentres();
|
||||
|
||||
const vector& srcP = srcC[srcCellI];
|
||||
|
||||
DynamicList<label> tgtCells(10);
|
||||
tgtCells.append(tgtCellI);
|
||||
|
||||
DynamicList<label> visitedCells(10);
|
||||
|
||||
scalar d = GREAT;
|
||||
|
||||
do
|
||||
{
|
||||
label tgtI = tgtCells.remove();
|
||||
visitedCells.append(tgtI);
|
||||
|
||||
scalar dTest = magSqr(tgtC[tgtI] - srcP);
|
||||
if (dTest < d)
|
||||
{
|
||||
tgtCellI = tgtI;
|
||||
d = dTest;
|
||||
appendNbrCells(tgtCellI, tgt, visitedCells, tgtCells);
|
||||
}
|
||||
|
||||
} while (tgtCells.size() > 0);
|
||||
}
|
||||
|
||||
|
||||
void Foam::meshToMeshNew::setNextNearestCells
|
||||
(
|
||||
label& startSeedI,
|
||||
label& srcCellI,
|
||||
label& tgtCellI,
|
||||
boolList& mapFlag,
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
const labelList& srcCellIDs
|
||||
)
|
||||
{
|
||||
const labelList& srcNbr = src.cellCells()[srcCellI];
|
||||
|
||||
srcCellI = -1;
|
||||
forAll(srcNbr, i)
|
||||
{
|
||||
label cellI = srcNbr[i];
|
||||
if (mapFlag[cellI])
|
||||
{
|
||||
srcCellI = cellI;
|
||||
startSeedI = cellI + 1;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
(void)findInitialSeeds
|
||||
(
|
||||
src,
|
||||
tgt,
|
||||
srcCellIDs,
|
||||
mapFlag,
|
||||
startSeedI,
|
||||
srcCellI,
|
||||
tgtCellI
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Foam::label Foam::meshToMeshNew::findMappedSrcCell
|
||||
(
|
||||
const polyMesh& tgt,
|
||||
const label tgtCellI,
|
||||
const List<DynamicList<label> >& tgtToSrc
|
||||
) const
|
||||
{
|
||||
DynamicList<label> testCells(10);
|
||||
DynamicList<label> visitedCells(10);
|
||||
|
||||
testCells.append(tgtCellI);
|
||||
|
||||
do
|
||||
{
|
||||
// search target tgtCellI neighbours for match with source cell
|
||||
label tgtI = testCells.remove();
|
||||
|
||||
if (findIndex(visitedCells, tgtI) == -1)
|
||||
{
|
||||
visitedCells.append(tgtI);
|
||||
|
||||
if (tgtToSrc[tgtI].size())
|
||||
{
|
||||
return tgtToSrc[tgtI][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
const labelList& nbrCells = tgt.cellCells()[tgtI];
|
||||
|
||||
forAll(nbrCells, i)
|
||||
{
|
||||
if (findIndex(visitedCells, nbrCells[i]) == -1)
|
||||
{
|
||||
testCells.append(nbrCells[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (testCells.size());
|
||||
|
||||
// did not find any match - should not be possible to get here!
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -23,15 +23,79 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "meshToMeshNew.H"
|
||||
#include "tetOverlapVolume.H"
|
||||
#include "cellVolumeWeightMethod.H"
|
||||
#include "indexedOctree.H"
|
||||
#include "treeDataCell.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::meshToMeshNew::calcCellVolumeWeight
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(cellVolumeWeightMethod, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
meshToMeshMethod,
|
||||
cellVolumeWeightMethod,
|
||||
components
|
||||
);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
bool Foam::cellVolumeWeightMethod::findInitialSeeds
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
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());
|
||||
|
||||
forAll(pts, ptI)
|
||||
{
|
||||
const point& pt = pts[ptI];
|
||||
label tgtI = tgt_.cellTree().findInside(pt);
|
||||
|
||||
if (tgtI != -1 && intersect(srcI, tgtI))
|
||||
{
|
||||
srcSeedI = srcI;
|
||||
tgtSeedI = tgtI;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "could not find starting seed" << endl;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Foam::cellVolumeWeightMethod::calculateAddressing
|
||||
(
|
||||
labelListList& srcToTgtCellAddr,
|
||||
scalarListList& srcToTgtCellWght,
|
||||
labelListList& tgtToSrcCellAddr,
|
||||
scalarListList& tgtToSrcCellWght,
|
||||
const label srcSeedI,
|
||||
const label tgtSeedI,
|
||||
const labelList& srcCellIDs,
|
||||
@ -42,11 +106,11 @@ void Foam::meshToMeshNew::calcCellVolumeWeight
|
||||
label srcCellI = srcSeedI;
|
||||
label tgtCellI = tgtSeedI;
|
||||
|
||||
List<DynamicList<label> > srcToTgtAddr(src.nCells());
|
||||
List<DynamicList<scalar> > srcToTgtWght(src.nCells());
|
||||
List<DynamicList<label> > srcToTgtAddr(src_.nCells());
|
||||
List<DynamicList<scalar> > srcToTgtWght(src_.nCells());
|
||||
|
||||
List<DynamicList<label> > tgtToSrcAddr(tgt.nCells());
|
||||
List<DynamicList<scalar> > tgtToSrcWght(tgt.nCells());
|
||||
List<DynamicList<label> > tgtToSrcAddr(tgt_.nCells());
|
||||
List<DynamicList<scalar> > tgtToSrcWght(tgt_.nCells());
|
||||
|
||||
// list of tgt cell neighbour cells
|
||||
DynamicList<label> nbrTgtCells(10);
|
||||
@ -55,10 +119,10 @@ void Foam::meshToMeshNew::calcCellVolumeWeight
|
||||
DynamicList<label> visitedTgtCells(10);
|
||||
|
||||
// list to keep track of tgt cells used to seed src cells
|
||||
labelList seedCells(src.nCells(), -1);
|
||||
labelList seedCells(src_.nCells(), -1);
|
||||
seedCells[srcCellI] = tgtCellI;
|
||||
|
||||
const scalarField& srcVol = src.cellVolumes();
|
||||
const scalarField& srcVol = src_.cellVolumes();
|
||||
|
||||
do
|
||||
{
|
||||
@ -67,14 +131,14 @@ void Foam::meshToMeshNew::calcCellVolumeWeight
|
||||
|
||||
// append initial target cell and neighbours
|
||||
nbrTgtCells.append(tgtCellI);
|
||||
appendNbrCells(tgtCellI, tgt, visitedTgtCells, nbrTgtCells);
|
||||
appendNbrCells(tgtCellI, tgt_, visitedTgtCells, nbrTgtCells);
|
||||
|
||||
do
|
||||
{
|
||||
tgtCellI = nbrTgtCells.remove();
|
||||
visitedTgtCells.append(tgtCellI);
|
||||
|
||||
scalar vol = interVol(src, tgt, srcCellI, tgtCellI);
|
||||
scalar vol = interVol(srcCellI, tgtCellI);
|
||||
|
||||
// accumulate addressing and weights for valid intersection
|
||||
if (vol/srcVol[srcCellI] > tolerance_)
|
||||
@ -86,7 +150,7 @@ void Foam::meshToMeshNew::calcCellVolumeWeight
|
||||
tgtToSrcAddr[tgtCellI].append(srcCellI);
|
||||
tgtToSrcWght[tgtCellI].append(vol);
|
||||
|
||||
appendNbrCells(tgtCellI, tgt, visitedTgtCells, nbrTgtCells);
|
||||
appendNbrCells(tgtCellI, tgt_, visitedTgtCells, nbrTgtCells);
|
||||
|
||||
// accumulate intersection volume
|
||||
V_ += vol;
|
||||
@ -102,8 +166,6 @@ void Foam::meshToMeshNew::calcCellVolumeWeight
|
||||
startSeedI,
|
||||
srcCellI,
|
||||
tgtCellI,
|
||||
src,
|
||||
tgt,
|
||||
srcCellIDs,
|
||||
mapFlag,
|
||||
visitedTgtCells,
|
||||
@ -113,34 +175,32 @@ void Foam::meshToMeshNew::calcCellVolumeWeight
|
||||
while (srcCellI != -1);
|
||||
|
||||
// transfer addressing into persistent storage
|
||||
forAll(srcToTgtCellAddr_, i)
|
||||
forAll(srcToTgtCellAddr, i)
|
||||
{
|
||||
srcToTgtCellAddr_[i].transfer(srcToTgtAddr[i]);
|
||||
srcToTgtCellWght_[i].transfer(srcToTgtWght[i]);
|
||||
srcToTgtCellAddr[i].transfer(srcToTgtAddr[i]);
|
||||
srcToTgtCellWght[i].transfer(srcToTgtWght[i]);
|
||||
}
|
||||
|
||||
forAll(tgtToSrcCellAddr_, i)
|
||||
forAll(tgtToSrcCellAddr, i)
|
||||
{
|
||||
tgtToSrcCellAddr_[i].transfer(tgtToSrcAddr[i]);
|
||||
tgtToSrcCellWght_[i].transfer(tgtToSrcWght[i]);
|
||||
tgtToSrcCellAddr[i].transfer(tgtToSrcAddr[i]);
|
||||
tgtToSrcCellWght[i].transfer(tgtToSrcWght[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::meshToMeshNew::setNextCells
|
||||
void Foam::cellVolumeWeightMethod::setNextCells
|
||||
(
|
||||
label& startSeedI,
|
||||
label& srcCellI,
|
||||
label& tgtCellI,
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
const labelList& srcCellIDs,
|
||||
const boolList& mapFlag,
|
||||
const DynamicList<label>& visitedCells,
|
||||
labelList& seedCells
|
||||
) const
|
||||
{
|
||||
const labelList& srcNbrCells = src.cellCells()[srcCellI];
|
||||
const labelList& srcNbrCells = src_.cellCells()[srcCellI];
|
||||
|
||||
// set possible seeds for later use by querying all src cell neighbours
|
||||
// with all visited target cells
|
||||
@ -155,7 +215,7 @@ void Foam::meshToMeshNew::setNextCells
|
||||
{
|
||||
label cellT = visitedCells[j];
|
||||
|
||||
if (intersect(src, tgt, cellS, cellT))
|
||||
if (intersect(cellS, cellT))
|
||||
{
|
||||
seedCells[cellS] = cellT;
|
||||
|
||||
@ -211,8 +271,6 @@ void Foam::meshToMeshNew::setNextCells
|
||||
bool restart =
|
||||
findInitialSeeds
|
||||
(
|
||||
src,
|
||||
tgt,
|
||||
srcCellIDs,
|
||||
mapFlag,
|
||||
startSeedI,
|
||||
@ -233,68 +291,91 @@ void Foam::meshToMeshNew::setNextCells
|
||||
}
|
||||
|
||||
|
||||
bool Foam::meshToMeshNew::intersect
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::cellVolumeWeightMethod::cellVolumeWeightMethod
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
const label srcCellI,
|
||||
const label tgtCellI
|
||||
) const
|
||||
{
|
||||
scalar threshold = tolerance_*src.cellVolumes()[srcCellI];
|
||||
|
||||
tetOverlapVolume overlapEngine;
|
||||
|
||||
treeBoundBox bbTgtCell
|
||||
(
|
||||
pointField
|
||||
(
|
||||
tgt.points(),
|
||||
tgt.cellPoints()[tgtCellI]
|
||||
)
|
||||
);
|
||||
|
||||
return overlapEngine.cellCellOverlapMinDecomp
|
||||
(
|
||||
src,
|
||||
srcCellI,
|
||||
tgt,
|
||||
tgtCellI,
|
||||
bbTgtCell,
|
||||
threshold
|
||||
);
|
||||
}
|
||||
const polyMesh& tgt
|
||||
)
|
||||
:
|
||||
meshToMeshMethod(src, tgt)
|
||||
{}
|
||||
|
||||
|
||||
Foam::scalar Foam::meshToMeshNew::interVol
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::cellVolumeWeightMethod::~cellVolumeWeightMethod()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::cellVolumeWeightMethod::calculate
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
const label srcCellI,
|
||||
const label tgtCellI
|
||||
) const
|
||||
labelListList& srcToTgtAddr,
|
||||
scalarListList& srcToTgtWght,
|
||||
labelListList& tgtToSrcAddr,
|
||||
scalarListList& tgtToSrcWght
|
||||
)
|
||||
{
|
||||
tetOverlapVolume overlapEngine;
|
||||
|
||||
treeBoundBox bbTgtCell
|
||||
bool ok = initialise
|
||||
(
|
||||
pointField
|
||||
srcToTgtAddr,
|
||||
srcToTgtWght,
|
||||
tgtToSrcAddr,
|
||||
tgtToSrcWght
|
||||
);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// (potentially) participating source mesh cells
|
||||
const labelList srcCellIDs(maskCells());
|
||||
|
||||
// list to keep track of whether src cell can be mapped
|
||||
boolList mapFlag(src_.nCells(), false);
|
||||
UIndirectList<bool>(mapFlag, srcCellIDs) = true;
|
||||
|
||||
// find initial point in tgt mesh
|
||||
label srcSeedI = -1;
|
||||
label tgtSeedI = -1;
|
||||
label startSeedI = 0;
|
||||
|
||||
bool startWalk =
|
||||
findInitialSeeds
|
||||
(
|
||||
tgt.points(),
|
||||
tgt.cellPoints()[tgtCellI]
|
||||
)
|
||||
);
|
||||
srcCellIDs,
|
||||
mapFlag,
|
||||
startSeedI,
|
||||
srcSeedI,
|
||||
tgtSeedI
|
||||
);
|
||||
|
||||
scalar vol = overlapEngine.cellCellOverlapVolumeMinDecomp
|
||||
(
|
||||
src,
|
||||
srcCellI,
|
||||
tgt,
|
||||
tgtCellI,
|
||||
bbTgtCell
|
||||
);
|
||||
|
||||
return vol;
|
||||
if (startWalk)
|
||||
{
|
||||
calculateAddressing
|
||||
(
|
||||
srcToTgtAddr,
|
||||
srcToTgtWght,
|
||||
tgtToSrcAddr,
|
||||
tgtToSrcWght,
|
||||
srcSeedI,
|
||||
tgtSeedI,
|
||||
srcCellIDs,
|
||||
mapFlag,
|
||||
startSeedI
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if meshes are collocated, after inflating the source mesh bounding
|
||||
// box tgt mesh cells may be transferred, but may still not overlap
|
||||
// with the source mesh
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,138 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::cellVolumeWeightMethod
|
||||
|
||||
Description
|
||||
Cell-volume-weighted mesh-to-mesh interpolation class
|
||||
|
||||
Volume conservative.
|
||||
|
||||
SourceFiles
|
||||
cellVolumeWeightMethod.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef cellVolumeWeightMethod_H
|
||||
#define cellVolumeWeightMethod_H
|
||||
|
||||
#include "meshToMeshMethod.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class cellVolumeWeightMethod Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class cellVolumeWeightMethod
|
||||
:
|
||||
public meshToMeshMethod
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Find indices of overlapping cells in src and tgt meshes - returns
|
||||
// true if found a matching pair
|
||||
bool findInitialSeeds
|
||||
(
|
||||
const labelList& srcCellIDs,
|
||||
const boolList& mapFlag,
|
||||
const label startSeedI,
|
||||
label& srcSeedI,
|
||||
label& tgtSeedI
|
||||
) const;
|
||||
|
||||
//- Calculate the mesh-to-mesh addressing and weights
|
||||
void calculateAddressing
|
||||
(
|
||||
labelListList& srcToTgtCellAddr,
|
||||
scalarListList& srcToTgtCellWght,
|
||||
labelListList& tgtToSrcCellAddr,
|
||||
scalarListList& tgtToSrcCellWght,
|
||||
const label srcSeedI,
|
||||
const label tgtSeedI,
|
||||
const labelList& srcCellIDs,
|
||||
boolList& mapFlag,
|
||||
label& startSeedI
|
||||
);
|
||||
|
||||
//- Set the next cells in the advancing front algorithm
|
||||
void setNextCells
|
||||
(
|
||||
label& startSeedI,
|
||||
label& srcCellI,
|
||||
label& tgtCellI,
|
||||
const labelList& srcCellIDs,
|
||||
const boolList& mapFlag,
|
||||
const DynamicList<label>& visitedCells,
|
||||
labelList& seedCells
|
||||
) const;
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
cellVolumeWeightMethod(const cellVolumeWeightMethod&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const cellVolumeWeightMethod&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Run-time type information
|
||||
TypeName("cellVolumeWeight");
|
||||
|
||||
//- Construct from source and target meshes
|
||||
cellVolumeWeightMethod(const polyMesh& src, const polyMesh& tgt);
|
||||
|
||||
//- Destructor
|
||||
virtual ~cellVolumeWeightMethod();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Evaluate
|
||||
|
||||
//- Calculate addressing and weights
|
||||
virtual void calculate
|
||||
(
|
||||
labelListList& srcToTgtAddr,
|
||||
scalarListList& srcToTgtWght,
|
||||
labelListList& tgtToTgtAddr,
|
||||
scalarListList& tgtToTgtWght
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,303 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "directMethod.H"
|
||||
#include "indexedOctree.H"
|
||||
#include "treeDataCell.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(directMethod, 0);
|
||||
addToRunTimeSelectionTable(meshToMeshMethod, directMethod, components);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
bool Foam::directMethod::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());
|
||||
|
||||
forAll(pts, ptI)
|
||||
{
|
||||
const point& pt = pts[ptI];
|
||||
label tgtI = tgt_.cellTree().findInside(pt);
|
||||
|
||||
if (tgtI != -1 && intersect(srcI, tgtI))
|
||||
{
|
||||
srcSeedI = srcI;
|
||||
tgtSeedI = tgtI;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "could not find starting seed" << endl;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Foam::directMethod::calculateAddressing
|
||||
(
|
||||
labelListList& srcToTgtCellAddr,
|
||||
scalarListList& srcToTgtCellWght,
|
||||
labelListList& tgtToSrcCellAddr,
|
||||
scalarListList& tgtToSrcCellWght,
|
||||
const label srcSeedI,
|
||||
const label tgtSeedI,
|
||||
const labelList& srcCellIDs, // not used
|
||||
boolList& mapFlag,
|
||||
label& startSeedI
|
||||
)
|
||||
{
|
||||
// store a list of src cells already mapped
|
||||
labelList srcTgtSeed(src_.nCells(), -1);
|
||||
|
||||
List<DynamicList<label> > srcToTgt(src_.nCells());
|
||||
List<DynamicList<label> > tgtToSrc(tgt_.nCells());
|
||||
|
||||
DynamicList<label> srcSeeds(10);
|
||||
|
||||
const scalarField& srcVc = src_.cellVolumes();
|
||||
const scalarField& tgtVc = tgt_.cellVolumes();
|
||||
|
||||
label srcCellI = srcSeedI;
|
||||
label tgtCellI = tgtSeedI;
|
||||
|
||||
do
|
||||
{
|
||||
// store src/tgt cell pair
|
||||
srcToTgt[srcCellI].append(tgtCellI);
|
||||
tgtToSrc[tgtCellI].append(srcCellI);
|
||||
|
||||
// mark source cell srcSeedI as matched
|
||||
mapFlag[srcCellI] = false;
|
||||
|
||||
// accumulate intersection volume
|
||||
V_ += srcVc[srcCellI];
|
||||
|
||||
// find new source seed cell
|
||||
appendToDirectSeeds
|
||||
(
|
||||
mapFlag,
|
||||
srcTgtSeed,
|
||||
srcSeeds,
|
||||
srcCellI,
|
||||
tgtCellI
|
||||
);
|
||||
}
|
||||
while (srcCellI >= 0);
|
||||
|
||||
// transfer addressing into persistent storage
|
||||
forAll(srcToTgtCellAddr, i)
|
||||
{
|
||||
scalar v = srcVc[i];
|
||||
srcToTgtCellAddr[i].transfer(srcToTgt[i]);
|
||||
srcToTgtCellWght[i] = scalarList(1, v);
|
||||
}
|
||||
|
||||
forAll(tgtToSrcCellAddr, i)
|
||||
{
|
||||
scalar v = tgtVc[i];
|
||||
tgtToSrcCellAddr[i].transfer(tgtToSrc[i]);
|
||||
tgtToSrcCellWght[i] = scalarList(1, v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::directMethod::appendToDirectSeeds
|
||||
(
|
||||
boolList& mapFlag,
|
||||
labelList& srcTgtSeed,
|
||||
DynamicList<label>& srcSeeds,
|
||||
label& srcSeedI,
|
||||
label& tgtSeedI
|
||||
) const
|
||||
{
|
||||
const labelList& srcNbr = src_.cellCells()[srcSeedI];
|
||||
const labelList& tgtNbr = tgt_.cellCells()[tgtSeedI];
|
||||
|
||||
const vectorField& srcCentre = src_.cellCentres();
|
||||
|
||||
forAll(srcNbr, i)
|
||||
{
|
||||
label srcI = srcNbr[i];
|
||||
|
||||
if (mapFlag[srcI] && (srcTgtSeed[srcI] == -1))
|
||||
{
|
||||
// source cell srcI not yet mapped
|
||||
|
||||
// identfy if target cell exists for source cell srcI
|
||||
bool found = false;
|
||||
forAll(tgtNbr, j)
|
||||
{
|
||||
label tgtI = tgtNbr[j];
|
||||
|
||||
if (tgt_.pointInCell(srcCentre[srcI], tgtI))
|
||||
{
|
||||
// new match - append to lists
|
||||
found = true;
|
||||
|
||||
srcTgtSeed[srcI] = tgtI;
|
||||
srcSeeds.append(srcI);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
// no match available for source cell srcI
|
||||
mapFlag[srcI] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (srcSeeds.size())
|
||||
{
|
||||
srcSeedI = srcSeeds.remove();
|
||||
tgtSeedI = srcTgtSeed[srcSeedI];
|
||||
}
|
||||
else
|
||||
{
|
||||
srcSeedI = -1;
|
||||
tgtSeedI = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::directMethod::directMethod
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt
|
||||
)
|
||||
:
|
||||
meshToMeshMethod(src, tgt)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::directMethod::~directMethod()
|
||||
{}
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::directMethod::calculate
|
||||
(
|
||||
labelListList& srcToTgtAddr,
|
||||
scalarListList& srcToTgtWght,
|
||||
labelListList& tgtToSrcAddr,
|
||||
scalarListList& tgtToSrcWght
|
||||
)
|
||||
{
|
||||
bool ok = initialise
|
||||
(
|
||||
srcToTgtAddr,
|
||||
srcToTgtWght,
|
||||
tgtToSrcAddr,
|
||||
tgtToSrcWght
|
||||
);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// (potentially) participating source mesh cells
|
||||
const labelList srcCellIDs(maskCells());
|
||||
|
||||
// list to keep track of whether src cell can be mapped
|
||||
boolList mapFlag(src_.nCells(), false);
|
||||
UIndirectList<bool>(mapFlag, srcCellIDs) = true;
|
||||
|
||||
// find initial point in tgt mesh
|
||||
label srcSeedI = -1;
|
||||
label tgtSeedI = -1;
|
||||
label startSeedI = 0;
|
||||
|
||||
bool startWalk =
|
||||
findInitialSeeds
|
||||
(
|
||||
srcCellIDs,
|
||||
mapFlag,
|
||||
startSeedI,
|
||||
srcSeedI,
|
||||
tgtSeedI
|
||||
);
|
||||
|
||||
if (startWalk)
|
||||
{
|
||||
calculateAddressing
|
||||
(
|
||||
srcToTgtAddr,
|
||||
srcToTgtWght,
|
||||
tgtToSrcAddr,
|
||||
tgtToSrcWght,
|
||||
srcSeedI,
|
||||
tgtSeedI,
|
||||
srcCellIDs,
|
||||
mapFlag,
|
||||
startSeedI
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if meshes are collocated, after inflating the source mesh bounding
|
||||
// box tgt mesh cells may be transferred, but may still not overlap
|
||||
// with the source mesh
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,136 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::directMethod
|
||||
|
||||
Description
|
||||
Direct (one-to-one cell correspondence) mesh-to-mesh interpolation class
|
||||
|
||||
Volume conservative.
|
||||
|
||||
SourceFiles
|
||||
directMethod.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef directMethod_H
|
||||
#define directMethod_H
|
||||
|
||||
#include "meshToMeshMethod.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class directMethod Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class directMethod
|
||||
:
|
||||
public meshToMeshMethod
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Find indices of overlapping cells in src and tgt meshes - returns
|
||||
// true if found a matching pair
|
||||
bool findInitialSeeds
|
||||
(
|
||||
const labelList& srcCellIDs,
|
||||
const boolList& mapFlag,
|
||||
const label startSeedI,
|
||||
label& srcSeedI,
|
||||
label& tgtSeedI
|
||||
) const;
|
||||
|
||||
//- Calculate the mesh-to-mesh addressing and weights
|
||||
void calculateAddressing
|
||||
(
|
||||
labelListList& srcToTgtCellAddr,
|
||||
scalarListList& srcToTgtCellWght,
|
||||
labelListList& tgtToSrcCellAddr,
|
||||
scalarListList& tgtToSrcCellWght,
|
||||
const label srcSeedI,
|
||||
const label tgtSeedI,
|
||||
const labelList& srcCellIDs,
|
||||
boolList& mapFlag,
|
||||
label& startSeedI
|
||||
);
|
||||
|
||||
//- Append to list of src mesh seed indices
|
||||
void appendToDirectSeeds
|
||||
(
|
||||
boolList& mapFlag,
|
||||
labelList& srcTgtSeed,
|
||||
DynamicList<label>& srcSeeds,
|
||||
label& srcSeedI,
|
||||
label& tgtSeedI
|
||||
) const;
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
directMethod(const directMethod&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const directMethod&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Run-time type information
|
||||
TypeName("direct");
|
||||
|
||||
//- Construct from source and target meshes
|
||||
directMethod(const polyMesh& src, const polyMesh& tgt);
|
||||
|
||||
//- Destructor
|
||||
virtual ~directMethod();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Evaluate
|
||||
|
||||
//- Calculate addressing and weights
|
||||
virtual void calculate
|
||||
(
|
||||
labelListList& srcToTgtAddr,
|
||||
scalarListList& srcToTgtWght,
|
||||
labelListList& tgtToTgtAddr,
|
||||
scalarListList& tgtToTgtWght
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,424 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#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<DynamicList<label> > srcToTgt(src_.nCells());
|
||||
List<DynamicList<label> > 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<label>& srcCells = tgtToSrc[targetCellI];
|
||||
|
||||
label srcCellI = srcCells[0];
|
||||
scalar d = magSqr(tgtC - srcCc[srcCellI]);
|
||||
|
||||
for (label i = 1; i < srcCells.size(); i++)
|
||||
{
|
||||
label srcI = srcCells[i];
|
||||
scalar dNew = magSqr(tgtC - srcCc[srcI]);
|
||||
if (dNew < d)
|
||||
{
|
||||
d = dNew;
|
||||
srcCellI = srcI;
|
||||
}
|
||||
}
|
||||
|
||||
srcCells.clear();
|
||||
srcCells.append(srcCellI);
|
||||
}
|
||||
}
|
||||
|
||||
// If there are more target cells than source cells, some target cells
|
||||
// might not yet be mapped
|
||||
forAll(tgtToSrc, tgtCellI)
|
||||
{
|
||||
if (tgtToSrc[tgtCellI].empty())
|
||||
{
|
||||
label srcCellI = findMappedSrcCell(tgtCellI, tgtToSrc);
|
||||
|
||||
findNearestCell(tgt_, src_, tgtCellI, srcCellI);
|
||||
|
||||
tgtToSrc[tgtCellI].append(srcCellI);
|
||||
}
|
||||
}
|
||||
|
||||
// transfer addressing into persistent storage
|
||||
forAll(srcToTgtCellAddr, i)
|
||||
{
|
||||
scalar v = srcVc[i];
|
||||
srcToTgtCellAddr[i].transfer(srcToTgt[i]);
|
||||
srcToTgtCellWght[i] = scalarList(1, v);
|
||||
}
|
||||
|
||||
forAll(tgtToSrcCellAddr, i)
|
||||
{
|
||||
scalar v = tgtVc[i];
|
||||
tgtToSrcCellAddr[i].transfer(tgtToSrc[i]);
|
||||
tgtToSrcCellWght[i] = scalarList(1, v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::mapNearestMethod::findNearestCell
|
||||
(
|
||||
const polyMesh& mesh1,
|
||||
const polyMesh& mesh2,
|
||||
const label cell1,
|
||||
label& cell2
|
||||
) const
|
||||
{
|
||||
const vectorField& Cc1 = mesh1.cellCentres();
|
||||
const vectorField& Cc2 = mesh2.cellCentres();
|
||||
|
||||
const vector& p1 = Cc1[cell1];
|
||||
|
||||
DynamicList<label> cells2(10);
|
||||
cells2.append(cell2);
|
||||
|
||||
DynamicList<label> visitedCells(10);
|
||||
|
||||
scalar d = GREAT;
|
||||
|
||||
do
|
||||
{
|
||||
label c2 = cells2.remove();
|
||||
visitedCells.append(c2);
|
||||
|
||||
scalar dTest = magSqr(Cc2[c2] - p1);
|
||||
if (dTest < d)
|
||||
{
|
||||
cell2 = c2;
|
||||
d = dTest;
|
||||
appendNbrCells(cell2, mesh2, visitedCells, cells2);
|
||||
}
|
||||
|
||||
} while (cells2.size() > 0);
|
||||
}
|
||||
|
||||
|
||||
void Foam::mapNearestMethod::setNextNearestCells
|
||||
(
|
||||
label& startSeedI,
|
||||
label& srcCellI,
|
||||
label& tgtCellI,
|
||||
boolList& mapFlag,
|
||||
const labelList& srcCellIDs
|
||||
) const
|
||||
{
|
||||
const labelList& srcNbr = src_.cellCells()[srcCellI];
|
||||
|
||||
srcCellI = -1;
|
||||
forAll(srcNbr, i)
|
||||
{
|
||||
label cellI = srcNbr[i];
|
||||
if (mapFlag[cellI])
|
||||
{
|
||||
srcCellI = cellI;
|
||||
startSeedI = cellI + 1;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
(void)findInitialSeeds
|
||||
(
|
||||
srcCellIDs,
|
||||
mapFlag,
|
||||
startSeedI,
|
||||
srcCellI,
|
||||
tgtCellI
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Foam::label Foam::mapNearestMethod::findMappedSrcCell
|
||||
(
|
||||
const label tgtCellI,
|
||||
const List<DynamicList<label> >& tgtToSrc
|
||||
) const
|
||||
{
|
||||
DynamicList<label> testCells(10);
|
||||
DynamicList<label> visitedCells(10);
|
||||
|
||||
testCells.append(tgtCellI);
|
||||
|
||||
do
|
||||
{
|
||||
// search target tgtCellI neighbours for match with source cell
|
||||
label tgtI = testCells.remove();
|
||||
|
||||
if (findIndex(visitedCells, tgtI) == -1)
|
||||
{
|
||||
visitedCells.append(tgtI);
|
||||
|
||||
if (tgtToSrc[tgtI].size())
|
||||
{
|
||||
return tgtToSrc[tgtI][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
const labelList& nbrCells = tgt_.cellCells()[tgtI];
|
||||
|
||||
forAll(nbrCells, i)
|
||||
{
|
||||
if (findIndex(visitedCells, nbrCells[i]) == -1)
|
||||
{
|
||||
testCells.append(nbrCells[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (testCells.size());
|
||||
|
||||
// did not find any match - should not be possible to get here!
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::mapNearestMethod::mapNearestMethod
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt
|
||||
)
|
||||
:
|
||||
meshToMeshMethod(src, tgt)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::mapNearestMethod::~mapNearestMethod()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::mapNearestMethod::calculate
|
||||
(
|
||||
labelListList& srcToTgtAddr,
|
||||
scalarListList& srcToTgtWght,
|
||||
labelListList& tgtToSrcAddr,
|
||||
scalarListList& tgtToSrcWght
|
||||
)
|
||||
{
|
||||
bool ok = initialise
|
||||
(
|
||||
srcToTgtAddr,
|
||||
srcToTgtWght,
|
||||
tgtToSrcAddr,
|
||||
tgtToSrcWght
|
||||
);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// (potentially) participating source mesh cells
|
||||
const labelList srcCellIDs(maskCells());
|
||||
|
||||
// list to keep track of whether src cell can be mapped
|
||||
boolList mapFlag(src_.nCells(), false);
|
||||
UIndirectList<bool>(mapFlag, srcCellIDs) = true;
|
||||
|
||||
// find initial point in tgt mesh
|
||||
label srcSeedI = -1;
|
||||
label tgtSeedI = -1;
|
||||
label startSeedI = 0;
|
||||
|
||||
bool startWalk =
|
||||
findInitialSeeds
|
||||
(
|
||||
srcCellIDs,
|
||||
mapFlag,
|
||||
startSeedI,
|
||||
srcSeedI,
|
||||
tgtSeedI
|
||||
);
|
||||
|
||||
if (startWalk)
|
||||
{
|
||||
calculateAddressing
|
||||
(
|
||||
srcToTgtAddr,
|
||||
srcToTgtWght,
|
||||
tgtToSrcAddr,
|
||||
tgtToSrcWght,
|
||||
srcSeedI,
|
||||
tgtSeedI,
|
||||
srcCellIDs,
|
||||
mapFlag,
|
||||
startSeedI
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if meshes are collocated, after inflating the source mesh bounding
|
||||
// box tgt mesh cells may be transferred, but may still not overlap
|
||||
// with the source mesh
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,152 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::mapNearestMethod
|
||||
|
||||
Description
|
||||
Map nearest mesh-to-mesh interpolation class
|
||||
|
||||
Not volume conservative.
|
||||
|
||||
SourceFiles
|
||||
mapNearestMethod.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef mapNearestMethod_H
|
||||
#define mapNearestMethod_H
|
||||
|
||||
#include "meshToMeshMethod.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class mapNearestMethod Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class mapNearestMethod
|
||||
:
|
||||
public meshToMeshMethod
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Find indices of overlapping cells in src and tgt meshes - returns
|
||||
// true if found a matching pair
|
||||
bool findInitialSeeds
|
||||
(
|
||||
const labelList& srcCellIDs,
|
||||
const boolList& mapFlag,
|
||||
const label startSeedI,
|
||||
label& srcSeedI,
|
||||
label& tgtSeedI
|
||||
) const;
|
||||
|
||||
//- Calculate the mesh-to-mesh addressing and weights
|
||||
void calculateAddressing
|
||||
(
|
||||
labelListList& srcToTgtCellAddr,
|
||||
scalarListList& srcToTgtCellWght,
|
||||
labelListList& tgtToSrcCellAddr,
|
||||
scalarListList& tgtToSrcCellWght,
|
||||
const label srcSeedI,
|
||||
const label tgtSeedI,
|
||||
const labelList& srcCellIDs,
|
||||
boolList& mapFlag,
|
||||
label& startSeedI
|
||||
);
|
||||
|
||||
//- Find the nearest cell on mesh2 for cell1 on mesh1
|
||||
void findNearestCell
|
||||
(
|
||||
const polyMesh& mesh1,
|
||||
const polyMesh& mesh2,
|
||||
const label cell1,
|
||||
label& cell2
|
||||
) const;
|
||||
|
||||
//- Set the next cells for the marching front algorithm
|
||||
void setNextNearestCells
|
||||
(
|
||||
label& startSeedI,
|
||||
label& srcCellI,
|
||||
label& tgtCellI,
|
||||
boolList& mapFlag,
|
||||
const labelList& srcCellIDs
|
||||
) const;
|
||||
|
||||
//- Find a source cell mapped to target cell tgtCellI
|
||||
label findMappedSrcCell
|
||||
(
|
||||
const label tgtCellI,
|
||||
const List<DynamicList<label> >& tgtToSrc
|
||||
) const;
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
mapNearestMethod(const mapNearestMethod&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const mapNearestMethod&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Run-time type information
|
||||
TypeName("mapNearest");
|
||||
|
||||
//- Construct from source and target meshes
|
||||
mapNearestMethod(const polyMesh& src, const polyMesh& tgt);
|
||||
|
||||
//- Destructor
|
||||
virtual ~mapNearestMethod();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Evaluate
|
||||
|
||||
//- Calculate addressing and weights
|
||||
virtual void calculate
|
||||
(
|
||||
labelListList& srcToTgtAddr,
|
||||
scalarListList& srcToTgtWght,
|
||||
labelListList& tgtToTgtAddr,
|
||||
scalarListList& tgtToTgtWght
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,274 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "meshToMeshMethod.H"
|
||||
#include "tetOverlapVolume.H"
|
||||
#include "OFstream.H"
|
||||
#include "Time.H"
|
||||
#include "treeBoundBox.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(meshToMeshMethod, 0);
|
||||
defineRunTimeSelectionTable(meshToMeshMethod, components);
|
||||
}
|
||||
|
||||
Foam::scalar Foam::meshToMeshMethod::tolerance_ = 1e-6;
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
Foam::labelList Foam::meshToMeshMethod::maskCells() const
|
||||
{
|
||||
boundBox intersectBb
|
||||
(
|
||||
max(src_.bounds().min(), tgt_.bounds().min()),
|
||||
min(src_.bounds().max(), tgt_.bounds().max())
|
||||
);
|
||||
|
||||
intersectBb.inflate(0.01);
|
||||
|
||||
const cellList& srcCells = src_.cells();
|
||||
const faceList& srcFaces = src_.faces();
|
||||
const pointField& srcPts = src_.points();
|
||||
|
||||
DynamicList<label> cells(src_.nCells());
|
||||
forAll(srcCells, srcI)
|
||||
{
|
||||
boundBox cellBb(srcCells[srcI].points(srcFaces, srcPts), false);
|
||||
if (intersectBb.overlaps(cellBb))
|
||||
{
|
||||
cells.append(srcI);
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "participating source mesh cells: " << cells.size() << endl;
|
||||
}
|
||||
|
||||
return cells;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::meshToMeshMethod::intersect
|
||||
(
|
||||
const label srcCellI,
|
||||
const label tgtCellI
|
||||
) const
|
||||
{
|
||||
scalar threshold = tolerance_*src_.cellVolumes()[srcCellI];
|
||||
|
||||
tetOverlapVolume overlapEngine;
|
||||
|
||||
treeBoundBox bbTgtCell
|
||||
(
|
||||
pointField
|
||||
(
|
||||
tgt_.points(),
|
||||
tgt_.cellPoints()[tgtCellI]
|
||||
)
|
||||
);
|
||||
|
||||
return overlapEngine.cellCellOverlapMinDecomp
|
||||
(
|
||||
src_,
|
||||
srcCellI,
|
||||
tgt_,
|
||||
tgtCellI,
|
||||
bbTgtCell,
|
||||
threshold
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::meshToMeshMethod::interVol
|
||||
(
|
||||
const label srcCellI,
|
||||
const label tgtCellI
|
||||
) const
|
||||
{
|
||||
tetOverlapVolume overlapEngine;
|
||||
|
||||
treeBoundBox bbTgtCell
|
||||
(
|
||||
pointField
|
||||
(
|
||||
tgt_.points(),
|
||||
tgt_.cellPoints()[tgtCellI]
|
||||
)
|
||||
);
|
||||
|
||||
scalar vol = overlapEngine.cellCellOverlapVolumeMinDecomp
|
||||
(
|
||||
src_,
|
||||
srcCellI,
|
||||
tgt_,
|
||||
tgtCellI,
|
||||
bbTgtCell
|
||||
);
|
||||
|
||||
return vol;
|
||||
}
|
||||
|
||||
|
||||
void Foam::meshToMeshMethod::appendNbrCells
|
||||
(
|
||||
const label cellI,
|
||||
const polyMesh& mesh,
|
||||
const DynamicList<label>& visitedCells,
|
||||
DynamicList<label>& nbrCellIDs
|
||||
) const
|
||||
{
|
||||
const labelList& nbrCells = mesh.cellCells()[cellI];
|
||||
|
||||
// filter out cells already visited from cell neighbours
|
||||
forAll(nbrCells, i)
|
||||
{
|
||||
label nbrCellI = nbrCells[i];
|
||||
|
||||
if
|
||||
(
|
||||
(findIndex(visitedCells, nbrCellI) == -1)
|
||||
&& (findIndex(nbrCellIDs, nbrCellI) == -1)
|
||||
)
|
||||
{
|
||||
nbrCellIDs.append(nbrCellI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Foam::meshToMeshMethod::initialise
|
||||
(
|
||||
labelListList& srcToTgtAddr,
|
||||
scalarListList& srcToTgtWght,
|
||||
labelListList& tgtToSrcAddr,
|
||||
scalarListList& tgtToSrcWght
|
||||
) const
|
||||
{
|
||||
srcToTgtAddr.setSize(src_.nCells());
|
||||
srcToTgtWght.setSize(src_.nCells());
|
||||
tgtToSrcAddr.setSize(tgt_.nCells());
|
||||
tgtToSrcWght.setSize(tgt_.nCells());
|
||||
|
||||
if (!src_.nCells())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!tgt_.nCells())
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "mesh interpolation: hhave " << src_.nCells() << " source "
|
||||
<< " cells but no target cells" << endl;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::meshToMeshMethod::meshToMeshMethod
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt
|
||||
)
|
||||
:
|
||||
src_(src),
|
||||
tgt_(tgt),
|
||||
V_(0.0)
|
||||
{
|
||||
if (!src_.nCells() || !tgt_.nCells())
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "mesh interpolation: cells not on processor: Source cells = "
|
||||
<< src_.nCells() << ", target cells = " << tgt_.nCells()
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::meshToMeshMethod::~meshToMeshMethod()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::meshToMeshMethod::writeConnectivity
|
||||
(
|
||||
const polyMesh& mesh1,
|
||||
const polyMesh& mesh2,
|
||||
const labelListList& mesh1ToMesh2Addr
|
||||
) const
|
||||
{
|
||||
Pout<< "Source size = " << mesh1.nCells() << endl;
|
||||
Pout<< "Target size = " << mesh2.nCells() << endl;
|
||||
|
||||
word fName("addressing_" + mesh1.name() + "_to_" + mesh2.name());
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
fName = fName + "_proc" + Foam::name(Pstream::myProcNo());
|
||||
}
|
||||
|
||||
OFstream os(src_.time().path()/fName + ".obj");
|
||||
|
||||
label vertI = 0;
|
||||
forAll(mesh1ToMesh2Addr, i)
|
||||
{
|
||||
const labelList& addr = mesh1ToMesh2Addr[i];
|
||||
forAll(addr, j)
|
||||
{
|
||||
label cellI = addr[j];
|
||||
const vector& c0 = mesh1.cellCentres()[i];
|
||||
|
||||
const cell& c = mesh2.cells()[cellI];
|
||||
const pointField pts(c.points(mesh2.faces(), mesh2.points()));
|
||||
forAll(pts, j)
|
||||
{
|
||||
const point& p = pts[j];
|
||||
os << "v " << p.x() << ' ' << p.y() << ' ' << p.z() << nl;
|
||||
vertI++;
|
||||
os << "v " << c0.x() << ' ' << c0.y() << ' ' << c0.z()
|
||||
<< nl;
|
||||
vertI++;
|
||||
os << "l " << vertI - 1 << ' ' << vertI << nl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,188 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::meshToMeshMethod
|
||||
|
||||
Description
|
||||
Base class for mesh-to-mesh calculation methods
|
||||
|
||||
SourceFiles
|
||||
meshToMeshMethod.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef meshToMeshMethod_H
|
||||
#define meshToMeshMethod_H
|
||||
|
||||
#include "polyMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class meshToMeshMethod Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class meshToMeshMethod
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Reference to the source mesh
|
||||
const polyMesh& src_;
|
||||
|
||||
//- Reference to the target mesh
|
||||
const polyMesh& tgt_;
|
||||
|
||||
//- Cell total volume in overlap region [m3]
|
||||
scalar V_;
|
||||
|
||||
//- Tolerance used in volume overlap calculations
|
||||
static scalar tolerance_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Return src cell IDs for the overlap region
|
||||
labelList maskCells() const;
|
||||
|
||||
//- Return the true if cells intersect
|
||||
bool intersect(const label srcCellI, const label tgtCellI) const;
|
||||
|
||||
//- Return the intersection volume between two cells
|
||||
scalar interVol(const label srcCellI, const label tgtCellI) const;
|
||||
|
||||
//- Append target cell neihgbour cells to cellIDs list
|
||||
void appendNbrCells
|
||||
(
|
||||
const label tgtCellI,
|
||||
const polyMesh& mesh,
|
||||
const DynamicList<label>& visitedTgtCells,
|
||||
DynamicList<label>& nbrTgtCellIDs
|
||||
) const;
|
||||
|
||||
bool initialise
|
||||
(
|
||||
labelListList& srcToTgtAddr,
|
||||
scalarListList& srcToTgtWght,
|
||||
labelListList& tgtToTgtAddr,
|
||||
scalarListList& tgtToTgtWght
|
||||
) const;
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
meshToMeshMethod(const meshToMeshMethod&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const meshToMeshMethod&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Run-time type information
|
||||
TypeName("meshToMeshMethod");
|
||||
|
||||
//- Declare runtime constructor selection table
|
||||
declareRunTimeSelectionTable
|
||||
(
|
||||
autoPtr,
|
||||
meshToMeshMethod,
|
||||
components,
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt
|
||||
),
|
||||
(src, tgt)
|
||||
);
|
||||
|
||||
//- Construct from source and target meshes
|
||||
meshToMeshMethod(const polyMesh& src, const polyMesh& tgt);
|
||||
|
||||
//- Selector
|
||||
static autoPtr<meshToMeshMethod> New
|
||||
(
|
||||
const word& methodName,
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~meshToMeshMethod();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Evaluate
|
||||
|
||||
//- Calculate addressing and weights
|
||||
virtual void calculate
|
||||
(
|
||||
labelListList& srcToTgtAddr,
|
||||
scalarListList& srcToTgtWght,
|
||||
labelListList& tgtToTgtAddr,
|
||||
scalarListList& tgtToTgtWght
|
||||
) = 0;
|
||||
|
||||
|
||||
// Access
|
||||
|
||||
//- Return const access to the source mesh
|
||||
inline const polyMesh& src() const;
|
||||
|
||||
//- Return const access to the target mesh
|
||||
inline const polyMesh& tgt() const;
|
||||
|
||||
//- Return const access to the overlap volume
|
||||
inline scalar V() const;
|
||||
|
||||
|
||||
// Check
|
||||
|
||||
//- Write the connectivity (debugging)
|
||||
void writeConnectivity
|
||||
(
|
||||
const polyMesh& mesh1,
|
||||
const polyMesh& mesh2,
|
||||
const labelListList& mesh1ToMesh2Addr
|
||||
) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "meshToMeshMethodI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,44 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
const Foam::polyMesh& Foam::meshToMeshMethod::src() const
|
||||
{
|
||||
return src_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::polyMesh& Foam::meshToMeshMethod::tgt() const
|
||||
{
|
||||
return tgt_;
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::meshToMeshMethod::V() const
|
||||
{
|
||||
return V_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,65 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "meshToMeshMethod.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::autoPtr<Foam::meshToMeshMethod> Foam::meshToMeshMethod::New
|
||||
(
|
||||
const word& methodName,
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt
|
||||
)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Selecting AMIMethod " << methodName << endl;
|
||||
}
|
||||
|
||||
componentsConstructorTable::iterator cstrIter =
|
||||
componentsConstructorTablePtr_->find(methodName);
|
||||
|
||||
if (cstrIter == componentsConstructorTablePtr_->end())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"Foam::autoPtr<Foam::meshToMeshMethod> Foam::meshToMeshMethod::New"
|
||||
"("
|
||||
"const word&, "
|
||||
"const polyMesh&, "
|
||||
"const polyMesh&"
|
||||
")"
|
||||
) << "Unknown meshToMesh type "
|
||||
<< methodName << nl << nl
|
||||
<< "Valid meshToMesh types are:" << nl
|
||||
<< componentsConstructorTablePtr_->sortedToc() << exit(FatalError);
|
||||
}
|
||||
|
||||
return autoPtr<meshToMeshMethod>(cstrIter()(src, tgt));
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -24,14 +24,9 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "meshToMeshNew.H"
|
||||
#include "OFstream.H"
|
||||
#include "Time.H"
|
||||
#include "globalIndex.H"
|
||||
#include "mergePoints.H"
|
||||
#include "treeBoundBox.H"
|
||||
#include "indexedOctree.H"
|
||||
#include "treeDataCell.H"
|
||||
#include "ListOps.H"
|
||||
#include "meshToMeshMethod.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
@ -55,55 +50,9 @@ namespace Foam
|
||||
meshToMeshNew::interpolationMethodNames_;
|
||||
}
|
||||
|
||||
Foam::scalar Foam::meshToMeshNew::tolerance_ = 1e-6;
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::meshToMeshNew::writeConnectivity
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
const labelListList& srcToTargetAddr
|
||||
) const
|
||||
{
|
||||
Pout<< "Source size = " << src.nCells() << endl;
|
||||
Pout<< "Target size = " << tgt.nCells() << endl;
|
||||
|
||||
word fName("addressing_" + src.name() + "_to_" + tgt.name());
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
fName = fName + "_proc" + Foam::name(Pstream::myProcNo());
|
||||
}
|
||||
|
||||
OFstream os(src.time().path()/fName + ".obj");
|
||||
|
||||
label vertI = 0;
|
||||
forAll(srcToTargetAddr, i)
|
||||
{
|
||||
const labelList& tgtAddress = srcToTargetAddr[i];
|
||||
forAll(tgtAddress, j)
|
||||
{
|
||||
label tgtI = tgtAddress[j];
|
||||
const vector& c0 = src.cellCentres()[i];
|
||||
|
||||
const cell& c = tgt.cells()[tgtI];
|
||||
const pointField pts(c.points(tgt.faces(), tgt.points()));
|
||||
forAll(pts, j)
|
||||
{
|
||||
const point& p = pts[j];
|
||||
os << "v " << p.x() << ' ' << p.y() << ' ' << p.z() << nl;
|
||||
vertI++;
|
||||
os << "v " << c0.x() << ' ' << c0.y() << ' ' << c0.z()
|
||||
<< nl;
|
||||
vertI++;
|
||||
os << "l " << vertI - 1 << ' ' << vertI << nl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::meshToMeshNew::maskCells
|
||||
(
|
||||
const polyMesh& src,
|
||||
@ -141,146 +90,6 @@ Foam::labelList Foam::meshToMeshNew::maskCells
|
||||
}
|
||||
|
||||
|
||||
bool Foam::meshToMeshNew::findInitialSeeds
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
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());
|
||||
|
||||
switch (method_)
|
||||
{
|
||||
case imDirect:
|
||||
case imCellVolumeWeight:
|
||||
{
|
||||
forAll(pts, ptI)
|
||||
{
|
||||
const point& pt = pts[ptI];
|
||||
label tgtI = tgt.cellTree().findInside(pt);
|
||||
|
||||
if (tgtI != -1 && intersect(src, tgt, srcI, tgtI))
|
||||
{
|
||||
srcSeedI = srcI;
|
||||
tgtSeedI = tgtI;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case imMapNearest:
|
||||
{
|
||||
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::meshToMeshNew::findInitialSeeds"
|
||||
"("
|
||||
"const polyMesh&, "
|
||||
"const polyMesh&, "
|
||||
"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;
|
||||
}
|
||||
default:
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"bool Foam::meshToMeshNew::findInitialSeeds"
|
||||
"("
|
||||
"const polyMesh&, "
|
||||
"const polyMesh&, "
|
||||
"const labelList&, "
|
||||
"const boolList&, "
|
||||
"const label, "
|
||||
"label&, "
|
||||
"label&"
|
||||
") const"
|
||||
)
|
||||
<< "Unhandled method: "
|
||||
<< interpolationMethodNames_[method_]
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "could not find starting seed" << endl;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Foam::meshToMeshNew::appendNbrCells
|
||||
(
|
||||
const label cellI,
|
||||
const polyMesh& mesh,
|
||||
const DynamicList<label>& visitedCells,
|
||||
DynamicList<label>& nbrCellIDs
|
||||
) const
|
||||
{
|
||||
const labelList& nbrCells = mesh.cellCells()[cellI];
|
||||
|
||||
// filter out cells already visited from cell neighbours
|
||||
forAll(nbrCells, i)
|
||||
{
|
||||
label nbrCellI = nbrCells[i];
|
||||
|
||||
if
|
||||
(
|
||||
(findIndex(visitedCells, nbrCellI) == -1)
|
||||
&& (findIndex(nbrCellIDs, nbrCellI) == -1)
|
||||
)
|
||||
{
|
||||
nbrCellIDs.append(nbrCellI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::meshToMeshNew::normaliseWeights
|
||||
(
|
||||
const word& descriptor,
|
||||
@ -324,124 +133,29 @@ void Foam::meshToMeshNew::calcAddressing
|
||||
const polyMesh& tgt
|
||||
)
|
||||
{
|
||||
srcToTgtCellAddr_.setSize(src.nCells());
|
||||
srcToTgtCellWght_.setSize(src.nCells());
|
||||
|
||||
tgtToSrcCellAddr_.setSize(tgt.nCells());
|
||||
tgtToSrcCellWght_.setSize(tgt.nCells());
|
||||
|
||||
if (!src.nCells() || !tgt.nCells())
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "mesh interpolation: cells not on processor: Source cells = "
|
||||
<< src.nCells() << ", target cells = " << tgt.nCells()
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (!src.nCells())
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (!tgt.nCells())
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "mesh interpolation: hhave " << src.nCells() << " source "
|
||||
<< " cells but no target cells" << endl;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// (potentially) participating source mesh cells
|
||||
const labelList srcCellIDs = maskCells(src, tgt);
|
||||
|
||||
// list to keep track of whether src cell can be mapped
|
||||
boolList mapFlag(src.nCells(), false);
|
||||
UIndirectList<bool>(mapFlag, srcCellIDs) = true;
|
||||
|
||||
// find initial point in tgt mesh
|
||||
label srcSeedI = -1;
|
||||
label tgtSeedI = -1;
|
||||
label startSeedI = 0;
|
||||
|
||||
bool startWalk =
|
||||
findInitialSeeds
|
||||
autoPtr<meshToMeshMethod> methodPtr
|
||||
(
|
||||
meshToMeshMethod::New
|
||||
(
|
||||
interpolationMethodNames_[method_],
|
||||
src,
|
||||
tgt,
|
||||
srcCellIDs,
|
||||
mapFlag,
|
||||
startSeedI,
|
||||
srcSeedI,
|
||||
tgtSeedI
|
||||
);
|
||||
tgt
|
||||
)
|
||||
);
|
||||
|
||||
if (!startWalk)
|
||||
{
|
||||
// if meshes are collocated, after inflating the source mesh bounding
|
||||
// box tgt mesh cells may be transferred, but may still not overlap
|
||||
// with the source mesh
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
switch (method_)
|
||||
{
|
||||
case imDirect:
|
||||
{
|
||||
calcDirect(src, tgt, srcSeedI, tgtSeedI);
|
||||
break;
|
||||
}
|
||||
case imMapNearest:
|
||||
{
|
||||
calcMapNearest
|
||||
(
|
||||
src,
|
||||
tgt,
|
||||
srcSeedI,
|
||||
tgtSeedI,
|
||||
srcCellIDs,
|
||||
mapFlag,
|
||||
startSeedI
|
||||
);
|
||||
break;
|
||||
}
|
||||
case imCellVolumeWeight:
|
||||
{
|
||||
calcCellVolumeWeight
|
||||
(
|
||||
src,
|
||||
tgt,
|
||||
srcSeedI,
|
||||
tgtSeedI,
|
||||
srcCellIDs,
|
||||
mapFlag,
|
||||
startSeedI
|
||||
);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void Foam::meshToMeshNew::calcAddressing"
|
||||
"("
|
||||
"const polyMesh&, "
|
||||
"const polyMesh&"
|
||||
")"
|
||||
)
|
||||
<< "Unknown interpolation method"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
methodPtr->calculate
|
||||
(
|
||||
srcToTgtCellAddr_,
|
||||
srcToTgtCellWght_,
|
||||
tgtToSrcCellAddr_,
|
||||
tgtToSrcCellWght_
|
||||
);
|
||||
|
||||
V_ = methodPtr->V();
|
||||
|
||||
if (debug)
|
||||
{
|
||||
writeConnectivity(src, tgt, srcToTgtCellAddr_);
|
||||
methodPtr->writeConnectivity(src, tgt, srcToTgtCellAddr_);
|
||||
}
|
||||
}
|
||||
|
||||
@ -688,6 +402,12 @@ Foam::meshToMeshNew::patchAMIs() const
|
||||
{
|
||||
if (patchAMIs_.empty())
|
||||
{
|
||||
const word amiMethod =
|
||||
AMIPatchToPatchInterpolation::interpolationMethodToWord
|
||||
(
|
||||
interpolationMethodAMI(method_)
|
||||
);
|
||||
|
||||
patchAMIs_.setSize(srcPatchID_.size());
|
||||
|
||||
forAll(srcPatchID_, i)
|
||||
@ -700,7 +420,7 @@ Foam::meshToMeshNew::patchAMIs() const
|
||||
|
||||
Info<< "Creating AMI between source patch " << srcPP.name()
|
||||
<< " and target patch " << tgtPP.name()
|
||||
<< " using " << interpolationMethodAMI(method_)
|
||||
<< " using " << amiMethod
|
||||
<< endl;
|
||||
|
||||
Info<< incrIndent;
|
||||
|
||||
@ -27,20 +27,14 @@ Class
|
||||
Description
|
||||
Class to calculate the cell-addressing between two overlapping meshes
|
||||
|
||||
Three methods are currently available:
|
||||
- direct : 1-to-1 mapping between meshes
|
||||
- mapNearest : assign nearest cell values without interpolation
|
||||
- cellVolumeWeight : volume consistent mapping
|
||||
|
||||
The \c direct and \c cellVolumeWeight options are volume conservative,
|
||||
whereas mapNearest is non-conservative.
|
||||
Mapping is performed using a run-time selectable interpolation mothod
|
||||
|
||||
SeeAlso
|
||||
meshToMeshMethod
|
||||
|
||||
SourceFiles
|
||||
calcDirect.C
|
||||
calcMapNearest.C
|
||||
calcCellVolumeWeight.C
|
||||
meshToMeshNew.C
|
||||
meshToMeshNewParallelOps.C
|
||||
meshToMeshNewTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -128,9 +122,6 @@ private:
|
||||
//- Target map pointer - parallel running only
|
||||
autoPtr<mapDistribute> tgtMapPtr_;
|
||||
|
||||
//- Tolerance used in volume overlap calculations
|
||||
static scalar tolerance_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
@ -138,39 +129,9 @@ private:
|
||||
template<class Type>
|
||||
void add(UList<Type>& fld, const label offset) const;
|
||||
|
||||
//- Write the connectivity (debugging)
|
||||
void writeConnectivity
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
const labelListList& srcToTargetAddr
|
||||
) const;
|
||||
|
||||
//- Return src cell IDs for the overlap region
|
||||
labelList maskCells(const polyMesh& src, const polyMesh& tgt) const;
|
||||
|
||||
//- Find indices of overlapping cells in src and tgt meshes - returns
|
||||
// true if found a matching pair
|
||||
bool findInitialSeeds
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
const labelList& srcCellIDs,
|
||||
const boolList& mapFlag,
|
||||
const label startSeedI,
|
||||
label& srcSeedI,
|
||||
label& tgtSeedI
|
||||
) const;
|
||||
|
||||
//- Append target cell neihgbour cells to cellIDs list
|
||||
void appendNbrCells
|
||||
(
|
||||
const label tgtCellI,
|
||||
const polyMesh& tgt,
|
||||
const DynamicList<label>& visitedTgtCells,
|
||||
DynamicList<label>& nbrTgtCellIDs
|
||||
) const;
|
||||
|
||||
//- Normalise the interpolation weights
|
||||
void normaliseWeights
|
||||
(
|
||||
@ -180,121 +141,6 @@ private:
|
||||
scalarListList& wght
|
||||
) const;
|
||||
|
||||
|
||||
// Direct (one-to-one) mapping
|
||||
|
||||
//- Main driver routine for direct mapping
|
||||
void calcDirect
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
const label srcSeedI,
|
||||
const label tgtSeedI
|
||||
);
|
||||
|
||||
//- Append to list of src mesh seed indices
|
||||
void appendToDirectSeeds
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
boolList& mapFlag,
|
||||
labelList& srcTgtSeed,
|
||||
DynamicList<label>& srcSeeds,
|
||||
label& srcSeedI,
|
||||
label& tgtSeedI
|
||||
) const;
|
||||
|
||||
// Nearest (non-conformal) mapping
|
||||
|
||||
//- Main driver routine for nearest-mapping routine
|
||||
void calcMapNearest
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
const label srcSeedI,
|
||||
const label tgtSeedI,
|
||||
const labelList& srcCellIDs,
|
||||
boolList& mapFlag,
|
||||
label& startSeedI
|
||||
);
|
||||
|
||||
//- Find target cell index of cell closest to source cell
|
||||
void findNearestCell
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
const label srcCellI,
|
||||
label& tgtCellI
|
||||
);
|
||||
|
||||
//- Set the next pair of cells
|
||||
void setNextNearestCells
|
||||
(
|
||||
label& startSeedI,
|
||||
label& srcCellI,
|
||||
label& tgtCellI,
|
||||
boolList& mapFlag,
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
const labelList& srcCellIDs
|
||||
);
|
||||
|
||||
//- Find source cell for target cell
|
||||
label findMappedSrcCell
|
||||
(
|
||||
const polyMesh& tgt,
|
||||
const label tgtCellI,
|
||||
const List<DynamicList<label> >& tgtToSrc
|
||||
) const;
|
||||
|
||||
|
||||
// Cell volume weighted (non-conformal) interpolation
|
||||
|
||||
//- Main driver routine for cell volume weighted interpolation
|
||||
void calcCellVolumeWeight
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
const label srcSeedI,
|
||||
const label tgtSeedI,
|
||||
const labelList& srcCellIDs,
|
||||
boolList& mapFlag,
|
||||
label& startSeedI
|
||||
);
|
||||
|
||||
//- Set the next cells in the advancing front algorithm
|
||||
void setNextCells
|
||||
(
|
||||
label& startSeedI,
|
||||
label& srcCellI,
|
||||
label& tgtCellI,
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
const labelList& srcCellIDs,
|
||||
const boolList& mapFlag,
|
||||
const DynamicList<label>& visitedCells,
|
||||
labelList& seedCells
|
||||
) const;
|
||||
|
||||
//- Return the true if cells intersect
|
||||
bool intersect
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
const label srcCellI,
|
||||
const label tgtCellI
|
||||
) const;
|
||||
|
||||
//- Return the intersection volume between two cells
|
||||
scalar interVol
|
||||
(
|
||||
const polyMesh& src,
|
||||
const polyMesh& tgt,
|
||||
const label srcCellI,
|
||||
const label tgtCellI
|
||||
) const;
|
||||
|
||||
|
||||
//- Calculate the addressing between overalping regions of src and tgt
|
||||
// meshes
|
||||
void calcAddressing(const polyMesh& src, const polyMesh& tgt);
|
||||
|
||||
Reference in New Issue
Block a user