/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 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 .
\*---------------------------------------------------------------------------*/
#include "surfaceInterpolationScheme.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "geometricOneField.H"
#include "coupledFvPatchField.H"
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
template
Foam::tmp>
Foam::surfaceInterpolationScheme::New
(
const fvMesh& mesh,
Istream& schemeData
)
{
if (schemeData.eof())
{
FatalIOErrorInFunction
(
schemeData
) << "Discretisation scheme not specified"
<< endl << endl
<< "Valid schemes are :" << endl
<< MeshConstructorTablePtr_->sortedToc()
<< exit(FatalIOError);
}
const word schemeName(schemeData);
if (surfaceInterpolation::debug || surfaceInterpolationScheme::debug)
{
InfoInFunction << "Discretisation scheme = " << schemeName << endl;
}
typename MeshConstructorTable::iterator constructorIter =
MeshConstructorTablePtr_->find(schemeName);
if (constructorIter == MeshConstructorTablePtr_->end())
{
FatalIOErrorInFunction
(
schemeData
) << "Unknown discretisation scheme "
<< schemeName << nl << nl
<< "Valid schemes are :" << endl
<< MeshConstructorTablePtr_->sortedToc()
<< exit(FatalIOError);
}
return constructorIter()(mesh, schemeData);
}
template
Foam::tmp>
Foam::surfaceInterpolationScheme::New
(
const fvMesh& mesh,
const surfaceScalarField& faceFlux,
Istream& schemeData
)
{
if (schemeData.eof())
{
FatalIOErrorInFunction
(
schemeData
) << "Discretisation scheme not specified"
<< endl << endl
<< "Valid schemes are :" << endl
<< MeshConstructorTablePtr_->sortedToc()
<< exit(FatalIOError);
}
const word schemeName(schemeData);
if (surfaceInterpolation::debug || surfaceInterpolationScheme::debug)
{
InfoInFunction
<< "Discretisation scheme = " << schemeName << endl;
}
typename MeshFluxConstructorTable::iterator constructorIter =
MeshFluxConstructorTablePtr_->find(schemeName);
if (constructorIter == MeshFluxConstructorTablePtr_->end())
{
FatalIOErrorInFunction
(
schemeData
) << "Unknown discretisation scheme "
<< schemeName << nl << nl
<< "Valid schemes are :" << endl
<< MeshFluxConstructorTablePtr_->sortedToc()
<< exit(FatalIOError);
}
return constructorIter()(mesh, faceFlux, schemeData);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template
Foam::surfaceInterpolationScheme::~surfaceInterpolationScheme()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template
Foam::tmp>
Foam::surfaceInterpolationScheme::interpolate
(
const GeometricField& vf,
const tmp& tlambdas,
const tmp& tys
)
{
if (surfaceInterpolation::debug)
{
InfoInFunction
<< "Interpolating "
<< vf.type() << " "
<< vf.name()
<< " from cells to faces "
"without explicit correction"
<< endl;
}
const surfaceScalarField& lambdas = tlambdas();
const surfaceScalarField& ys = tys();
const Field& vfi = vf.internalField();
const scalarField& lambda = lambdas.internalField();
const scalarField& y = ys.internalField();
const fvMesh& mesh = vf.mesh();
const labelUList& P = mesh.owner();
const labelUList& N = mesh.neighbour();
tmp> tsf
(
new GeometricField
(
IOobject
(
"interpolate("+vf.name()+')',
vf.instance(),
vf.db()
),
mesh,
vf.dimensions()
)
);
GeometricField& sf = tsf.ref();
Field& sfi = sf.internalField();
for (label fi=0; fi::
GeometricBoundaryField& sfbf = sf.boundaryFieldRef();
forAll(lambdas.boundaryField(), pi)
{
const fvsPatchScalarField& pLambda = lambdas.boundaryField()[pi];
const fvsPatchScalarField& pY = ys.boundaryField()[pi];
if (vf.boundaryField()[pi].coupled())
{
sfbf[pi] =
pLambda*vf.boundaryField()[pi].patchInternalField()
+ pY*vf.boundaryField()[pi].patchNeighbourField();
}
else
{
sfbf[pi] = vf.boundaryField()[pi];
}
}
tlambdas.clear();
tys.clear();
return tsf;
}
template
template
Foam::tmp
<
Foam::GeometricField
<
typename Foam::innerProduct::type,
Foam::fvsPatchField,
Foam::surfaceMesh
>
>
Foam::surfaceInterpolationScheme::dotInterpolate
(
const SFType& Sf,
const GeometricField& vf,
const tmp& tlambdas
)
{
if (surfaceInterpolation::debug)
{
InfoInFunction
<< "Interpolating "
<< vf.type() << " "
<< vf.name()
<< " from cells to faces "
"without explicit correction"
<< endl;
}
typedef typename Foam::innerProduct::type
RetType;
const surfaceScalarField& lambdas = tlambdas();
const Field& vfi = vf.internalField();
const scalarField& lambda = lambdas.internalField();
const fvMesh& mesh = vf.mesh();
const labelUList& P = mesh.owner();
const labelUList& N = mesh.neighbour();
tmp> tsf
(
new GeometricField
(
IOobject
(
"interpolate("+vf.name()+')',
vf.instance(),
vf.db()
),
mesh,
Sf.dimensions()*vf.dimensions()
)
);
GeometricField& sf = tsf.ref();
Field& sfi = sf.internalField();
const typename SFType::InternalField& Sfi = Sf.internalField();
for (label fi=0; fi::
GeometricBoundaryField& sfbf = sf.boundaryFieldRef();
forAll(lambdas.boundaryField(), pi)
{
const fvsPatchScalarField& pLambda = lambdas.boundaryField()[pi];
const typename SFType::PatchFieldType& pSf = Sf.boundaryField()[pi];
fvsPatchField& psf = sfbf[pi];
if (vf.boundaryField()[pi].coupled())
{
psf =
pSf
& (
pLambda*vf.boundaryField()[pi].patchInternalField()
+ (1.0 - pLambda)*vf.boundaryField()[pi].patchNeighbourField()
);
}
else
{
psf = pSf & vf.boundaryField()[pi];
}
}
tlambdas.clear();
return tsf;
}
template
Foam::tmp>
Foam::surfaceInterpolationScheme::interpolate
(
const GeometricField& vf,
const tmp& tlambdas
)
{
return dotInterpolate(geometricOneField(), vf, tlambdas);
}
template
Foam::tmp
<
Foam::GeometricField
<
typename Foam::innerProduct::type,
Foam::fvsPatchField,
Foam::surfaceMesh
>
>
Foam::surfaceInterpolationScheme::dotInterpolate
(
const surfaceVectorField& Sf,
const GeometricField& vf
) const
{
if (surfaceInterpolation::debug)
{
InfoInFunction
<< "Interpolating "
<< vf.type() << " "
<< vf.name()
<< " from cells to faces"
<< endl;
}
tmp
<
GeometricField
<
typename Foam::innerProduct::type,
fvsPatchField,
surfaceMesh
>
> tsf = dotInterpolate(Sf, vf, weights(vf));
if (corrected())
{
tsf.ref() += Sf & correction(vf);
}
return tsf;
}
template
Foam::tmp
<
Foam::GeometricField
<
typename Foam::innerProduct::type,
Foam::fvsPatchField,
Foam::surfaceMesh
>
>
Foam::surfaceInterpolationScheme::dotInterpolate
(
const surfaceVectorField& Sf,
const tmp>& tvf
) const
{
tmp
<
GeometricField
<
typename Foam::innerProduct::type,
fvsPatchField,
surfaceMesh
>
> tSfDotinterpVf = dotInterpolate(Sf, tvf());
tvf.clear();
return tSfDotinterpVf;
}
template
Foam::tmp>
Foam::surfaceInterpolationScheme::interpolate
(
const GeometricField& vf
) const
{
if (surfaceInterpolation::debug)
{
InfoInFunction
<< "Interpolating "
<< vf.type() << " "
<< vf.name()
<< " from cells to faces"
<< endl;
}
tmp> tsf
= interpolate(vf, weights(vf));
if (corrected())
{
tsf.ref() += correction(vf);
}
return tsf;
}
template
Foam::tmp>
Foam::surfaceInterpolationScheme::interpolate
(
const tmp>& tvf
) const
{
tmp> tinterpVf
= interpolate(tvf());
tvf.clear();
return tinterpVf;
}
// ************************************************************************* //