mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Creation of OpenFOAM-dev repository 15/04/2008
This commit is contained in:
@ -0,0 +1,363 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Description
|
||||
private member of meshToMesh.
|
||||
Calculates mesh to mesh addressing pattern (for each cell from one mesh
|
||||
find the closest cell centre in the other mesh).
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "meshToMesh.H"
|
||||
#include "SubField.H"
|
||||
|
||||
#include "octree.H"
|
||||
#include "octreeDataCell.H"
|
||||
#include "octreeDataFace.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void meshToMesh::calcAddressing()
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "meshToMesh::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<< "meshToMesh::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 unallocLabelList& 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;
|
||||
}
|
||||
|
||||
// Wrap indices and mesh information into helper object
|
||||
octreeDataCell shapes(fromMesh_);
|
||||
|
||||
octree<octreeDataCell> oc
|
||||
(
|
||||
shiftedBb, // overall bounding box
|
||||
shapes, // all information needed to do checks on cells
|
||||
1, // min. levels
|
||||
10.0, // max. size of leaves
|
||||
10.0 // maximum ratio of cubes v.s. cells
|
||||
);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
oc.printStats(Info);
|
||||
}
|
||||
|
||||
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.size() == 0)
|
||||
{
|
||||
WarningIn("meshToMesh::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)
|
||||
);
|
||||
|
||||
// Wrap data for octree into container
|
||||
octreeDataFace shapes(fromPatch);
|
||||
|
||||
octree<octreeDataFace> oc
|
||||
(
|
||||
shiftedBb, // overall search domain
|
||||
shapes, // all information needed to do checks on cells
|
||||
1, // min levels
|
||||
20.0, // maximum ratio of cubes v.s. cells
|
||||
2.0
|
||||
);
|
||||
|
||||
|
||||
const vectorField::subField centresToBoundary =
|
||||
toPatch.faceCentres();
|
||||
|
||||
boundaryAddressing_[patchi].setSize(toPatch.size());
|
||||
|
||||
treeBoundBox tightest;
|
||||
scalar tightestDist;
|
||||
|
||||
forAll(toPatch, toi)
|
||||
{
|
||||
tightest = wallBb; // starting search bb
|
||||
tightestDist = Foam::GREAT; // starting max distance
|
||||
|
||||
boundaryAddressing_[patchi][toi] = oc.findNearest
|
||||
(
|
||||
centresToBoundary[toi],
|
||||
tightest,
|
||||
tightestDist
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "meshToMesh::calculateAddressing() : "
|
||||
<< "finished calculating mesh-to-mesh acell ddressing" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void meshToMesh::cellAddresses
|
||||
(
|
||||
labelList& cellAddressing_,
|
||||
const pointField& points,
|
||||
const fvMesh& fromMesh,
|
||||
const List<bool>& boundaryCell,
|
||||
const octree<octreeDataCell>& 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.find(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.find(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,125 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "meshToMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void meshToMesh::calculateInverseDistanceWeights() const
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "meshToMesh::calculateInverseDistanceWeights() : "
|
||||
<< "calculating inverse distance weighting factors" << endl;
|
||||
}
|
||||
|
||||
if (inverseDistanceWeightsPtr_)
|
||||
{
|
||||
FatalErrorIn("meshToMesh::calculateInverseDistanceWeights()")
|
||||
<< "weighting factors already calculated"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
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
|
||||
if
|
||||
(
|
||||
m < directHitTol // Direct hit
|
||||
|| neighbours.size() == 0
|
||||
)
|
||||
{
|
||||
invDistCoeffs[celli].setSize(1);
|
||||
invDistCoeffs[celli][0] = 1.0;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
const scalarListList& meshToMesh::inverseDistanceWeights() const
|
||||
{
|
||||
if (!inverseDistanceWeightsPtr_)
|
||||
{
|
||||
calculateInverseDistanceWeights();
|
||||
}
|
||||
|
||||
return *inverseDistanceWeightsPtr_;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
216
src/sampling/meshToMeshInterpolation/meshToMesh/meshToMesh.C
Normal file
216
src/sampling/meshToMeshInterpolation/meshToMesh/meshToMesh.C
Normal file
@ -0,0 +1,216 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "meshToMesh.H"
|
||||
#include "processorFvPatch.H"
|
||||
#include "demandDrivenData.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(meshToMesh, 0);
|
||||
|
||||
const scalar meshToMesh::directHitTol = 1e-5;
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
meshToMesh::meshToMesh
|
||||
(
|
||||
const fvMesh& meshFrom,
|
||||
const fvMesh& meshTo,
|
||||
const HashTable<word>& patchMap,
|
||||
const wordList& cuttingPatchNames
|
||||
)
|
||||
:
|
||||
fromMesh_(meshFrom),
|
||||
toMesh_(meshTo),
|
||||
patchMap_(patchMap),
|
||||
fromPointMesh_(meshFrom),
|
||||
cellAddressing_(toMesh_.nCells()),
|
||||
boundaryAddressing_(toMesh_.boundaryMesh().size()),
|
||||
inverseDistanceWeightsPtr_(NULL)
|
||||
{
|
||||
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
|
||||
(
|
||||
"meshToMesh::meshToMesh"
|
||||
"(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 (toMesh_.boundaryMesh()[patchi].type() == processorFvPatch::typeName)
|
||||
{
|
||||
cuttingPatches_.insert
|
||||
(
|
||||
toMesh_.boundaryMesh()[patchi].name(),
|
||||
patchi
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
calcAddressing();
|
||||
}
|
||||
|
||||
|
||||
meshToMesh::meshToMesh
|
||||
(
|
||||
const fvMesh& meshFrom,
|
||||
const fvMesh& meshTo
|
||||
)
|
||||
:
|
||||
fromMesh_(meshFrom),
|
||||
toMesh_(meshTo),
|
||||
fromPointMesh_(meshFrom),
|
||||
cellAddressing_(toMesh_.nCells()),
|
||||
boundaryAddressing_(toMesh_.boundaryMesh().size()),
|
||||
inverseDistanceWeightsPtr_(NULL)
|
||||
{
|
||||
// check whether both meshes have got the same number
|
||||
// of boundary patches
|
||||
if (fromMesh_.boundary().size() != toMesh_.boundary().size())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"meshToMesh::meshToMesh"
|
||||
"(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
|
||||
(
|
||||
"meshToMesh::meshToMesh"
|
||||
"(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
|
||||
(
|
||||
"meshToMesh::meshToMesh"
|
||||
"(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 * * * * * * * * * * * * * * * //
|
||||
|
||||
meshToMesh::~meshToMesh()
|
||||
{
|
||||
deleteDemandDrivenData(inverseDistanceWeightsPtr_);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
325
src/sampling/meshToMeshInterpolation/meshToMesh/meshToMesh.H
Normal file
325
src/sampling/meshToMeshInterpolation/meshToMesh/meshToMesh.H
Normal file
@ -0,0 +1,325 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Class
|
||||
Foam::meshToMesh
|
||||
|
||||
Description
|
||||
mesh to mesh interpolation class.
|
||||
|
||||
SourceFiles
|
||||
meshToMesh.C
|
||||
calculateMeshToMeshAddressing.C
|
||||
calculateMeshToMeshWeights.C
|
||||
meshToMeshInterpolate.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef meshtoMesh_H
|
||||
#define meshtoMesh_H
|
||||
|
||||
#include "fvMesh.H"
|
||||
#include "pointMesh.H"
|
||||
#include "HashTable.H"
|
||||
#include "fvPatchMapper.H"
|
||||
#include "scalarList.H"
|
||||
#include "className.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
template<class Type>
|
||||
class octree;
|
||||
|
||||
class octreeDataCell;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class meshToMesh Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class meshToMesh
|
||||
{
|
||||
// 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_;
|
||||
|
||||
//- Point mesh used for interpolation
|
||||
pointMesh fromPointMesh_;
|
||||
|
||||
//- Cell addressing
|
||||
labelList cellAddressing_;
|
||||
|
||||
//- Boundary addressing
|
||||
labelListList boundaryAddressing_;
|
||||
|
||||
//- Inverse-distance interpolation weights
|
||||
mutable scalarListList* inverseDistanceWeightsPtr_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
void calcAddressing();
|
||||
|
||||
void cellAddresses
|
||||
(
|
||||
labelList& cells,
|
||||
const pointField& points,
|
||||
const fvMesh& fromMesh,
|
||||
const List<bool>& boundaryCell,
|
||||
const octree<octreeDataCell>& oc
|
||||
) const;
|
||||
|
||||
void calculateInverseDistanceWeights() const;
|
||||
|
||||
const scalarListList& inverseDistanceWeights() const;
|
||||
|
||||
|
||||
// Private static data members
|
||||
|
||||
//- Direct hit tolerance
|
||||
static const scalar directHitTol;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Declare name of the class and its debug switch
|
||||
ClassName("meshToMesh");
|
||||
|
||||
|
||||
//- Enumeration specifying required accuracy
|
||||
enum order
|
||||
{
|
||||
MAP,
|
||||
INTERPOLATE,
|
||||
CELL_POINT_INTERPOLATE
|
||||
};
|
||||
|
||||
|
||||
// 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
|
||||
meshToMesh
|
||||
(
|
||||
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
|
||||
meshToMesh
|
||||
(
|
||||
const fvMesh& fromMesh,
|
||||
const fvMesh& toMesh
|
||||
);
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
~meshToMesh();
|
||||
|
||||
|
||||
//- 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;
|
||||
}
|
||||
|
||||
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_;
|
||||
}
|
||||
|
||||
// Interpolation
|
||||
|
||||
//- Map field
|
||||
template<class Type>
|
||||
void mapField
|
||||
(
|
||||
Field<Type>&,
|
||||
const Field<Type>&,
|
||||
const labelList& adr
|
||||
) const;
|
||||
|
||||
//- Interpolate field using inverse-distance weights
|
||||
template<class Type>
|
||||
void interpolateField
|
||||
(
|
||||
Field<Type>&,
|
||||
const GeometricField<Type, fvPatchField, volMesh>&,
|
||||
const labelList& adr,
|
||||
const scalarListList& weights
|
||||
) const;
|
||||
|
||||
//- Interpolate field using cell-point interpolation
|
||||
template<class Type>
|
||||
void interpolateField
|
||||
(
|
||||
Field<Type>&,
|
||||
const GeometricField<Type, fvPatchField, volMesh>&,
|
||||
const labelList& adr,
|
||||
const vectorField& centres
|
||||
) const;
|
||||
|
||||
|
||||
//- Interpolate internal volume field
|
||||
template<class Type>
|
||||
void interpolateInternalField
|
||||
(
|
||||
Field<Type>&,
|
||||
const GeometricField<Type, fvPatchField, volMesh>&,
|
||||
order=INTERPOLATE
|
||||
) const;
|
||||
|
||||
template<class Type>
|
||||
void interpolateInternalField
|
||||
(
|
||||
Field<Type>&,
|
||||
const tmp<GeometricField<Type, fvPatchField, volMesh> >&,
|
||||
order=INTERPOLATE
|
||||
) const;
|
||||
|
||||
|
||||
//- Interpolate volume field
|
||||
template<class Type>
|
||||
void interpolate
|
||||
(
|
||||
GeometricField<Type, fvPatchField, volMesh>&,
|
||||
const GeometricField<Type, fvPatchField, volMesh>&,
|
||||
order=INTERPOLATE
|
||||
) const;
|
||||
|
||||
template<class Type>
|
||||
void interpolate
|
||||
(
|
||||
GeometricField<Type, fvPatchField, volMesh>&,
|
||||
const tmp<GeometricField<Type, fvPatchField, volMesh> >&,
|
||||
order=INTERPOLATE
|
||||
) const;
|
||||
|
||||
|
||||
//- Interpolate volume field
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh> > interpolate
|
||||
(
|
||||
const GeometricField<Type, fvPatchField, volMesh>&,
|
||||
order=INTERPOLATE
|
||||
) const;
|
||||
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh> > interpolate
|
||||
(
|
||||
const tmp<GeometricField<Type, fvPatchField, volMesh> >&,
|
||||
order=INTERPOLATE
|
||||
) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "meshToMeshInterpolate.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,415 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "meshToMesh.H"
|
||||
#include "volFields.H"
|
||||
#include "volPointInterpolation.H"
|
||||
#include "interpolationCellPoint.H"
|
||||
#include "SubField.H"
|
||||
#include "mixedFvPatchField.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void meshToMesh::mapField
|
||||
(
|
||||
Field<Type>& toF,
|
||||
const Field<Type>& fromVf,
|
||||
const labelList& adr
|
||||
) const
|
||||
{
|
||||
// Direct mapping of nearest-cell values
|
||||
|
||||
forAll(toF, celli)
|
||||
{
|
||||
if (adr[celli] != -1)
|
||||
{
|
||||
toF[celli] = fromVf[adr[celli]];
|
||||
}
|
||||
}
|
||||
|
||||
//toF.map(fromVf, adr);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void meshToMesh::interpolateField
|
||||
(
|
||||
Field<Type>& toF,
|
||||
const GeometricField<Type, fvPatchField, volMesh>& fromVf,
|
||||
const labelList& adr,
|
||||
const scalarListList& weights
|
||||
) 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];
|
||||
|
||||
toF[celli] = fromVf[adr[celli]]*w[0];
|
||||
|
||||
for (label ni = 1; ni < w.size(); ni++)
|
||||
{
|
||||
toF[celli] += fromVf[neighbours[ni - 1]]*w[ni];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void meshToMesh::interpolateField
|
||||
(
|
||||
Field<Type>& toF,
|
||||
const GeometricField<Type, fvPatchField, volMesh>& fromVf,
|
||||
const labelList& adr,
|
||||
const vectorField& centres
|
||||
) const
|
||||
{
|
||||
// Cell-Point interpolation
|
||||
volPointInterpolation vpi(fromMesh_, fromPointMesh_);
|
||||
|
||||
interpolationCellPoint<Type> interpolator
|
||||
(
|
||||
vpi,
|
||||
fromVf
|
||||
);
|
||||
|
||||
forAll (toF, celli)
|
||||
{
|
||||
if (adr[celli] != -1)
|
||||
{
|
||||
toF[celli] = interpolator.interpolate
|
||||
(
|
||||
centres[celli],
|
||||
adr[celli]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void meshToMesh::interpolateInternalField
|
||||
(
|
||||
Field<Type>& toF,
|
||||
const GeometricField<Type, fvPatchField, volMesh>& fromVf,
|
||||
meshToMesh::order ord
|
||||
) const
|
||||
{
|
||||
if (fromVf.mesh() != fromMesh_)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"meshToMesh::interpolateInternalField(Field<Type>& toF, "
|
||||
"const GeometricField<Type, fvPatchField, volMesh>& fromVf, "
|
||||
"meshToMesh::order ord) 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
|
||||
(
|
||||
"meshToMesh::interpolateInternalField(Field<Type>& toF, "
|
||||
"const GeometricField<Type, fvPatchField, volMesh>& fromVf, "
|
||||
"meshToMesh::order ord) 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_);
|
||||
break;
|
||||
|
||||
case INTERPOLATE:
|
||||
interpolateField
|
||||
(
|
||||
toF,
|
||||
fromVf,
|
||||
cellAddressing_,
|
||||
inverseDistanceWeights()
|
||||
);
|
||||
break;
|
||||
|
||||
case CELL_POINT_INTERPOLATE:
|
||||
interpolateField
|
||||
(
|
||||
toF,
|
||||
fromVf,
|
||||
cellAddressing_,
|
||||
toMesh_.cellCentres()
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
FatalErrorIn
|
||||
(
|
||||
"meshToMesh::interpolateInternalField(Field<Type>& toF, "
|
||||
"const GeometricField<Type, fvPatchField, volMesh>& fromVf, "
|
||||
"meshToMesh::order ord) const"
|
||||
) << "unknown interpolation scheme " << ord
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void meshToMesh::interpolateInternalField
|
||||
(
|
||||
Field<Type>& toF,
|
||||
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf,
|
||||
meshToMesh::order ord
|
||||
) const
|
||||
{
|
||||
interpolateInternalField(toF, tfromVf(), ord);
|
||||
tfromVf.clear();
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void meshToMesh::interpolate
|
||||
(
|
||||
GeometricField<Type, fvPatchField, volMesh>& toVf,
|
||||
const GeometricField<Type, fvPatchField, volMesh>& fromVf,
|
||||
meshToMesh::order ord
|
||||
) const
|
||||
{
|
||||
interpolateInternalField(toVf, fromVf, ord);
|
||||
|
||||
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]
|
||||
);
|
||||
break;
|
||||
|
||||
case INTERPOLATE:
|
||||
interpolateField
|
||||
(
|
||||
toVf.boundaryField()[patchi],
|
||||
fromVf,
|
||||
boundaryAddressing_[patchi],
|
||||
toPatch.Cf()
|
||||
);
|
||||
break;
|
||||
|
||||
case CELL_POINT_INTERPOLATE:
|
||||
interpolateField
|
||||
(
|
||||
toVf.boundaryField()[patchi],
|
||||
fromVf,
|
||||
boundaryAddressing_[patchi],
|
||||
toPatch.Cf()
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
FatalErrorIn
|
||||
(
|
||||
"meshToMesh::interpolate("
|
||||
"GeometricField<Type, fvPatchField, volMesh>& toVf, "
|
||||
"const GeometricField<Type, fvPatchField, volMesh>& "
|
||||
"fromVf, meshToMesh::order ord) 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]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void meshToMesh::interpolate
|
||||
(
|
||||
GeometricField<Type, fvPatchField, volMesh>& toVf,
|
||||
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf,
|
||||
meshToMesh::order ord
|
||||
) const
|
||||
{
|
||||
interpolate(toVf, tfromVf(), ord);
|
||||
tfromVf.clear();
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh> > meshToMesh::interpolate
|
||||
(
|
||||
const GeometricField<Type, fvPatchField, volMesh>& fromVf,
|
||||
meshToMesh::order ord
|
||||
) const
|
||||
{
|
||||
// Create and map the internal-field values
|
||||
Field<Type> internalField(toMesh_.nCells());
|
||||
interpolateInternalField(internalField, fromVf, ord);
|
||||
|
||||
// check whether both meshes have got the same number
|
||||
// of boundary patches
|
||||
if (fromMesh_.boundary().size() != toMesh_.boundary().size())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"meshToMesh::interpolate"
|
||||
"(const GeometricField<Type, fvPatchField, volMesh>& fromVf,"
|
||||
"meshToMesh::order ord) 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>
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh> > meshToMesh::interpolate
|
||||
(
|
||||
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf,
|
||||
meshToMesh::order ord
|
||||
) const
|
||||
{
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh> > tint =
|
||||
interpolate(tfromVf(), ord);
|
||||
tfromVf.clear();
|
||||
|
||||
return tint;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user