mapFields: Reinstated mapFields from OpenFOAM-2.2.x and renamed the current mapFields -> mapFieldsPar

This required the addition of the meshToMesh class in the sampling
library from OpenFOAM-2.2.x which is now named meshToMesh0.
This commit is contained in:
Henry
2015-05-26 11:32:46 +01:00
parent 1c2b2f2fa9
commit cfe1163dc8
45 changed files with 3804 additions and 278 deletions

View File

@ -55,15 +55,18 @@ graphField/writePatchGraph.C
graphField/writeCellGraph.C
graphField/makeGraph.C
meshToMesh = meshToMeshInterpolation/meshToMesh
$(meshToMesh)/meshToMesh.C
$(meshToMesh)/meshToMeshParallelOps.C
meshToMeshMethods = meshToMeshInterpolation/meshToMesh/calcMethod
meshToMesh/meshToMesh.C
meshToMesh/meshToMeshParallelOps.C
meshToMeshMethods = meshToMesh/calcMethod
$(meshToMeshMethods)/meshToMeshMethod/meshToMeshMethod.C
$(meshToMeshMethods)/meshToMeshMethod/meshToMeshMethodNew.C
$(meshToMeshMethods)/cellVolumeWeight/cellVolumeWeightMethod.C
$(meshToMeshMethods)/direct/directMethod.C
$(meshToMeshMethods)/mapNearest/mapNearestMethod.C
meshToMesh0/meshToMesh0.C
meshToMesh0/calculateMeshToMesh0Addressing.C
meshToMesh0/calculateMeshToMesh0Weights.C
LIB = $(FOAM_LIBBIN)/libsampling

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -0,0 +1,343 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 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/>.
Description
private member of meshToMesh0.
Calculates mesh to mesh addressing pattern (for each cell from one mesh
find the closest cell centre in the other mesh).
\*---------------------------------------------------------------------------*/
#include "meshToMesh0.H"
#include "SubField.H"
#include "indexedOctree.H"
#include "treeDataCell.H"
#include "treeDataFace.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::meshToMesh0::calcAddressing()
{
if (debug)
{
Info<< "meshToMesh0::calculateAddressing() : "
<< "calculating mesh-to-mesh cell addressing" << endl;
}
// set reference to cells
const cellList& fromCells = fromMesh_.cells();
const pointField& fromPoints = fromMesh_.points();
// In an attempt to preserve the efficiency of linear search and prevent
// failure, a RESCUE mechanism will be set up. Here, we shall mark all
// cells next to the solid boundaries. If such a cell is found as the
// closest, the relationship between the origin and cell will be examined.
// If the origin is outside the cell, a global n-squared search is
// triggered.
// SETTING UP RESCUE
// visit all boundaries and mark the cell next to the boundary.
if (debug)
{
Info<< "meshToMesh0::calculateAddressing() : "
<< "Setting up rescue" << endl;
}
List<bool> boundaryCell(fromCells.size(), false);
// set reference to boundary
const polyPatchList& patchesFrom = fromMesh_.boundaryMesh();
forAll(patchesFrom, patchI)
{
// get reference to cells next to the boundary
const labelUList& bCells = patchesFrom[patchI].faceCells();
forAll(bCells, faceI)
{
boundaryCell[bCells[faceI]] = true;
}
}
treeBoundBox meshBb(fromPoints);
scalar typDim = meshBb.avgDim()/(2.0*cbrt(scalar(fromCells.size())));
treeBoundBox shiftedBb
(
meshBb.min(),
meshBb.max() + vector(typDim, typDim, typDim)
);
if (debug)
{
Info<< "\nMesh" << endl;
Info<< " bounding box : " << meshBb << endl;
Info<< " bounding box (shifted) : " << shiftedBb << endl;
Info<< " typical dimension :" << shiftedBb.typDim() << endl;
}
indexedOctree<treeDataCell> oc
(
treeDataCell(false, fromMesh_, polyMesh::FACE_DIAG_TRIS),
shiftedBb, // overall bounding box
8, // maxLevel
10, // leafsize
6.0 // duplicity
);
if (debug)
{
oc.print(Pout, false, 0);
}
cellAddresses
(
cellAddressing_,
toMesh_.cellCentres(),
fromMesh_,
boundaryCell,
oc
);
forAll(toMesh_.boundaryMesh(), patchi)
{
const polyPatch& toPatch = toMesh_.boundaryMesh()[patchi];
if (cuttingPatches_.found(toPatch.name()))
{
boundaryAddressing_[patchi].setSize(toPatch.size());
cellAddresses
(
boundaryAddressing_[patchi],
toPatch.faceCentres(),
fromMesh_,
boundaryCell,
oc
);
}
else if
(
patchMap_.found(toPatch.name())
&& fromMeshPatches_.found(patchMap_.find(toPatch.name())())
)
{
const polyPatch& fromPatch = fromMesh_.boundaryMesh()
[
fromMeshPatches_.find(patchMap_.find(toPatch.name())())()
];
if (fromPatch.empty())
{
WarningIn("meshToMesh0::calcAddressing()")
<< "Source patch " << fromPatch.name()
<< " has no faces. Not performing mapping for it."
<< endl;
boundaryAddressing_[patchi] = -1;
}
else
{
treeBoundBox wallBb(fromPatch.localPoints());
scalar typDim =
wallBb.avgDim()/(2.0*sqrt(scalar(fromPatch.size())));
treeBoundBox shiftedBb
(
wallBb.min(),
wallBb.max() + vector(typDim, typDim, typDim)
);
// Note: allow more levels than in meshSearch. Assume patch
// is not as big as all boundary faces
indexedOctree<treeDataFace> oc
(
treeDataFace(false, fromPatch),
shiftedBb, // overall search domain
12, // maxLevel
10, // leafsize
6.0 // duplicity
);
const vectorField::subField centresToBoundary =
toPatch.faceCentres();
boundaryAddressing_[patchi].setSize(toPatch.size());
scalar distSqr = sqr(wallBb.mag());
forAll(toPatch, toi)
{
boundaryAddressing_[patchi][toi] = oc.findNearest
(
centresToBoundary[toi],
distSqr
).index();
}
}
}
}
if (debug)
{
Info<< "meshToMesh0::calculateAddressing() : "
<< "finished calculating mesh-to-mesh cell addressing" << endl;
}
}
void Foam::meshToMesh0::cellAddresses
(
labelList& cellAddressing_,
const pointField& points,
const fvMesh& fromMesh,
const List<bool>& boundaryCell,
const indexedOctree<treeDataCell>& oc
) const
{
// the implemented search method is a simple neighbour array search.
// It starts from a cell zero, searches its neighbours and finds one
// which is nearer to the target point than the current position.
// The location of the "current position" is reset to that cell and
// search through the neighbours continues. The search is finished
// when all the neighbours of the cell are farther from the target
// point than the current cell
// set curCell label to zero (start)
register label curCell = 0;
// set reference to cell to cell addressing
const vectorField& centresFrom = fromMesh.cellCentres();
const labelListList& cc = fromMesh.cellCells();
forAll(points, toI)
{
// pick up target position
const vector& p = points[toI];
// set the sqr-distance
scalar distSqr = magSqr(p - centresFrom[curCell]);
bool closer;
do
{
closer = false;
// set the current list of neighbouring cells
const labelList& neighbours = cc[curCell];
forAll(neighbours, nI)
{
scalar curDistSqr =
magSqr(p - centresFrom[neighbours[nI]]);
// search through all the neighbours.
// If the cell is closer, reset current cell and distance
if (curDistSqr < (1 - SMALL)*distSqr)
{
curCell = neighbours[nI];
distSqr = curDistSqr;
closer = true; // a closer neighbour has been found
}
}
} while (closer);
cellAddressing_[toI] = -1;
// Check point is actually in the nearest cell
if (fromMesh.pointInCell(p, curCell))
{
cellAddressing_[toI] = curCell;
}
else
{
// If curCell is a boundary cell then the point maybe either outside
// the domain or in an other region of the doamin, either way use
// the octree search to find it.
if (boundaryCell[curCell])
{
cellAddressing_[toI] = oc.findInside(p);
}
else
{
// If not on the boundary search the neighbours
bool found = false;
// set the current list of neighbouring cells
const labelList& neighbours = cc[curCell];
forAll(neighbours, nI)
{
// search through all the neighbours.
// If point is in neighbour reset current cell
if (fromMesh.pointInCell(p, neighbours[nI]))
{
cellAddressing_[toI] = neighbours[nI];
found = true;
break;
}
}
if (!found)
{
// If still not found search the neighbour-neighbours
// set the current list of neighbouring cells
const labelList& neighbours = cc[curCell];
forAll(neighbours, nI)
{
// set the current list of neighbour-neighbouring cells
const labelList& nn = cc[neighbours[nI]];
forAll(nn, nI)
{
// search through all the neighbours.
// If point is in neighbour reset current cell
if (fromMesh.pointInCell(p, nn[nI]))
{
cellAddressing_[toI] = nn[nI];
found = true;
break;
}
}
if (found) break;
}
}
if (!found)
{
// Still not found so us the octree
cellAddressing_[toI] = oc.findInside(p);
}
}
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,274 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 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 "meshToMesh0.H"
#include "tetOverlapVolume.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::meshToMesh0::calculateInverseDistanceWeights() const
{
if (debug)
{
Info<< "meshToMesh0::calculateInverseDistanceWeights() : "
<< "calculating inverse distance weighting factors" << endl;
}
if (inverseDistanceWeightsPtr_)
{
FatalErrorIn("meshToMesh0::calculateInverseDistanceWeights()")
<< "weighting factors already calculated"
<< exit(FatalError);
}
//- Initialise overlap volume to zero
V_ = 0.0;
inverseDistanceWeightsPtr_ = new scalarListList(toMesh_.nCells());
scalarListList& invDistCoeffs = *inverseDistanceWeightsPtr_;
// get reference to source mesh data
const labelListList& cc = fromMesh_.cellCells();
const vectorField& centreFrom = fromMesh_.C().internalField();
const vectorField& centreTo = toMesh_.C().internalField();
forAll(cellAddressing_, celli)
{
if (cellAddressing_[celli] != -1)
{
const vector& target = centreTo[celli];
scalar m = mag(target - centreFrom[cellAddressing_[celli]]);
const labelList& neighbours = cc[cellAddressing_[celli]];
// if the nearest cell is a boundary cell or there is a direct hit,
// pick up the value
label directCelli = -1;
if (m < directHitTol || neighbours.empty())
{
directCelli = celli;
}
else
{
forAll(neighbours, ni)
{
scalar nm = mag(target - centreFrom[neighbours[ni]]);
if (nm < directHitTol)
{
directCelli = neighbours[ni];
break;
}
}
}
if (directCelli != -1)
{
// Direct hit
invDistCoeffs[directCelli].setSize(1);
invDistCoeffs[directCelli][0] = 1.0;
V_ += fromMesh_.V()[cellAddressing_[directCelli]];
}
else
{
invDistCoeffs[celli].setSize(neighbours.size() + 1);
// The first coefficient corresponds to the centre cell.
// The rest is ordered in the same way as the cellCells list.
scalar invDist = 1.0/m;
invDistCoeffs[celli][0] = invDist;
scalar sumInvDist = invDist;
// now add the neighbours
forAll(neighbours, ni)
{
invDist = 1.0/mag(target - centreFrom[neighbours[ni]]);
invDistCoeffs[celli][ni + 1] = invDist;
sumInvDist += invDist;
}
// divide by the total inverse-distance
forAll(invDistCoeffs[celli], i)
{
invDistCoeffs[celli][i] /= sumInvDist;
}
V_ +=
invDistCoeffs[celli][0]
*fromMesh_.V()[cellAddressing_[celli]];
for (label i = 1; i < invDistCoeffs[celli].size(); i++)
{
V_ +=
invDistCoeffs[celli][i]*fromMesh_.V()[neighbours[i-1]];
}
}
}
}
}
void Foam::meshToMesh0::calculateInverseVolumeWeights() const
{
if (debug)
{
Info<< "meshToMesh0::calculateInverseVolumeWeights() : "
<< "calculating inverse volume weighting factors" << endl;
}
if (inverseVolumeWeightsPtr_)
{
FatalErrorIn("meshToMesh0::calculateInverseVolumeWeights()")
<< "weighting factors already calculated"
<< exit(FatalError);
}
//- Initialise overlap volume to zero
V_ = 0.0;
inverseVolumeWeightsPtr_ = new scalarListList(toMesh_.nCells());
scalarListList& invVolCoeffs = *inverseVolumeWeightsPtr_;
const labelListList& cellToCell = cellToCellAddressing();
tetOverlapVolume overlapEngine;
forAll(cellToCell, celli)
{
const labelList& overlapCells = cellToCell[celli];
if (overlapCells.size() > 0)
{
invVolCoeffs[celli].setSize(overlapCells.size());
forAll(overlapCells, j)
{
label cellFrom = overlapCells[j];
treeBoundBox bbFromMesh
(
pointField
(
fromMesh_.points(),
fromMesh_.cellPoints()[cellFrom]
)
);
scalar v = overlapEngine.cellCellOverlapVolumeMinDecomp
(
toMesh_,
celli,
fromMesh_,
cellFrom,
bbFromMesh
);
invVolCoeffs[celli][j] = v/toMesh_.V()[celli];
V_ += v;
}
}
}
}
void Foam::meshToMesh0::calculateCellToCellAddressing() const
{
if (debug)
{
Info<< "meshToMesh0::calculateCellToCellAddressing() : "
<< "calculating cell to cell addressing" << endl;
}
if (cellToCellAddressingPtr_)
{
FatalErrorIn("meshToMesh0::calculateCellToCellAddressing()")
<< "addressing already calculated"
<< exit(FatalError);
}
//- Initialise overlap volume to zero
V_ = 0.0;
tetOverlapVolume overlapEngine;
cellToCellAddressingPtr_ = new labelListList(toMesh_.nCells());
labelListList& cellToCell = *cellToCellAddressingPtr_;
forAll(cellToCell, iTo)
{
const labelList overLapCells =
overlapEngine.overlappingCells(fromMesh_, toMesh_, iTo);
if (overLapCells.size() > 0)
{
//Info << "To " << iTo << endl;
//Info << "cellToCell " << overLapCells << endl;
cellToCell[iTo].setSize(overLapCells.size());
forAll(overLapCells, j)
{
cellToCell[iTo][j] = overLapCells[j];
V_ += fromMesh_.V()[overLapCells[j]];
}
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
const Foam::scalarListList& Foam::meshToMesh0::inverseDistanceWeights() const
{
if (!inverseDistanceWeightsPtr_)
{
calculateInverseDistanceWeights();
}
return *inverseDistanceWeightsPtr_;
}
const Foam::scalarListList& Foam::meshToMesh0::inverseVolumeWeights() const
{
if (!inverseVolumeWeightsPtr_)
{
calculateInverseVolumeWeights();
}
return *inverseVolumeWeightsPtr_;
}
const Foam::labelListList& Foam::meshToMesh0::cellToCellAddressing() const
{
if (!cellToCellAddressingPtr_)
{
calculateCellToCellAddressing();
}
return *cellToCellAddressingPtr_;
}
// ************************************************************************* //

View File

@ -0,0 +1,216 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 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 "meshToMesh0.H"
#include "processorFvPatch.H"
#include "demandDrivenData.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(meshToMesh0, 0);
}
const Foam::scalar Foam::meshToMesh0::directHitTol = 1e-5;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::meshToMesh0::meshToMesh0
(
const fvMesh& meshFrom,
const fvMesh& meshTo,
const HashTable<word>& patchMap,
const wordList& cuttingPatchNames
)
:
fromMesh_(meshFrom),
toMesh_(meshTo),
patchMap_(patchMap),
cellAddressing_(toMesh_.nCells()),
boundaryAddressing_(toMesh_.boundaryMesh().size()),
inverseDistanceWeightsPtr_(NULL),
inverseVolumeWeightsPtr_(NULL),
cellToCellAddressingPtr_(NULL),
V_(0.0)
{
forAll(fromMesh_.boundaryMesh(), patchi)
{
fromMeshPatches_.insert
(
fromMesh_.boundaryMesh()[patchi].name(),
patchi
);
}
forAll(toMesh_.boundaryMesh(), patchi)
{
toMeshPatches_.insert
(
toMesh_.boundaryMesh()[patchi].name(),
patchi
);
}
forAll(cuttingPatchNames, i)
{
if (toMeshPatches_.found(cuttingPatchNames[i]))
{
cuttingPatches_.insert
(
cuttingPatchNames[i],
toMeshPatches_.find(cuttingPatchNames[i])()
);
}
else
{
WarningIn
(
"meshToMesh0::meshToMesh0"
"(const fvMesh& meshFrom, const fvMesh& meshTo,"
"const HashTable<word>& patchMap,"
"const wordList& cuttingPatchNames)"
) << "Cannot find cutting-patch " << cuttingPatchNames[i]
<< " in destination mesh" << endl;
}
}
forAll(toMesh_.boundaryMesh(), patchi)
{
// Add the processor patches in the toMesh to the cuttingPatches list
if (isA<processorPolyPatch>(toMesh_.boundaryMesh()[patchi]))
{
cuttingPatches_.insert
(
toMesh_.boundaryMesh()[patchi].name(),
patchi
);
}
}
calcAddressing();
}
Foam::meshToMesh0::meshToMesh0
(
const fvMesh& meshFrom,
const fvMesh& meshTo
)
:
fromMesh_(meshFrom),
toMesh_(meshTo),
cellAddressing_(toMesh_.nCells()),
boundaryAddressing_(toMesh_.boundaryMesh().size()),
inverseDistanceWeightsPtr_(NULL),
inverseVolumeWeightsPtr_(NULL),
cellToCellAddressingPtr_(NULL),
V_(0.0)
{
// check whether both meshes have got the same number
// of boundary patches
if (fromMesh_.boundary().size() != toMesh_.boundary().size())
{
FatalErrorIn
(
"meshToMesh0::meshToMesh0"
"(const fvMesh& meshFrom, const fvMesh& meshTo)"
) << "Incompatible meshes: different number of patches, "
<< "fromMesh = " << fromMesh_.boundary().size()
<< ", toMesh = " << toMesh_.boundary().size()
<< exit(FatalError);
}
forAll(fromMesh_.boundaryMesh(), patchi)
{
if
(
fromMesh_.boundaryMesh()[patchi].name()
!= toMesh_.boundaryMesh()[patchi].name()
)
{
FatalErrorIn
(
"meshToMesh0::meshToMesh0"
"(const fvMesh& meshFrom, const fvMesh& meshTo)"
) << "Incompatible meshes: different patch names for patch "
<< patchi
<< ", fromMesh = " << fromMesh_.boundary()[patchi].name()
<< ", toMesh = " << toMesh_.boundary()[patchi].name()
<< exit(FatalError);
}
if
(
fromMesh_.boundaryMesh()[patchi].type()
!= toMesh_.boundaryMesh()[patchi].type()
)
{
FatalErrorIn
(
"meshToMesh0::meshToMesh0"
"(const fvMesh& meshFrom, const fvMesh& meshTo)"
) << "Incompatible meshes: different patch types for patch "
<< patchi
<< ", fromMesh = " << fromMesh_.boundary()[patchi].type()
<< ", toMesh = " << toMesh_.boundary()[patchi].type()
<< exit(FatalError);
}
fromMeshPatches_.insert
(
fromMesh_.boundaryMesh()[patchi].name(),
patchi
);
toMeshPatches_.insert
(
toMesh_.boundaryMesh()[patchi].name(),
patchi
);
patchMap_.insert
(
toMesh_.boundaryMesh()[patchi].name(),
fromMesh_.boundaryMesh()[patchi].name()
);
}
calcAddressing();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::meshToMesh0::~meshToMesh0()
{
deleteDemandDrivenData(inverseDistanceWeightsPtr_);
deleteDemandDrivenData(inverseVolumeWeightsPtr_);
deleteDemandDrivenData(cellToCellAddressingPtr_);
}
// ************************************************************************* //

View File

@ -0,0 +1,373 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 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::meshToMesh0
Description
mesh to mesh interpolation class.
Note
This class is due to be deprecated in favour of meshToMesh0New
SourceFiles
meshToMesh0.C
calculateMeshToMesh0Addressing.C
calculateMeshToMesh0Weights.C
meshToMesh0Templates.C
\*---------------------------------------------------------------------------*/
#ifndef meshtoMesh_H
#define meshtoMesh_H
#include "fvMesh.H"
#include "HashTable.H"
#include "fvPatchMapper.H"
#include "scalarList.H"
#include "className.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<class Type>
class indexedOctree;
class treeDataCell;
/*---------------------------------------------------------------------------*\
Class meshToMesh0 Declaration
\*---------------------------------------------------------------------------*/
class meshToMesh0
{
// Private data
// mesh references
const fvMesh& fromMesh_;
const fvMesh& toMesh_;
//- fromMesh patch labels
HashTable<label> fromMeshPatches_;
//- toMesh patch labels
HashTable<label> toMeshPatches_;
//- Patch map
HashTable<word> patchMap_;
//- toMesh patch labels which cut the from-mesh
HashTable<label> cuttingPatches_;
//- Cell addressing
labelList cellAddressing_;
//- Boundary addressing
labelListList boundaryAddressing_;
//- Inverse-distance interpolation weights
mutable scalarListList* inverseDistanceWeightsPtr_;
//- Inverse-volume interpolation weights
mutable scalarListList* inverseVolumeWeightsPtr_;
//- Cell to cell overlap addressing
mutable labelListList* cellToCellAddressingPtr_;
//- Overlap volume
mutable scalar V_;
// Private Member Functions
void calcAddressing();
void cellAddresses
(
labelList& cells,
const pointField& points,
const fvMesh& fromMesh,
const List<bool>& boundaryCell,
const indexedOctree<treeDataCell>& oc
) const;
void calculateInverseDistanceWeights() const;
void calculateInverseVolumeWeights() const;
void calculateCellToCellAddressing() const;
const scalarListList& inverseDistanceWeights() const;
const scalarListList& inverseVolumeWeights() const;
const labelListList& cellToCellAddressing() const;
// Private static data members
//- Direct hit tolerance
static const scalar directHitTol;
public:
// Declare name of the class and its debug switch
ClassName("meshToMesh0");
//- Enumeration specifying required accuracy
enum order
{
MAP,
INTERPOLATE,
CELL_POINT_INTERPOLATE,
CELL_VOLUME_WEIGHT
};
// Constructors
//- Construct from the two meshes, the patch name map for the patches
// to be interpolated and the names of the toMesh-patches which
// cut the fromMesh
meshToMesh0
(
const fvMesh& fromMesh,
const fvMesh& toMesh,
const HashTable<word>& patchMap,
const wordList& cuttingPatchNames
);
//- Construct from the two meshes assuming there is an exact mapping
// between the patches
meshToMesh0
(
const fvMesh& fromMesh,
const fvMesh& toMesh
);
//- Destructor
~meshToMesh0();
//- Patch-field interpolation class
class patchFieldInterpolator
:
public fvPatchFieldMapper
{
const labelList& directAddressing_;
public:
// Constructors
//- Construct given addressing
patchFieldInterpolator(const labelList& addr)
:
directAddressing_(addr)
{}
//- Destructor
virtual ~patchFieldInterpolator()
{}
// Member Functions
label size() const
{
return directAddressing_.size();
}
bool direct() const
{
return true;
}
bool hasUnmapped() const
{
return false;
}
const labelList& directAddressing() const
{
return directAddressing_;
}
};
// Member Functions
// Access
const fvMesh& fromMesh() const
{
return fromMesh_;
}
const fvMesh& toMesh() const
{
return toMesh_;
}
//- From toMesh cells to fromMesh cells
const labelList& cellAddressing() const
{
return cellAddressing_;
}
//- Overlap volume
scalar V() const
{
return V_;
}
// Interpolation
//- Map field
template<class Type, class CombineOp>
void mapField
(
Field<Type>&,
const Field<Type>&,
const labelList& adr,
const CombineOp& cop
) const;
//- Interpolate field using inverse-distance weights
template<class Type, class CombineOp>
void interpolateField
(
Field<Type>&,
const GeometricField<Type, fvPatchField, volMesh>&,
const labelList& adr,
const scalarListList& weights,
const CombineOp& cop
) const;
//- Interpolate field using inverse-volume weights
template<class Type, class CombineOp>
void interpolateField
(
Field<Type>&,
const GeometricField<Type, fvPatchField, volMesh>&,
const labelListList& adr,
const scalarListList& weights,
const CombineOp& cop
) const;
//- Interpolate field using cell-point interpolation
template<class Type, class CombineOp>
void interpolateField
(
Field<Type>&,
const GeometricField<Type, fvPatchField, volMesh>&,
const labelList& adr,
const vectorField& centres,
const CombineOp& cop
)const;
//- Interpolate internal volume field
template<class Type, class CombineOp>
void interpolateInternalField
(
Field<Type>&,
const GeometricField<Type, fvPatchField, volMesh>&,
order=INTERPOLATE,
const CombineOp& cop = eqOp<Type>()
) const;
template<class Type, class CombineOp>
void interpolateInternalField
(
Field<Type>&,
const tmp<GeometricField<Type, fvPatchField, volMesh> >&,
order=INTERPOLATE,
const CombineOp& cop = eqOp<Type>()
) const;
//- Interpolate volume field
template<class Type, class CombineOp>
void interpolate
(
GeometricField<Type, fvPatchField, volMesh>&,
const GeometricField<Type, fvPatchField, volMesh>&,
order=INTERPOLATE,
const CombineOp& cop = eqOp<Type>()
) const;
template<class Type, class CombineOp>
void interpolate
(
GeometricField<Type, fvPatchField, volMesh>&,
const tmp<GeometricField<Type, fvPatchField, volMesh> >&,
order=INTERPOLATE,
const CombineOp& cop = eqOp<Type>()
) const;
//- Interpolate volume field
template<class Type, class CombineOp>
tmp<GeometricField<Type, fvPatchField, volMesh> > interpolate
(
const GeometricField<Type, fvPatchField, volMesh>&,
order=INTERPOLATE,
const CombineOp& cop = eqOp<Type>()
) const;
template<class Type, class CombineOp>
tmp<GeometricField<Type, fvPatchField, volMesh> > interpolate
(
const tmp<GeometricField<Type, fvPatchField, volMesh> >&,
order=INTERPOLATE,
const CombineOp& cop = eqOp<Type>()
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "meshToMesh0Templates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,477 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 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 "meshToMesh0.H"
#include "volFields.H"
#include "interpolationCellPoint.H"
#include "SubField.H"
#include "mixedFvPatchField.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type, class CombineOp>
void Foam::meshToMesh0::mapField
(
Field<Type>& toF,
const Field<Type>& fromVf,
const labelList& adr,
const CombineOp& cop
) const
{
// Direct mapping of nearest-cell values
forAll(toF, celli)
{
if (adr[celli] != -1)
{
cop(toF[celli], fromVf[adr[celli]]);
}
}
//toF.map(fromVf, adr);
}
template<class Type, class CombineOp>
void Foam::meshToMesh0::interpolateField
(
Field<Type>& toF,
const GeometricField<Type, fvPatchField, volMesh>& fromVf,
const labelListList& adr,
const scalarListList& weights,
const CombineOp& cop
) const
{
// Inverse volume weighted interpolation
forAll(toF, celli)
{
const labelList& overlapCells = adr[celli];
const scalarList& w = weights[celli];
Type f = pTraits<Type>::zero;
forAll(overlapCells, i)
{
label fromCelli = overlapCells[i];
f += fromVf[fromCelli]*w[i];
cop(toF[celli], f);
}
}
}
template<class Type, class CombineOp>
void Foam::meshToMesh0::interpolateField
(
Field<Type>& toF,
const GeometricField<Type, fvPatchField, volMesh>& fromVf,
const labelList& adr,
const scalarListList& weights,
const CombineOp& cop
) const
{
// Inverse distance weighted interpolation
// get reference to cellCells
const labelListList& cc = fromMesh_.cellCells();
forAll(toF, celli)
{
if (adr[celli] != -1)
{
const labelList& neighbours = cc[adr[celli]];
const scalarList& w = weights[celli];
Type f = fromVf[adr[celli]]*w[0];
for (label ni = 1; ni < w.size(); ni++)
{
f += fromVf[neighbours[ni - 1]]*w[ni];
}
cop(toF[celli], f);
}
}
}
template<class Type, class CombineOp>
void Foam::meshToMesh0::interpolateField
(
Field<Type>& toF,
const GeometricField<Type, fvPatchField, volMesh>& fromVf,
const labelList& adr,
const vectorField& centres,
const CombineOp& cop
) const
{
// Cell-Point interpolation
interpolationCellPoint<Type> interpolator(fromVf);
forAll(toF, celli)
{
if (adr[celli] != -1)
{
cop
(
toF[celli],
interpolator.interpolate
(
centres[celli],
adr[celli]
)
);
}
}
}
template<class Type, class CombineOp>
void Foam::meshToMesh0::interpolateInternalField
(
Field<Type>& toF,
const GeometricField<Type, fvPatchField, volMesh>& fromVf,
meshToMesh0::order ord,
const CombineOp& cop
) const
{
if (fromVf.mesh() != fromMesh_)
{
FatalErrorIn
(
"meshToMesh0::interpolateInternalField(Field<Type>&, "
"const GeometricField<Type, fvPatchField, volMesh>&, "
"meshToMesh0::order, const CombineOp&) const"
) << "the argument field does not correspond to the right mesh. "
<< "Field size: " << fromVf.size()
<< " mesh size: " << fromMesh_.nCells()
<< exit(FatalError);
}
if (toF.size() != toMesh_.nCells())
{
FatalErrorIn
(
"meshToMesh0::interpolateInternalField(Field<Type>&, "
"const GeometricField<Type, fvPatchField, volMesh>&, "
"meshToMesh0::order, const CombineOp&) const"
) << "the argument field does not correspond to the right mesh. "
<< "Field size: " << toF.size()
<< " mesh size: " << toMesh_.nCells()
<< exit(FatalError);
}
switch(ord)
{
case MAP:
mapField(toF, fromVf, cellAddressing_, cop);
break;
case INTERPOLATE:
{
interpolateField
(
toF,
fromVf,
cellAddressing_,
inverseDistanceWeights(),
cop
);
break;
}
case CELL_POINT_INTERPOLATE:
{
interpolateField
(
toF,
fromVf,
cellAddressing_,
toMesh_.cellCentres(),
cop
);
break;
}
case CELL_VOLUME_WEIGHT:
{
const labelListList& cellToCell = cellToCellAddressing();
const scalarListList& invVolWeights = inverseVolumeWeights();
interpolateField
(
toF,
fromVf,
cellToCell,
invVolWeights,
cop
);
break;
}
default:
FatalErrorIn
(
"meshToMesh0::interpolateInternalField(Field<Type>&, "
"const GeometricField<Type, fvPatchField, volMesh>&, "
"meshToMesh0::order, const CombineOp&) const"
) << "unknown interpolation scheme " << ord
<< exit(FatalError);
}
}
template<class Type, class CombineOp>
void Foam::meshToMesh0::interpolateInternalField
(
Field<Type>& toF,
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf,
meshToMesh0::order ord,
const CombineOp& cop
) const
{
interpolateInternalField(toF, tfromVf(), ord, cop);
tfromVf.clear();
}
template<class Type, class CombineOp>
void Foam::meshToMesh0::interpolate
(
GeometricField<Type, fvPatchField, volMesh>& toVf,
const GeometricField<Type, fvPatchField, volMesh>& fromVf,
meshToMesh0::order ord,
const CombineOp& cop
) const
{
interpolateInternalField(toVf, fromVf, ord, cop);
forAll(toMesh_.boundaryMesh(), patchi)
{
const fvPatch& toPatch = toMesh_.boundary()[patchi];
if (cuttingPatches_.found(toPatch.name()))
{
switch(ord)
{
case MAP:
{
mapField
(
toVf.boundaryField()[patchi],
fromVf,
boundaryAddressing_[patchi],
cop
);
break;
}
case INTERPOLATE:
{
interpolateField
(
toVf.boundaryField()[patchi],
fromVf,
boundaryAddressing_[patchi],
toPatch.Cf(),
cop
);
break;
}
case CELL_POINT_INTERPOLATE:
{
interpolateField
(
toVf.boundaryField()[patchi],
fromVf,
boundaryAddressing_[patchi],
toPatch.Cf(),
cop
);
break;
}
case CELL_VOLUME_WEIGHT:
{
// Do nothing
break;
}
default:
FatalErrorIn
(
"meshToMesh0::interpolate("
"GeometricField<Type, fvPatchField, volMesh>&, "
"const GeometricField<Type, fvPatchField, volMesh>&, "
"meshToMesh0::order, const CombineOp&) const"
) << "unknown interpolation scheme " << ord
<< exit(FatalError);
}
if (isA<mixedFvPatchField<Type> >(toVf.boundaryField()[patchi]))
{
refCast<mixedFvPatchField<Type> >
(
toVf.boundaryField()[patchi]
).refValue() = toVf.boundaryField()[patchi];
}
}
else if
(
patchMap_.found(toPatch.name())
&& fromMeshPatches_.found(patchMap_.find(toPatch.name())())
)
{
/*
toVf.boundaryField()[patchi].map
(
fromVf.boundaryField()
[
fromMeshPatches_.find(patchMap_.find(toPatch.name())())()
],
boundaryAddressing_[patchi]
);
*/
mapField
(
toVf.boundaryField()[patchi],
fromVf.boundaryField()
[
fromMeshPatches_.find(patchMap_.find(toPatch.name())())()
],
boundaryAddressing_[patchi],
cop
);
}
}
}
template<class Type, class CombineOp>
void Foam::meshToMesh0::interpolate
(
GeometricField<Type, fvPatchField, volMesh>& toVf,
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf,
meshToMesh0::order ord,
const CombineOp& cop
) const
{
interpolate(toVf, tfromVf(), ord, cop);
tfromVf.clear();
}
template<class Type, class CombineOp>
Foam::tmp< Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::meshToMesh0::interpolate
(
const GeometricField<Type, fvPatchField, volMesh>& fromVf,
meshToMesh0::order ord,
const CombineOp& cop
) const
{
// Create and map the internal-field values
Field<Type> internalField(toMesh_.nCells());
interpolateInternalField(internalField, fromVf, ord, cop);
// check whether both meshes have got the same number
// of boundary patches
if (fromMesh_.boundary().size() != toMesh_.boundary().size())
{
FatalErrorIn
(
"meshToMesh0::interpolate"
"(const GeometricField<Type, fvPatchField, volMesh>&,"
"meshToMesh0::order, const CombineOp&) const"
) << "Incompatible meshes: different number of boundaries, "
"only internal field may be interpolated"
<< exit(FatalError);
}
// Create and map the patch field values
PtrList<fvPatchField<Type> > patchFields
(
boundaryAddressing_.size()
);
forAll(boundaryAddressing_, patchI)
{
patchFields.set
(
patchI,
fvPatchField<Type>::New
(
fromVf.boundaryField()[patchI],
toMesh_.boundary()[patchI],
DimensionedField<Type, volMesh>::null(),
patchFieldInterpolator
(
boundaryAddressing_[patchI]
)
)
);
}
// Create the complete field from the pieces
tmp<GeometricField<Type, fvPatchField, volMesh> > ttoF
(
new GeometricField<Type, fvPatchField, volMesh>
(
IOobject
(
"interpolated(" + fromVf.name() + ')',
toMesh_.time().timeName(),
toMesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
toMesh_,
fromVf.dimensions(),
internalField,
patchFields
)
);
return ttoF;
}
template<class Type, class CombineOp>
Foam::tmp< Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::meshToMesh0::interpolate
(
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf,
meshToMesh0::order ord,
const CombineOp& cop
) const
{
tmp<GeometricField<Type, fvPatchField, volMesh> > tint =
interpolate(tfromVf(), ord, cop);
tfromVf.clear();
return tint;
}
// ************************************************************************* //