Files
openfoam/src/genericPatchFields/genericFaPatchField/genericFaPatchField.C
Mark Olesen 15c53a2ef1 ENH: for-range, forAllIters() ... in genericPatchFields/
- reduced clutter when iterating over containers
2019-01-07 09:20:51 +01:00

758 lines
24 KiB
C

/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
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 "genericFaPatchField.H"
#include "faPatchFieldMapper.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::genericFaPatchField<Type>::genericFaPatchField
(
const faPatch& p,
const DimensionedField<Type, areaMesh>& iF
)
:
calculatedFaPatchField<Type>(p, iF)
{
FatalErrorInFunction
<< "Trying to construct an genericFaPatchField on patch "
<< this->patch().name()
<< " of field " << this->internalField().name()
<< abort(FatalError);
}
template<class Type>
Foam::genericFaPatchField<Type>::genericFaPatchField
(
const faPatch& p,
const DimensionedField<Type, areaMesh>& iF,
const dictionary& dict
)
:
calculatedFaPatchField<Type>(p, iF, dict),
actualTypeName_(dict.get<word>("type")),
dict_(dict)
{
if (!dict.found("value"))
{
FatalIOErrorInFunction(dict)
<< "\n Cannot find 'value' entry"
<< " on patch " << this->patch().name()
<< " of field " << this->internalField().name()
<< " in file " << this->internalField().objectPath()
<< nl
<< " which is required to set the"
" values of the generic patch field." << nl
<< " (Actual type " << actualTypeName_ << ")" << nl
<< "\n Please add the 'value' entry to the write function "
"of the user-defined boundary-condition\n"
<< exit(FatalIOError);
}
for (const entry& dEntry : dict_)
{
const keyType& key = dEntry.keyword();
if (key != "type" && key != "value")
{
if
(
dEntry.isStream()
&& dEntry.stream().size()
)
{
ITstream& is = dEntry.stream();
// Read first token
token firstToken(is);
if
(
firstToken.isWord()
&& firstToken.wordToken() == "nonuniform"
)
{
token fieldToken(is);
if (!fieldToken.isCompound())
{
if
(
fieldToken.isLabel()
&& fieldToken.labelToken() == 0
)
{
scalarFields_.insert
(
key,
autoPtr<scalarField>::New()
);
}
else
{
FatalIOErrorInFunction(dict)
<< "\n token following 'nonuniform' "
"is not a compound"
<< "\n on patch " << this->patch().name()
<< " of field "
<< this->internalField().name()
<< " in file "
<< this->internalField().objectPath()
<< exit(FatalIOError);
}
}
else if
(
fieldToken.compoundToken().type()
== token::Compound<List<scalar>>::typeName
)
{
auto fPtr = autoPtr<scalarField>::New();
fPtr->transfer
(
dynamicCast<token::Compound<List<scalar>>>
(
fieldToken.transferCompoundToken(is)
)
);
if (fPtr->size() != this->size())
{
FatalIOErrorInFunction(dict)
<< "\n size of field " << key
<< " (" << fPtr->size() << ')'
<< " is not the same size as the patch ("
<< this->size() << ')'
<< "\n on patch " << this->patch().name()
<< " of field "
<< this->internalField().name()
<< " in file "
<< this->internalField().objectPath()
<< exit(FatalIOError);
}
scalarFields_.insert(key, fPtr);
}
else if
(
fieldToken.compoundToken().type()
== token::Compound<List<vector>>::typeName
)
{
auto fPtr = autoPtr<vectorField>::New();
fPtr->transfer
(
dynamicCast<token::Compound<List<vector>>>
(
fieldToken.transferCompoundToken(is)
)
);
if (fPtr->size() != this->size())
{
FatalIOErrorInFunction(dict)
<< "\n size of field " << key
<< " (" << fPtr->size() << ')'
<< " is not the same size as the patch ("
<< this->size() << ')'
<< "\n on patch " << this->patch().name()
<< " of field "
<< this->internalField().name()
<< " in file "
<< this->internalField().objectPath()
<< exit(FatalIOError);
}
vectorFields_.insert(key, fPtr);
}
else if
(
fieldToken.compoundToken().type()
== token::Compound<List<sphericalTensor>>::typeName
)
{
auto fPtr = autoPtr<sphericalTensorField>::New();
fPtr->transfer
(
dynamicCast
<
token::Compound<List<sphericalTensor>>
>
(
fieldToken.transferCompoundToken(is)
)
);
if (fPtr->size() != this->size())
{
FatalIOErrorInFunction(dict)
<< "\n size of field " << key
<< " (" << fPtr->size() << ')'
<< " is not the same size as the patch ("
<< this->size() << ')'
<< "\n on patch " << this->patch().name()
<< " of field "
<< this->internalField().name()
<< " in file "
<< this->internalField().objectPath()
<< exit(FatalIOError);
}
sphTensorFields_.insert(key, fPtr);
}
else if
(
fieldToken.compoundToken().type()
== token::Compound<List<symmTensor>>::typeName
)
{
auto fPtr = autoPtr<symmTensorField>::New();
fPtr->transfer
(
dynamicCast
<
token::Compound<List<symmTensor>>
>
(
fieldToken.transferCompoundToken(is)
)
);
if (fPtr->size() != this->size())
{
FatalIOErrorInFunction(dict)
<< "\n size of field " << key
<< " (" << fPtr->size() << ')'
<< " is not the same size as the patch ("
<< this->size() << ')'
<< "\n on patch " << this->patch().name()
<< " of field "
<< this->internalField().name()
<< " in file "
<< this->internalField().objectPath()
<< exit(FatalIOError);
}
symmTensorFields_.insert(key, fPtr);
}
else if
(
fieldToken.compoundToken().type()
== token::Compound<List<tensor>>::typeName
)
{
auto fPtr = autoPtr<tensorField>::New();
fPtr->transfer
(
dynamicCast<token::Compound<List<tensor>>>
(
fieldToken.transferCompoundToken(is)
)
);
if (fPtr->size() != this->size())
{
FatalIOErrorInFunction(dict)
<< "\n size of field " << key
<< " (" << fPtr->size() << ')'
<< " is not the same size as the patch ("
<< this->size() << ')'
<< "\n on patch " << this->patch().name()
<< " of field "
<< this->internalField().name()
<< " in file "
<< this->internalField().objectPath()
<< exit(FatalIOError);
}
tensorFields_.insert(key, fPtr);
}
else
{
FatalIOErrorInFunction(dict)
<< "\n compound " << fieldToken.compoundToken()
<< " not supported"
<< "\n on patch " << this->patch().name()
<< " of field "
<< this->internalField().name()
<< " in file "
<< this->internalField().objectPath()
<< exit(FatalIOError);
}
}
else if
(
firstToken.isWord()
&& firstToken.wordToken() == "uniform"
)
{
token fieldToken(is);
if (!fieldToken.isPunctuation())
{
scalarFields_.insert
(
key,
autoPtr<scalarField>::New
(
this->size(),
fieldToken.number()
)
);
}
else
{
// Read as scalarList.
is.putBack(fieldToken);
scalarList l(is);
if (l.size() == vector::nComponents)
{
vector vs(l[0], l[1], l[2]);
vectorFields_.insert
(
key,
autoPtr<vectorField>::New
(
this->size(),
vs
)
);
}
else if (l.size() == sphericalTensor::nComponents)
{
sphericalTensor vs(l[0]);
sphTensorFields_.insert
(
key,
autoPtr<sphericalTensorField>::New
(
this->size(),
vs
)
);
}
else if (l.size() == symmTensor::nComponents)
{
symmTensor vs(l[0], l[1], l[2], l[3], l[4], l[5]);
symmTensorFields_.insert
(
key,
autoPtr<symmTensorField>::New
(
this->size(),
vs
)
);
}
else if (l.size() == tensor::nComponents)
{
tensor vs
(
l[0], l[1], l[2],
l[3], l[4], l[5],
l[6], l[7], l[8]
);
tensorFields_.insert
(
key,
autoPtr<tensorField>::New
(
this->size(),
vs
)
);
}
else
{
FatalIOErrorInFunction(dict)
<< "\n unrecognised native type " << l
<< "\n on patch " << this->patch().name()
<< " of field "
<< this->internalField().name()
<< " in file "
<< this->internalField().objectPath()
<< exit(FatalIOError);
}
}
}
}
}
}
}
template<class Type>
Foam::genericFaPatchField<Type>::genericFaPatchField
(
const genericFaPatchField<Type>& ptf,
const faPatch& p,
const DimensionedField<Type, areaMesh>& iF,
const faPatchFieldMapper& mapper
)
:
calculatedFaPatchField<Type>(ptf, p, iF, mapper),
actualTypeName_(ptf.actualTypeName_),
dict_(ptf.dict_)
{
forAllConstIters(ptf.scalarFields_, iter)
{
scalarFields_.insert
(
iter.key(),
autoPtr<scalarField>::New(*iter(), mapper)
);
}
forAllConstIters(ptf.vectorFields_, iter)
{
vectorFields_.insert
(
iter.key(),
autoPtr<vectorField>::New(*iter(), mapper)
);
}
forAllConstIters(ptf.sphTensorFields_, iter)
{
sphTensorFields_.insert
(
iter.key(),
autoPtr<sphericalTensorField>::New(*iter(), mapper)
);
}
forAllConstIters(ptf.symmTensorFields_, iter)
{
symmTensorFields_.insert
(
iter.key(),
autoPtr<symmTensorField>::New(*iter(), mapper)
);
}
forAllConstIters(ptf.tensorFields_, iter)
{
tensorFields_.insert
(
iter.key(),
autoPtr<tensorField>::New(*iter(), mapper)
);
}
}
template<class Type>
Foam::genericFaPatchField<Type>::genericFaPatchField
(
const genericFaPatchField<Type>& ptf
)
:
calculatedFaPatchField<Type>(ptf),
actualTypeName_(ptf.actualTypeName_),
dict_(ptf.dict_),
scalarFields_(ptf.scalarFields_),
vectorFields_(ptf.vectorFields_),
sphTensorFields_(ptf.sphTensorFields_),
symmTensorFields_(ptf.symmTensorFields_),
tensorFields_(ptf.tensorFields_)
{}
template<class Type>
Foam::genericFaPatchField<Type>::genericFaPatchField
(
const genericFaPatchField<Type>& ptf,
const DimensionedField<Type, areaMesh>& iF
)
:
calculatedFaPatchField<Type>(ptf, iF),
actualTypeName_(ptf.actualTypeName_),
dict_(ptf.dict_),
scalarFields_(ptf.scalarFields_),
vectorFields_(ptf.vectorFields_),
sphTensorFields_(ptf.sphTensorFields_),
symmTensorFields_(ptf.symmTensorFields_),
tensorFields_(ptf.tensorFields_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::genericFaPatchField<Type>::autoMap
(
const faPatchFieldMapper& m
)
{
calculatedFaPatchField<Type>::autoMap(m);
forAllIters(scalarFields_, iter)
{
iter()->autoMap(m);
}
forAllIters(vectorFields_, iter)
{
iter()->autoMap(m);
}
forAllIters(sphTensorFields_, iter)
{
iter()->autoMap(m);
}
forAllIters(symmTensorFields_, iter)
{
iter()->autoMap(m);
}
forAllIters(tensorFields_, iter)
{
iter()->autoMap(m);
}
}
template<class Type>
void Foam::genericFaPatchField<Type>::rmap
(
const faPatchField<Type>& ptf,
const labelList& addr
)
{
calculatedFaPatchField<Type>::rmap(ptf, addr);
const genericFaPatchField<Type>& dptf =
refCast<const genericFaPatchField<Type>>(ptf);
forAllIters(scalarFields_, iter )
{
const auto iter2 = dptf.scalarFields_.cfind(iter.key());
if (iter.found())
{
iter()->rmap(*iter2(), addr);
}
}
forAllIters(vectorFields_, iter)
{
const auto iter2 = dptf.vectorFields_.cfind(iter.key());
if (iter.found())
{
iter()->rmap(*iter2(), addr);
}
}
forAllIters(sphTensorFields_, iter)
{
const auto iter2 = dptf.sphTensorFields_.cfind(iter.key());
if (iter.found())
{
iter()->rmap(*iter2(), addr);
}
}
forAllIters(symmTensorFields_, iter)
{
const auto iter2 = dptf.symmTensorFields_.cfind(iter.key());
if (iter.found())
{
iter()->rmap(*iter2(), addr);
}
}
forAllIters(tensorFields_, iter)
{
const auto iter2 = dptf.tensorFields_.find(iter.key());
if (iter.found())
{
iter()->rmap(*iter2(), addr);
}
}
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::genericFaPatchField<Type>::valueInternalCoeffs
(
const tmp<scalarField>&
) const
{
FatalErrorInFunction
<< "cannot be called for a genericFaPatchField"
" (actual type " << actualTypeName_ << ")"
<< "\n on patch " << this->patch().name()
<< " of field " << this->internalField().name()
<< " in file " << this->internalField().objectPath()
<< "\n You are probably trying to solve for a field with a "
"generic boundary condition."
<< abort(FatalError);
return *this;
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::genericFaPatchField<Type>::valueBoundaryCoeffs
(
const tmp<scalarField>&
) const
{
FatalErrorInFunction
<< "cannot be called for a genericFaPatchField"
" (actual type " << actualTypeName_ << ")"
<< "\n on patch " << this->patch().name()
<< " of field " << this->internalField().name()
<< " in file " << this->internalField().objectPath()
<< "\n You are probably trying to solve for a field with a "
"generic boundary condition."
<< abort(FatalError);
return *this;
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::genericFaPatchField<Type>::gradientInternalCoeffs() const
{
FatalErrorInFunction
<< "cannot be called for a genericFaPatchField"
" (actual type " << actualTypeName_ << ")"
<< "\n on patch " << this->patch().name()
<< " of field " << this->internalField().name()
<< " in file " << this->internalField().objectPath()
<< "\n You are probably trying to solve for a field with a "
"generic boundary condition."
<< abort(FatalError);
return *this;
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::genericFaPatchField<Type>::gradientBoundaryCoeffs() const
{
FatalErrorInFunction
<< "cannot be called for a genericFaPatchField"
" (actual type " << actualTypeName_ << ")"
<< "\n on patch " << this->patch().name()
<< " of field " << this->internalField().name()
<< " in file " << this->internalField().objectPath()
<< "\n You are probably trying to solve for a field with a "
"generic boundary condition."
<< abort(FatalError);
return *this;
}
template<class Type>
const Foam::word& Foam::genericFaPatchField<Type>::actualType() const
{
return actualTypeName_;
}
template<class Type>
void Foam::genericFaPatchField<Type>::write(Ostream& os) const
{
os.writeEntry("type", actualTypeName_);
for (const entry& dEntry : dict_)
{
const keyType& key = dEntry.keyword();
if (key != "type" && key != "value")
{
if
(
dEntry.isStream()
&& dEntry.stream().size()
&& dEntry.stream()[0].isWord()
&& dEntry.stream()[0].wordToken() == "nonuniform"
)
{
if (scalarFields_.found(key))
{
scalarFields_.find(key)()
->writeEntry(key, os);
}
else if (vectorFields_.found(key))
{
vectorFields_.find(key)()
->writeEntry(key, os);
}
else if (sphTensorFields_.found(key))
{
sphTensorFields_.find(key)()
->writeEntry(key, os);
}
else if (symmTensorFields_.found(key))
{
symmTensorFields_.find(key)()
->writeEntry(key, os);
}
else if (tensorFields_.found(key))
{
tensorFields_.find(key)()
->writeEntry(key, os);
}
}
else
{
dEntry.write(os);
}
}
}
this->writeEntry("value", os);
}
// ************************************************************************* //