mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
558 lines
14 KiB
C
558 lines
14 KiB
C
/*---------------------------------------------------------------------------*\
|
|
========= |
|
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
\\ / O peration |
|
|
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
|
|
\\/ M anipulation |
|
|
-------------------------------------------------------------------------------
|
|
License
|
|
This file is part of OpenFOAM.
|
|
|
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
#include "fvMesh.H"
|
|
#include "volFields.H"
|
|
|
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
|
|
namespace Foam
|
|
{
|
|
//- Helper class for list
|
|
template<class Type>
|
|
class ListPlusEqOp
|
|
{
|
|
public:
|
|
void operator()(List<Type>& x, const List<Type> y) const
|
|
{
|
|
if (y.size())
|
|
{
|
|
if (x.size())
|
|
{
|
|
label sz = x.size();
|
|
x.setSize(sz + y.size());
|
|
forAll(y, i)
|
|
{
|
|
x[sz++] = y[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
x = y;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
|
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
|
|
|
template<class Type>
|
|
void Foam::meshToMeshNew::add
|
|
(
|
|
UList<Type>& fld,
|
|
const label offset
|
|
) const
|
|
{
|
|
forAll(fld, i)
|
|
{
|
|
fld[i] += offset;
|
|
}
|
|
}
|
|
|
|
|
|
template<class Type, class CombineOp>
|
|
void Foam::meshToMeshNew::mapSrcToTgt
|
|
(
|
|
const UList<Type>& srcField,
|
|
const CombineOp& cop,
|
|
List<Type>& result
|
|
) const
|
|
{
|
|
if (result.size() != tgtToSrcCellAddr_.size())
|
|
{
|
|
FatalErrorIn
|
|
(
|
|
"void Foam::meshToMeshNew::mapSrcToTgt"
|
|
"("
|
|
"const UList<Type>&, "
|
|
"const CombineOp&, "
|
|
"List<Type>&"
|
|
") const"
|
|
) << "Supplied field size is not equal to target mesh size" << nl
|
|
<< " source mesh = " << srcToTgtCellAddr_.size() << nl
|
|
<< " target mesh = " << tgtToSrcCellAddr_.size() << nl
|
|
<< " supplied field = " << result.size()
|
|
<< abort(FatalError);
|
|
}
|
|
|
|
multiplyWeightedOp<Type, CombineOp> cbop(cop);
|
|
|
|
if (singleMeshProc_ == -1)
|
|
{
|
|
const mapDistribute& map = srcMapPtr_();
|
|
|
|
List<Type> work(srcField);
|
|
map.distribute(work);
|
|
|
|
forAll(result, cellI)
|
|
{
|
|
const labelList& srcAddress = tgtToSrcCellAddr_[cellI];
|
|
const scalarList& srcWeight = tgtToSrcCellWght_[cellI];
|
|
|
|
if (srcAddress.size())
|
|
{
|
|
// result[cellI] = pTraits<Type>::zero;
|
|
result[cellI] *= (1.0 - sum(srcWeight));
|
|
forAll(srcAddress, i)
|
|
{
|
|
label srcI = srcAddress[i];
|
|
scalar w = srcWeight[i];
|
|
cbop(result[cellI], cellI, work[srcI], w);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
forAll(result, cellI)
|
|
{
|
|
const labelList& srcAddress = tgtToSrcCellAddr_[cellI];
|
|
const scalarList& srcWeight = tgtToSrcCellWght_[cellI];
|
|
|
|
if (srcAddress.size())
|
|
{
|
|
// result[cellI] = pTraits<Type>::zero;
|
|
result[cellI] *= (1.0 - sum(srcWeight));
|
|
forAll(srcAddress, i)
|
|
{
|
|
label srcI = srcAddress[i];
|
|
scalar w = srcWeight[i];
|
|
cbop(result[cellI], cellI, srcField[srcI], w);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
template<class Type, class CombineOp>
|
|
Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapSrcToTgt
|
|
(
|
|
const Field<Type>& srcField,
|
|
const CombineOp& cop
|
|
) const
|
|
{
|
|
tmp<Field<Type> > tresult
|
|
(
|
|
new Field<Type>
|
|
(
|
|
tgtToSrcCellAddr_.size(),
|
|
pTraits<Type>::zero
|
|
)
|
|
);
|
|
|
|
mapSrcToTgt(srcField, cop, tresult());
|
|
|
|
return tresult;
|
|
}
|
|
|
|
|
|
template<class Type, class CombineOp>
|
|
Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapSrcToTgt
|
|
(
|
|
const tmp<Field<Type> >& tsrcField,
|
|
const CombineOp& cop
|
|
) const
|
|
{
|
|
return mapSrcToTgt(tsrcField(), cop);
|
|
}
|
|
|
|
|
|
template<class Type>
|
|
Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapSrcToTgt
|
|
(
|
|
const Field<Type>& srcField
|
|
) const
|
|
{
|
|
return mapSrcToTgt(srcField, plusEqOp<Type>());
|
|
}
|
|
|
|
|
|
template<class Type>
|
|
Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapSrcToTgt
|
|
(
|
|
const tmp<Field<Type> >& tsrcField
|
|
) const
|
|
{
|
|
return mapSrcToTgt(tsrcField());
|
|
}
|
|
|
|
|
|
template<class Type, class CombineOp>
|
|
void Foam::meshToMeshNew::mapTgtToSrc
|
|
(
|
|
const UList<Type>& tgtField,
|
|
const CombineOp& cop,
|
|
List<Type>& result
|
|
) const
|
|
{
|
|
if (result.size() != srcToTgtCellAddr_.size())
|
|
{
|
|
FatalErrorIn
|
|
(
|
|
"void Foam::meshToMeshNew::mapTgtToSrc"
|
|
"("
|
|
"const UList<Type>&, "
|
|
"const CombineOp&, "
|
|
"List<Type>&"
|
|
") const"
|
|
) << "Supplied field size is not equal to source mesh size" << nl
|
|
<< " source mesh = " << srcToTgtCellAddr_.size() << nl
|
|
<< " target mesh = " << tgtToSrcCellAddr_.size() << nl
|
|
<< " supplied field = " << result.size()
|
|
<< abort(FatalError);
|
|
}
|
|
|
|
multiplyWeightedOp<Type, CombineOp> cbop(cop);
|
|
|
|
if (singleMeshProc_ == -1)
|
|
{
|
|
const mapDistribute& map = tgtMapPtr_();
|
|
|
|
List<Type> work(tgtField);
|
|
map.distribute(work);
|
|
|
|
forAll(result, cellI)
|
|
{
|
|
const labelList& tgtAddress = srcToTgtCellAddr_[cellI];
|
|
const scalarList& tgtWeight = srcToTgtCellWght_[cellI];
|
|
|
|
if (tgtAddress.size())
|
|
{
|
|
result[cellI] *= (1.0 - sum(tgtWeight));
|
|
forAll(tgtAddress, i)
|
|
{
|
|
label tgtI = tgtAddress[i];
|
|
scalar w = tgtWeight[i];
|
|
cbop(result[cellI], cellI, work[tgtI], w);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
forAll(result, cellI)
|
|
{
|
|
const labelList& tgtAddress = srcToTgtCellAddr_[cellI];
|
|
const scalarList& tgtWeight = srcToTgtCellWght_[cellI];
|
|
|
|
if (tgtAddress.size())
|
|
{
|
|
result[cellI] *= (1.0 - sum(tgtWeight));
|
|
forAll(tgtAddress, i)
|
|
{
|
|
label tgtI = tgtAddress[i];
|
|
scalar w = tgtWeight[i];
|
|
cbop(result[cellI], cellI, tgtField[tgtI], w);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
template<class Type, class CombineOp>
|
|
Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapTgtToSrc
|
|
(
|
|
const Field<Type>& tgtField,
|
|
const CombineOp& cop
|
|
) const
|
|
{
|
|
tmp<Field<Type> > tresult
|
|
(
|
|
new Field<Type>
|
|
(
|
|
srcToTgtCellAddr_.size(),
|
|
pTraits<Type>::zero
|
|
)
|
|
);
|
|
|
|
mapTgtToSrc(tgtField, cop, tresult());
|
|
|
|
return tresult;
|
|
}
|
|
|
|
|
|
template<class Type, class CombineOp>
|
|
Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapTgtToSrc
|
|
(
|
|
const tmp<Field<Type> >& ttgtField,
|
|
const CombineOp& cop
|
|
) const
|
|
{
|
|
return mapTgtToSrc(ttgtField(), cop);
|
|
}
|
|
|
|
|
|
template<class Type>
|
|
Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapTgtToSrc
|
|
(
|
|
const Field<Type>& tgtField
|
|
) const
|
|
{
|
|
return mapTgtToSrc(tgtField, plusEqOp<Type>());
|
|
}
|
|
|
|
|
|
template<class Type>
|
|
Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapTgtToSrc
|
|
(
|
|
const tmp<Field<Type> >& ttgtField
|
|
) const
|
|
{
|
|
return mapTgtToSrc(ttgtField(), plusEqOp<Type>());
|
|
}
|
|
|
|
|
|
template<class Type, class CombineOp>
|
|
void Foam::meshToMeshNew::mapSrcToTgt
|
|
(
|
|
const GeometricField<Type, fvPatchField, volMesh>& field,
|
|
const CombineOp& cop,
|
|
GeometricField<Type, fvPatchField, volMesh>& result
|
|
) const
|
|
{
|
|
mapSrcToTgt(field, cop, result.internalField());
|
|
|
|
const PtrList<AMIPatchToPatchInterpolation>& AMIList = patchAMIs();
|
|
|
|
forAll(AMIList, i)
|
|
{
|
|
label srcPatchI = srcPatchID_[i];
|
|
label tgtPatchI = tgtPatchID_[i];
|
|
|
|
const Field<Type>& srcField = field.boundaryField()[srcPatchI];
|
|
Field<Type>& tgtField = result.boundaryField()[tgtPatchI];
|
|
|
|
tgtField = pTraits<Type>::zero;
|
|
|
|
AMIList[i].interpolateToTarget
|
|
(
|
|
srcField,
|
|
multiplyWeightedOp<Type, CombineOp>(cop),
|
|
tgtField
|
|
);
|
|
}
|
|
|
|
forAll(cuttingPatches_, i)
|
|
{
|
|
label patchI = cuttingPatches_[i];
|
|
fvPatchField<Type>& pf = result.boundaryField()[patchI];
|
|
pf == pf.patchInternalField();
|
|
}
|
|
}
|
|
|
|
|
|
template<class Type, class CombineOp>
|
|
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
|
|
Foam::meshToMeshNew::mapSrcToTgt
|
|
(
|
|
const GeometricField<Type, fvPatchField, volMesh>& field,
|
|
const CombineOp& cop
|
|
) const
|
|
{
|
|
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
|
|
|
const fvMesh& tgtMesh = static_cast<const fvMesh&>(tgtRegion_);
|
|
|
|
tmp<fieldType> tresult
|
|
(
|
|
new fieldType
|
|
(
|
|
IOobject
|
|
(
|
|
type() + ".interpolate(" + field.name() + ")",
|
|
tgtMesh.time().timeName(),
|
|
tgtMesh,
|
|
IOobject::NO_READ,
|
|
IOobject::NO_WRITE
|
|
),
|
|
tgtMesh,
|
|
dimensioned<Type>
|
|
(
|
|
"zero",
|
|
field.dimensions(),
|
|
pTraits<Type>::zero
|
|
)
|
|
)
|
|
);
|
|
|
|
mapSrcToTgt(field, cop, tresult());
|
|
|
|
return tresult;
|
|
}
|
|
|
|
|
|
template<class Type, class CombineOp>
|
|
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
|
|
Foam::meshToMeshNew::mapSrcToTgt
|
|
(
|
|
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfield,
|
|
const CombineOp& cop
|
|
) const
|
|
{
|
|
return mapSrcToTgt(tfield(), cop);
|
|
}
|
|
|
|
|
|
template<class Type>
|
|
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
|
|
Foam::meshToMeshNew::mapSrcToTgt
|
|
(
|
|
const GeometricField<Type, fvPatchField, volMesh>& field
|
|
) const
|
|
{
|
|
return mapSrcToTgt(field, plusEqOp<Type>());
|
|
}
|
|
|
|
|
|
template<class Type>
|
|
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
|
|
Foam::meshToMeshNew::mapSrcToTgt
|
|
(
|
|
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfield
|
|
) const
|
|
{
|
|
return mapSrcToTgt(tfield(), plusEqOp<Type>());
|
|
}
|
|
|
|
|
|
template<class Type, class CombineOp>
|
|
void Foam::meshToMeshNew::mapTgtToSrc
|
|
(
|
|
const GeometricField<Type, fvPatchField, volMesh>& field,
|
|
const CombineOp& cop,
|
|
GeometricField<Type, fvPatchField, volMesh>& result
|
|
) const
|
|
{
|
|
mapTgtToSrc(field, cop, result.internalField());
|
|
|
|
const PtrList<AMIPatchToPatchInterpolation>& AMIList = patchAMIs();
|
|
|
|
forAll(AMIList, i)
|
|
{
|
|
label srcPatchI = srcPatchID_[i];
|
|
label tgtPatchI = tgtPatchID_[i];
|
|
|
|
Field<Type>& srcField = result.boundaryField()[srcPatchI];
|
|
const Field<Type>& tgtField = field.boundaryField()[tgtPatchI];
|
|
|
|
srcField = pTraits<Type>::zero;
|
|
|
|
AMIList[i].interpolateToSource
|
|
(
|
|
tgtField,
|
|
multiplyWeightedOp<Type, CombineOp>(cop),
|
|
srcField
|
|
);
|
|
}
|
|
|
|
forAll(cuttingPatches_, i)
|
|
{
|
|
label patchI = cuttingPatches_[i];
|
|
fvPatchField<Type>& pf = result.boundaryField()[patchI];
|
|
pf == pf.patchInternalField();
|
|
}
|
|
}
|
|
|
|
|
|
template<class Type, class CombineOp>
|
|
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
|
|
Foam::meshToMeshNew::mapTgtToSrc
|
|
(
|
|
const GeometricField<Type, fvPatchField, volMesh>& field,
|
|
const CombineOp& cop
|
|
) const
|
|
{
|
|
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
|
|
|
const fvMesh& srcMesh = static_cast<const fvMesh&>(srcRegion_);
|
|
|
|
tmp<fieldType> tresult
|
|
(
|
|
new fieldType
|
|
(
|
|
IOobject
|
|
(
|
|
type() + ".interpolate(" + field.name() + ")",
|
|
srcMesh.time().timeName(),
|
|
srcMesh,
|
|
IOobject::NO_READ,
|
|
IOobject::NO_WRITE
|
|
),
|
|
srcMesh,
|
|
dimensioned<Type>
|
|
(
|
|
"zero",
|
|
field.dimensions(),
|
|
pTraits<Type>::zero
|
|
)
|
|
)
|
|
);
|
|
|
|
mapTgtToSrc(field, cop, tresult());
|
|
|
|
return tresult;
|
|
}
|
|
|
|
|
|
template<class Type, class CombineOp>
|
|
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
|
|
Foam::meshToMeshNew::mapTgtToSrc
|
|
(
|
|
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfield,
|
|
const CombineOp& cop
|
|
) const
|
|
{
|
|
return mapTgtToSrc(tfield(), cop);
|
|
}
|
|
|
|
|
|
template<class Type>
|
|
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
|
|
Foam::meshToMeshNew::mapTgtToSrc
|
|
(
|
|
const GeometricField<Type, fvPatchField, volMesh>& field
|
|
) const
|
|
{
|
|
return mapTgtToSrc(field, plusEqOp<Type>());
|
|
}
|
|
|
|
|
|
template<class Type>
|
|
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
|
|
Foam::meshToMeshNew::mapTgtToSrc
|
|
(
|
|
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfield
|
|
) const
|
|
{
|
|
return mapTgtToSrc(tfield(), plusEqOp<Type>());
|
|
}
|
|
|
|
|
|
// ************************************************************************* //
|