/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "primitivePatchInterpolation.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template
Foam::tmp>
Foam::expressions::patchExpr::parseDriver::getVariableIfAvailable
(
const word& name
) const
{
bool hasPointData = false;
refPtr tvar;
if (hasVariable(name) && variable(name).isType())
{
tvar.cref(variable(name));
hasPointData = tvar().isPointData();
}
else if (isGlobalVariable(name))
{
tvar.cref(lookupGlobal(name));
}
if (tvar.valid())
{
const auto& var = tvar.cref();
const Field& vals = var.cref();
const label len = (hasPointData ? this->pointSize() : this->size());
if (returnReduceAnd(vals.size() == len))
{
// Return a copy of the field
return tmp>::New(vals);
}
if (!var.isUniform())
{
WarningInFunction
<< "Variable " << name
<< " is nonuniform and does not fit the size"
<< ". Using average" << endl;
}
return tmp>::New(this->size(), gAverage(vals));
}
return nullptr;
}
template
Foam::tmp>
Foam::expressions::patchExpr::parseDriver::getVolField(const word& name)
{
return getField(name);
}
template
Foam::tmp>
Foam::expressions::patchExpr::parseDriver::getSurfaceField(const word& name)
{
return getField(name);
}
template
Foam::tmp>
Foam::expressions::patchExpr::parseDriver::getPointField(const word& name)
{
return getField(name);
}
template
Foam::tmp>
Foam::expressions::patchExpr::parseDriver::getField(const word& name)
{
tmp> tfield = getVariableIfAvailable(name);
if (tfield.valid())
{
return tfield;
}
const objectRegistry& obr = this->mesh().thisDb();
const label patchIndex = patch_.index();
// Local, temporary storage and/or lookup values
bool found = false;
tmp> vfield;
tmp> sfield;
tmp> pfield;
for (int checki = 0; !found && checki < 2; ++checki)
{
// Check 0: object context (first)
// Check 1: regular objectRegistry
const regIOobject* ioptr =
(
(checki == 0)
? exprDriver::cfindContextIOobject(name)
: obr.cfindIOobject(name)
);
if (!ioptr) continue;
if (!found)
{
vfield.cref(dynamic_cast*>(ioptr));
found = vfield.valid();
}
if (!found)
{
sfield.cref(dynamic_cast*>(ioptr));
found = sfield.valid();
}
if (!found)
{
pfield.cref(dynamic_cast*>(ioptr));
found = pfield.valid();
}
}
// Finally, search files if necessary (and permitted)
if (!found && searchFiles())
{
const word fldType = this->getTypeOfField(name);
if (fldType == VolumeField::typeName)
{
vfield = this->readAndRegister>(name, mesh());
}
else if (fldType == SurfaceField::typeName)
{
sfield = this->readAndRegister>(name, mesh());
}
else if (fldType == PointField::typeName)
{
pfield = this->readAndRegister>
(
name,
pointMesh::New(mesh())
);
}
}
if (vfield.valid())
{
return tmp>::New
(
vfield().boundaryField()[patchIndex]
);
}
if (sfield.valid())
{
return tmp>::New
(
sfield().boundaryField()[patchIndex]
);
}
if (pfield.valid())
{
return pfield().boundaryField()[patchIndex].patchInternalField();
}
FatalErrorInFunction
<< "No field '" << name << "' of type "
<< pTraits::typeName << nl << nl;
FatalError
<< VolumeField::typeName << " Fields: "
<< flatOutput(obr.sortedNames>()) << nl;
FatalError
<< SurfaceField::typeName << " Fields: "
<< flatOutput(obr.sortedNames>()) << nl;
FatalError
<< PointField::typeName << " Fields: "
<< flatOutput(obr.sortedNames>()) << nl;
FatalError
<< exit(FatalError);
return tmp>::New();
}
template
Foam::tmp>
Foam::expressions::patchExpr::parseDriver::patchInternalField
(
const word& name
)
{
tmp> tfield = getVariableIfAvailable(name);
if (tfield.valid())
{
return tfield;
}
const objectRegistry& obr = this->mesh().thisDb();
const label patchIndex = patch_.index();
// Local, temporary storage and/or lookup values
bool found = false;
tmp> vfield;
tmp> pfield;
for (int checki = 0; !found && checki < 2; ++checki)
{
// Check 0: object context (first)
// Check 1: regular objectRegistry
const regIOobject* ioptr =
(
(checki == 0)
? exprDriver::cfindContextIOobject(name)
: obr.cfindIOobject(name)
);
if (!ioptr) continue;
if (!found)
{
vfield.cref(dynamic_cast*>(ioptr));
found = vfield.valid();
}
if (!found)
{
pfield.cref(dynamic_cast*>(ioptr));
found = pfield.valid();
}
}
// Finally, search files if necessary (and permitted)
if (!found && searchFiles())
{
const word fldType = this->getTypeOfField(name);
if (fldType == VolumeField::typeName)
{
vfield = this->readAndRegister>(name, mesh());
}
else if (fldType == PointField::typeName)
{
pfield = this->readAndRegister>
(
name,
pointMesh::New(mesh())
);
}
}
if (vfield.valid())
{
return vfield().boundaryField()[patchIndex].patchInternalField();
}
if (pfield.valid())
{
return pfield().boundaryField()[patchIndex].patchInternalField();
}
FatalErrorInFunction
<< "No field '" << name << "' of type "
<< pTraits::typeName << nl << nl;
FatalError
<< VolumeField::typeName << " Fields: "
<< flatOutput(obr.sortedNames>()) << nl;
FatalError
<< PointField::typeName << " Fields: "
<< flatOutput(obr.sortedNames>()) << nl;
FatalError
<< exit(FatalError);
return tmp>::New();
}
template
Foam::tmp>
Foam::expressions::patchExpr::parseDriver::patchNeighbourField
(
const word& name
)
{
tmp> tfield = getVariableIfAvailable(name);
if (tfield.valid())
{
return tfield;
}
const objectRegistry& obr = this->mesh().thisDb();
const label patchIndex = patch_.index();
// Local, temporary storage and/or lookup values
bool found = false;
tmp> vfield;
for (int checki = 0; !found && checki < 2; ++checki)
{
// Check 0: object context (first)
// Check 1: regular objectRegistry
const regIOobject* ioptr =
(
(checki == 0)
? exprDriver::cfindContextIOobject(name)
: obr.cfindIOobject(name)
);
if (!ioptr) continue;
if (!found)
{
vfield.cref(dynamic_cast*>(ioptr));
found = vfield.valid();
}
}
// Finally, search files if necessary (and permitted)
if (!found && searchFiles())
{
const word fldType = this->getTypeOfField(name);
if (fldType == VolumeField::typeName)
{
vfield = this->readAndRegister>(name, mesh());
}
}
if (vfield.valid())
{
return vfield().boundaryField()[patchIndex].patchNeighbourField();
}
FatalErrorInFunction
<< "No field '" << name << "' of type "
<< pTraits::typeName << nl << nl;
FatalError
<< VolumeField::typeName << " Fields: "
<< flatOutput(obr.sortedNames>()) << nl;
FatalError
<< exit(FatalError);
return tmp>::New();
}
template
Foam::tmp>
Foam::expressions::patchExpr::parseDriver::patchNormalField
(
const word& name
)
{
tmp> tfield = getVariableIfAvailable(name);
if (tfield.valid())
{
return tfield;
}
const objectRegistry& obr = this->mesh().thisDb();
const label patchIndex = patch_.index();
// Local, temporary storage and/or lookup values
bool found = false;
tmp> vfield;
for (int checki = 0; !found && checki < 2; ++checki)
{
// Check 0: object context (first)
// Check 1: regular objectRegistry
const regIOobject* ioptr =
(
(checki == 0)
? exprDriver::cfindContextIOobject(name)
: obr.cfindIOobject(name)
);
if (!ioptr) continue;
if (!found)
{
vfield.cref(dynamic_cast*>(ioptr));
found = vfield.valid();
}
}
// Finally, search files if necessary (and permitted)
if (!found && searchFiles())
{
const word fldType = this->getTypeOfField(name);
if (fldType == VolumeField::typeName)
{
vfield = this->readAndRegister>(name, mesh());
}
}
if (vfield.valid())
{
return vfield().boundaryField()[patchIndex].snGrad();
}
FatalErrorInFunction
<< "No field '" << name << "' of type "
<< pTraits::typeName << nl << nl;
FatalError
<< VolumeField::typeName << " Fields: "
<< flatOutput(obr.sortedNames>()) << nl;
FatalError
<< exit(FatalError);
return tmp>::New();
}
template
Foam::tmp>
Foam::expressions::patchExpr::parseDriver::faceToPoint
(
const Field& field
) const
{
primitivePatchInterpolation interp(patch_.patch());
return interp.faceToPointInterpolate(field);
}
template
Foam::tmp>
Foam::expressions::patchExpr::parseDriver::pointToFace
(
const Field& field
) const
{
primitivePatchInterpolation interp(patch_.patch());
return interp.pointToFaceInterpolate(field);
}
// ************************************************************************* //