Commit 5edba1d1 authored by sergio's avatar sergio
Browse files

ENH: Adding mapRegion option to meshToMesh and volume weighted

interpolation method
parent 698ceefe
......@@ -69,4 +69,8 @@ $(meshToMesh)/meshToMesh.C
$(meshToMesh)/calculateMeshToMeshAddressing.C
$(meshToMesh)/calculateMeshToMeshWeights.C
tetOverlapVolume = meshToMeshInterpolation/tetOverlapVolume
$(tetOverlapVolume)/tetOverlapVolume.C
LIB = $(FOAM_LIBBIN)/libsampling
......@@ -24,6 +24,7 @@ License
\*---------------------------------------------------------------------------*/
#include "meshToMesh.H"
#include "tetOverlapVolume.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
......@@ -99,6 +100,108 @@ void Foam::meshToMesh::calculateInverseDistanceWeights() const
}
void Foam::meshToMesh::calculateInverseVolumeWeights() const
{
if (debug)
{
Info<< "meshToMesh::calculateInverseVolumeWeights() : "
<< "calculating inverse volume weighting factors" << endl;
}
if (inverseVolumeWeightsPtr_)
{
FatalErrorIn("meshToMesh::calculateInverseVolumeWeights()")
<< "weighting factors already calculated"
<< exit(FatalError);
}
inverseVolumeWeightsPtr_ = new scalarListList(toMesh_.nCells());
scalarListList& invVolCoeffs = *inverseVolumeWeightsPtr_;
labelListList& cellToCell = *cellToCellAddressingPtr_;
tetOverlapVolume overlapEngine;
forAll(cellToCell, celli)
{
const labelList& overlapCells = cellToCell[celli];
if (overlapCells.size() > 0)
{
invVolCoeffs[celli].setSize(overlapCells.size());
scalar v(0);
forAll (overlapCells, j)
{
label cellFrom = overlapCells[j];
treeBoundBox bbFromMesh
(
pointField
(
fromMesh_.points(),
fromMesh_.cellPoints()[cellFrom]
)
);
v = overlapEngine.cellCellOverlapVolumeMinDecomp
(
toMesh_,
celli,
fromMesh_,
cellFrom,
bbFromMesh
);
invVolCoeffs[celli][j] = v/toMesh_.V()[celli];
}
if (celli == 2)
{
Info << "cellToCell :" << cellToCell[celli] << endl;
Info << "invVolCoeffs :" << invVolCoeffs[celli] << endl;
}
}
}
}
void Foam::meshToMesh::calculateCellToCellAddressing() const
{
if (debug)
{
Info<< "meshToMesh::calculateCellToCellAddressing() : "
<< "calculating cell to cell addressing" << endl;
}
if (cellToCellAddressingPtr_)
{
FatalErrorIn("meshToMesh::calculateCellToCellAddressing()")
<< "addressing already calculated"
<< exit(FatalError);
}
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];
}
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
const Foam::scalarListList& Foam::meshToMesh::inverseDistanceWeights() const
......@@ -112,4 +215,24 @@ const Foam::scalarListList& Foam::meshToMesh::inverseDistanceWeights() const
}
const Foam::scalarListList& Foam::meshToMesh::inverseVolumeWeights() const
{
if (!inverseVolumeWeightsPtr_)
{
calculateInverseVolumeWeights();
}
return *inverseVolumeWeightsPtr_;
}
const Foam::labelListList& Foam::meshToMesh::cellToCellAddressing() const
{
if (!cellToCellAddressingPtr_)
{
calculateCellToCellAddressing();
}
return *cellToCellAddressingPtr_;
}
// ************************************************************************* //
......@@ -48,7 +48,9 @@ Foam::meshToMesh::meshToMesh
patchMap_(patchMap),
cellAddressing_(toMesh_.nCells()),
boundaryAddressing_(toMesh_.boundaryMesh().size()),
inverseDistanceWeightsPtr_(NULL)
inverseDistanceWeightsPtr_(NULL),
inverseVolumeWeightsPtr_(NULL),
cellToCellAddressingPtr_(NULL)
{
forAll(fromMesh_.boundaryMesh(), patchi)
{
......@@ -118,7 +120,9 @@ Foam::meshToMesh::meshToMesh
toMesh_(meshTo),
cellAddressing_(toMesh_.nCells()),
boundaryAddressing_(toMesh_.boundaryMesh().size()),
inverseDistanceWeightsPtr_(NULL)
inverseDistanceWeightsPtr_(NULL),
inverseVolumeWeightsPtr_(NULL),
cellToCellAddressingPtr_(NULL)
{
// check whether both meshes have got the same number
// of boundary patches
......@@ -198,6 +202,8 @@ Foam::meshToMesh::meshToMesh
Foam::meshToMesh::~meshToMesh()
{
deleteDemandDrivenData(inverseDistanceWeightsPtr_);
deleteDemandDrivenData(inverseVolumeWeightsPtr_);
deleteDemandDrivenData(cellToCellAddressingPtr_);
}
......
......@@ -88,6 +88,12 @@ class meshToMesh
//- Inverse-distance interpolation weights
mutable scalarListList* inverseDistanceWeightsPtr_;
//- Inverse-volume interpolation weights
mutable scalarListList* inverseVolumeWeightsPtr_;
//- Cell to cell overlap addressing
mutable labelListList* cellToCellAddressingPtr_;
// Private Member Functions
......@@ -104,8 +110,16 @@ class meshToMesh
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
......@@ -124,7 +138,8 @@ public:
{
MAP,
INTERPOLATE,
CELL_POINT_INTERPOLATE
CELL_POINT_INTERPOLATE,
CELL_VOLUME_WEIGHT
};
......@@ -239,6 +254,18 @@ public:
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
......
......@@ -54,6 +54,33 @@ void Foam::meshToMesh::mapField
}
template<class Type, class CombineOp>
void Foam::meshToMesh::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::meshToMesh::interpolateField
(
......@@ -162,6 +189,7 @@ void Foam::meshToMesh::interpolateInternalField
break;
case INTERPOLATE:
{
interpolateField
(
toF,
......@@ -170,9 +198,10 @@ void Foam::meshToMesh::interpolateInternalField
inverseDistanceWeights(),
cop
);
break;
break;
}
case CELL_POINT_INTERPOLATE:
{
interpolateField
(
toF,
......@@ -181,8 +210,24 @@ void Foam::meshToMesh::interpolateInternalField
toMesh_.cellCentres(),
cop
);
break;
break;
}
case CELL_VOLUME_WEIGHT:
{
const labelListList& cellToCell = cellToCellAddressing();
const scalarListList& invVolWeights = inverseVolumeWeights();
interpolateField
(
toF,
fromVf,
cellToCell,
invVolWeights,
cop
);
break;
}
default:
FatalErrorIn
(
......@@ -229,6 +274,7 @@ void Foam::meshToMesh::interpolate
switch(ord)
{
case MAP:
{
mapField
(
toVf.boundaryField()[patchi],
......@@ -236,9 +282,11 @@ void Foam::meshToMesh::interpolate
boundaryAddressing_[patchi],
cop
);
break;
break;
}
case INTERPOLATE:
{
interpolateField
(
toVf.boundaryField()[patchi],
......@@ -247,9 +295,11 @@ void Foam::meshToMesh::interpolate
toPatch.Cf(),
cop
);
break;
break;
}
case CELL_POINT_INTERPOLATE:
{
interpolateField
(
toVf.boundaryField()[patchi],
......@@ -258,7 +308,13 @@ void Foam::meshToMesh::interpolate
toPatch.Cf(),
cop
);
break;
break;
}
case CELL_VOLUME_WEIGHT:
{
// Do nothing
break;
}
default:
FatalErrorIn
......
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 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::tetOverlapVolume
Description
Calculates overlap volume of two tets.
SourceFiles
tetOverlapVolume.C
\*---------------------------------------------------------------------------*/
#ifndef tetOverlapVolume_H
#define tetOverlapVolume_H
#include "tetrahedron.H"
#include "fvMesh.H"
#include "plane.H"
#include "tetPointRef.H"
#include "OFstream.H"
#include "meshTools.H"
#include "indexedOctree.H"
#include "treeDataCell.H"
#include "tetPoints.H"
#include "tetCell.H"
#include "EdgeMap.H"
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class tetOverlapVolume Declaration
\*---------------------------------------------------------------------------*/
class tetOverlapVolume
{
// Private member functions
//- Plane intersection
inline point planeIntersection
(
const FixedList<scalar, 4>& d,
const tetPoints& t,
const label negI,
const label posI
);
//- Decompose prism
template <class TetOp> inline void decomposePrism
(
const FixedList<point, 6>& points,
TetOp& op
);
//- Helping cľasses
class dummyTetOp
{
public:
inline void operator()(const tetPoints&){}
};
class sumTetVolOp
{
public:
scalar vol_;
inline sumTetVolOp()
:
vol_(0.0)
{}
inline void operator()(const tetPoints& tet)
{
vol_ += tet.tet().mag();
}
};
class storeTetOp
{
FixedList<tetPoints, 200>& tets_;
label& nTets_;
public:
inline storeTetOp(FixedList<tetPoints, 200>& tets, label& nTets)
:
tets_(tets),
nTets_(nTets)
{}
inline void operator()(const tetPoints& tet)
{
tets_[nTets_++] = tet;
}
};
//- Slice. Split tet into subtets above and below plane
template <class AboveTetOp, class BelowTetOp>
inline void tetSliceWithPlane
(
const tetPoints& tet,
const plane& pl,
AboveTetOp& aboveOp,
BelowTetOp& belowOp
);
//- Tet overlap
void tetTetOverlap
(
const tetPoints& tetA,
const tetPoints& tetB,
FixedList<tetPoints, 200>& insideTets,
label& nInside,
FixedList<tetPoints, 200>& outsideTets,
label& nOutside
);
//- Tet Overlap Vol
inline scalar tetTetOverlapVol
(
const tetPoints& tetA,
const tetPoints& tetB
);
//- Return a const treeBoundBox
inline const treeBoundBox pyrBb
(
const pointField& points,
const face& f,
const point& fc
);
public:
//- Runtime type information
TypeName("tetOverlapVolume");
// Constructors
//- Null constructor
tetOverlapVolume();
//- Destructor
virtual ~tetOverlapVolume();
// Public members
//- Return a list of cells in meshA which overlaps with cellBI in
// meshB
labelList overlappingCells
(
const fvMesh& meshA,
const fvMesh& meshB,
const label cellBI
) const;
//- Calculates the overlap volume
scalar cellCellOverlapVolumeMinDecomp
(
const primitiveMesh& meshA,
const label cellAI,
const primitiveMesh& meshB,
const label cellBI,
const treeBoundBox& cellBbB
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2011 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 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