OpenFOAM-4.x/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C
Henry Weller a25a449c9e GeometricField: Rationalized and simplified access to the dimensioned internal field
Given that the type of the dimensioned internal field is encapsulated in
the GeometricField class the name need not include "Field"; the type
name is "Internal" so

volScalarField::DimensionedInternalField -> volScalarField::Internal

In addition to the ".dimensionedInternalField()" access function the
simpler "()" de-reference operator is also provided to greatly simplify
FV equation source term expressions which need not evaluate boundary
conditions.  To demonstrate this kEpsilon.C has been updated to use
dimensioned internal field expressions in the k and epsilon equation
source terms.
2016-04-27 21:32:45 +01:00

1284 lines
33 KiB
C

/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "GeometricField.H"
#include "Time.H"
#include "demandDrivenData.H"
#include "dictionary.H"
#include "data.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#define checkField(gf1, gf2, op) \
if ((gf1).mesh() != (gf2).mesh()) \
{ \
FatalErrorInFunction \
<< "different mesh for fields " \
<< (gf1).name() << " and " << (gf2).name() \
<< " during operatrion " << op \
<< abort(FatalError); \
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::readFields
(
const dictionary& dict
)
{
DimensionedField<Type, GeoMesh>::readField(dict, "internalField");
boundaryField_.readField(*this, dict.subDict("boundaryField"));
if (dict.found("referenceLevel"))
{
Type fieldAverage(pTraits<Type>(dict.lookup("referenceLevel")));
Field<Type>::operator+=(fieldAverage);
forAll(boundaryField_, patchi)
{
boundaryField_[patchi] == boundaryField_[patchi] + fieldAverage;
}
}
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::readFields()
{
const IOdictionary dict
(
IOobject
(
this->name(),
this->time().timeName(),
this->db(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
this->readStream(typeName)
);
this->close();
readFields(dict);
}
template<class Type, template<class> class PatchField, class GeoMesh>
bool Foam::GeometricField<Type, PatchField, GeoMesh>::readIfPresent()
{
if
(
this->readOpt() == IOobject::MUST_READ
|| this->readOpt() == IOobject::MUST_READ_IF_MODIFIED
)
{
WarningInFunction
<< "read option IOobject::MUST_READ or MUST_READ_IF_MODIFIED"
<< " suggests that a read constructor for field " << this->name()
<< " would be more appropriate." << endl;
}
else if (this->readOpt() == IOobject::READ_IF_PRESENT && this->headerOk())
{
readFields();
// Check compatibility between field and mesh
if (this->size() != GeoMesh::size(this->mesh()))
{
FatalIOErrorInFunction(this->readStream(typeName))
<< " number of field elements = " << this->size()
<< " number of mesh elements = "
<< GeoMesh::size(this->mesh())
<< exit(FatalIOError);
}
readOldTimeIfPresent();
return true;
}
return false;
}
template<class Type, template<class> class PatchField, class GeoMesh>
bool Foam::GeometricField<Type, PatchField, GeoMesh>::readOldTimeIfPresent()
{
// Read the old time field if present
IOobject field0
(
this->name() + "_0",
this->time().timeName(),
this->db(),
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE,
this->registerObject()
);
if (field0.headerOk())
{
if (debug)
{
InfoInFunction << "Reading old time level for field"
<< endl << this->info() << endl;
}
field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
(
field0,
this->mesh()
);
field0Ptr_->timeIndex_ = timeIndex_ - 1;
if (!field0Ptr_->readOldTimeIfPresent())
{
field0Ptr_->oldTime();
}
return true;
}
return false;
}
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const IOobject& io,
const Mesh& mesh,
const dimensionSet& ds,
const word& patchFieldType
)
:
DimensionedField<Type, GeoMesh>(io, mesh, ds, false),
timeIndex_(this->time().timeIndex()),
field0Ptr_(NULL),
fieldPrevIterPtr_(NULL),
boundaryField_(mesh.boundary(), *this, patchFieldType)
{
if (debug)
{
InfoInFunction << "Creating temporary" << endl << this->info() << endl;
}
readIfPresent();
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const IOobject& io,
const Mesh& mesh,
const dimensionSet& ds,
const wordList& patchFieldTypes,
const wordList& actualPatchTypes
)
:
DimensionedField<Type, GeoMesh>(io, mesh, ds, false),
timeIndex_(this->time().timeIndex()),
field0Ptr_(NULL),
fieldPrevIterPtr_(NULL),
boundaryField_(mesh.boundary(), *this, patchFieldTypes, actualPatchTypes)
{
if (debug)
{
InfoInFunction << "Creating temporary" << endl << this->info() << endl;
}
readIfPresent();
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const IOobject& io,
const Mesh& mesh,
const dimensioned<Type>& dt,
const word& patchFieldType
)
:
DimensionedField<Type, GeoMesh>(io, mesh, dt, false),
timeIndex_(this->time().timeIndex()),
field0Ptr_(NULL),
fieldPrevIterPtr_(NULL),
boundaryField_(mesh.boundary(), *this, patchFieldType)
{
if (debug)
{
InfoInFunction << "Creating temporary" << endl << this->info() << endl;
}
boundaryField_ == dt.value();
readIfPresent();
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const IOobject& io,
const Mesh& mesh,
const dimensioned<Type>& dt,
const wordList& patchFieldTypes,
const wordList& actualPatchTypes
)
:
DimensionedField<Type, GeoMesh>(io, mesh, dt, false),
timeIndex_(this->time().timeIndex()),
field0Ptr_(NULL),
fieldPrevIterPtr_(NULL),
boundaryField_(mesh.boundary(), *this, patchFieldTypes, actualPatchTypes)
{
if (debug)
{
InfoInFunction << "Creating temporary" << endl << this->info() << endl;
}
boundaryField_ == dt.value();
readIfPresent();
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const IOobject& io,
const Mesh& mesh,
const dimensionSet& ds,
const Field<Type>& iField,
const PtrList<PatchField<Type>>& ptfl
)
:
DimensionedField<Type, GeoMesh>(io, mesh, ds, iField),
timeIndex_(this->time().timeIndex()),
field0Ptr_(NULL),
fieldPrevIterPtr_(NULL),
boundaryField_(mesh.boundary(), *this, ptfl)
{
if (debug)
{
InfoInFunction
<< "Constructing from components" << endl << this->info() << endl;
}
readIfPresent();
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const IOobject& io,
const Mesh& mesh
)
:
DimensionedField<Type, GeoMesh>(io, mesh, dimless, false),
timeIndex_(this->time().timeIndex()),
field0Ptr_(NULL),
fieldPrevIterPtr_(NULL),
boundaryField_(mesh.boundary())
{
readFields();
// Check compatibility between field and mesh
if (this->size() != GeoMesh::size(this->mesh()))
{
FatalIOErrorInFunction(this->readStream(typeName))
<< " number of field elements = " << this->size()
<< " number of mesh elements = " << GeoMesh::size(this->mesh())
<< exit(FatalIOError);
}
readOldTimeIfPresent();
if (debug)
{
InfoInFunction
<< "Finishing read-construction of" << endl << this->info() << endl;
}
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const IOobject& io,
const Mesh& mesh,
const dictionary& dict
)
:
DimensionedField<Type, GeoMesh>(io, mesh, dimless, false),
timeIndex_(this->time().timeIndex()),
field0Ptr_(NULL),
fieldPrevIterPtr_(NULL),
boundaryField_(mesh.boundary())
{
readFields(dict);
// Check compatibility between field and mesh
if (this->size() != GeoMesh::size(this->mesh()))
{
FatalErrorInFunction
<< " number of field elements = " << this->size()
<< " number of mesh elements = " << GeoMesh::size(this->mesh())
<< exit(FatalIOError);
}
readOldTimeIfPresent();
if (debug)
{
InfoInFunction
<< "Finishing dictionary-construct of "
<< endl << this->info() << endl;
}
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const GeometricField<Type, PatchField, GeoMesh>& gf
)
:
DimensionedField<Type, GeoMesh>(gf),
timeIndex_(gf.timeIndex()),
field0Ptr_(NULL),
fieldPrevIterPtr_(NULL),
boundaryField_(*this, gf.boundaryField_)
{
if (debug)
{
InfoInFunction
<< "Constructing as copy" << endl << this->info() << endl;
}
if (gf.field0Ptr_)
{
field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
(
*gf.field0Ptr_
);
}
this->writeOpt() = IOobject::NO_WRITE;
}
#ifndef NoConstructFromTmp
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const tmp<GeometricField<Type, PatchField, GeoMesh>>& tgf
)
:
DimensionedField<Type, GeoMesh>
(
const_cast<GeometricField<Type, PatchField, GeoMesh>&>(tgf()),
tgf.isTmp()
),
timeIndex_(tgf().timeIndex()),
field0Ptr_(NULL),
fieldPrevIterPtr_(NULL),
boundaryField_(*this, tgf().boundaryField_)
{
if (debug)
{
InfoInFunction
<< "Constructing from tmp" << endl << this->info() << endl;
}
this->writeOpt() = IOobject::NO_WRITE;
tgf.clear();
}
#endif
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const IOobject& io,
const GeometricField<Type, PatchField, GeoMesh>& gf
)
:
DimensionedField<Type, GeoMesh>(io, gf),
timeIndex_(gf.timeIndex()),
field0Ptr_(NULL),
fieldPrevIterPtr_(NULL),
boundaryField_(*this, gf.boundaryField_)
{
if (debug)
{
InfoInFunction
<< "Constructing as copy resetting IO params"
<< endl << this->info() << endl;
}
if (!readIfPresent() && gf.field0Ptr_)
{
field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
(
io.name() + "_0",
*gf.field0Ptr_
);
}
}
#ifndef NoConstructFromTmp
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const IOobject& io,
const tmp<GeometricField<Type, PatchField, GeoMesh>>& tgf
)
:
DimensionedField<Type, GeoMesh>
(
io,
const_cast<GeometricField<Type, PatchField, GeoMesh>&>(tgf()),
tgf.isTmp()
),
timeIndex_(tgf().timeIndex()),
field0Ptr_(NULL),
fieldPrevIterPtr_(NULL),
boundaryField_(*this, tgf().boundaryField_)
{
if (debug)
{
InfoInFunction
<< "Constructing from tmp resetting IO params"
<< endl << this->info() << endl;
}
tgf.clear();
readIfPresent();
}
#endif
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const word& newName,
const GeometricField<Type, PatchField, GeoMesh>& gf
)
:
DimensionedField<Type, GeoMesh>(newName, gf),
timeIndex_(gf.timeIndex()),
field0Ptr_(NULL),
fieldPrevIterPtr_(NULL),
boundaryField_(*this, gf.boundaryField_)
{
if (debug)
{
InfoInFunction
<< "Constructing as copy resetting name"
<< endl << this->info() << endl;
}
if (!readIfPresent() && gf.field0Ptr_)
{
field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
(
newName + "_0",
*gf.field0Ptr_
);
}
}
#ifndef NoConstructFromTmp
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const word& newName,
const tmp<GeometricField<Type, PatchField, GeoMesh>>& tgf
)
:
DimensionedField<Type, GeoMesh>
(
newName,
const_cast<GeometricField<Type, PatchField, GeoMesh>&>(tgf()),
tgf.isTmp()
),
timeIndex_(tgf().timeIndex()),
field0Ptr_(NULL),
fieldPrevIterPtr_(NULL),
boundaryField_(*this, tgf().boundaryField_)
{
if (debug)
{
InfoInFunction
<< "Constructing from tmp resetting name"
<< endl << this->info() << endl;
}
tgf.clear();
}
#endif
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const IOobject& io,
const GeometricField<Type, PatchField, GeoMesh>& gf,
const word& patchFieldType
)
:
DimensionedField<Type, GeoMesh>(io, gf),
timeIndex_(gf.timeIndex()),
field0Ptr_(NULL),
fieldPrevIterPtr_(NULL),
boundaryField_(this->mesh().boundary(), *this, patchFieldType)
{
if (debug)
{
InfoInFunction
<< "Constructing as copy resetting IO params"
<< endl << this->info() << endl;
}
boundaryField_ == gf.boundaryField_;
if (!readIfPresent() && gf.field0Ptr_)
{
field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
(
io.name() + "_0",
*gf.field0Ptr_
);
}
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const IOobject& io,
const GeometricField<Type, PatchField, GeoMesh>& gf,
const wordList& patchFieldTypes,
const wordList& actualPatchTypes
)
:
DimensionedField<Type, GeoMesh>(io, gf),
timeIndex_(gf.timeIndex()),
field0Ptr_(NULL),
fieldPrevIterPtr_(NULL),
boundaryField_
(
this->mesh().boundary(),
*this,
patchFieldTypes,
actualPatchTypes
)
{
if (debug)
{
InfoInFunction
<< "Constructing as copy resetting IO params and patch types"
<< endl << this->info() << endl;
}
boundaryField_ == gf.boundaryField_;
if (!readIfPresent() && gf.field0Ptr_)
{
field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
(
io.name() + "_0",
*gf.field0Ptr_
);
}
}
#ifndef NoConstructFromTmp
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const IOobject& io,
const tmp<GeometricField<Type, PatchField, GeoMesh>>& tgf,
const wordList& patchFieldTypes,
const wordList& actualPatchTypes
)
:
DimensionedField<Type, GeoMesh>
(
io,
const_cast<GeometricField<Type, PatchField, GeoMesh>&>(tgf()),
tgf.isTmp()
),
timeIndex_(tgf().timeIndex()),
field0Ptr_(NULL),
fieldPrevIterPtr_(NULL),
boundaryField_
(
this->mesh().boundary(),
*this,
patchFieldTypes,
actualPatchTypes
)
{
if (debug)
{
InfoInFunction
<< "Constructing from tmp resetting IO params and patch types"
<< endl << this->info() << endl;
}
boundaryField_ == tgf().boundaryField_;
tgf.clear();
}
#endif
// * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::~GeometricField()
{
deleteDemandDrivenData(field0Ptr_);
deleteDemandDrivenData(fieldPrevIterPtr_);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh>
typename
Foam::GeometricField<Type, PatchField, GeoMesh>::Internal&
Foam::GeometricField<Type, PatchField, GeoMesh>::dimensionedInternalFieldRef()
{
this->setUpToDate();
storeOldTimes();
return *this;
}
template<class Type, template<class> class PatchField, class GeoMesh>
typename
Foam::GeometricField<Type, PatchField, GeoMesh>::Internal::FieldType&
Foam::GeometricField<Type, PatchField, GeoMesh>::internalField()
{
this->setUpToDate();
storeOldTimes();
return *this;
}
template<class Type, template<class> class PatchField, class GeoMesh>
typename
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricBoundaryField&
Foam::GeometricField<Type, PatchField, GeoMesh>::boundaryFieldRef()
{
this->setUpToDate();
storeOldTimes();
return boundaryField_;
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::storeOldTimes() const
{
if
(
field0Ptr_
&& timeIndex_ != this->time().timeIndex()
&& !(
this->name().size() > 2
&& this->name()(this->name().size()-2, 2) == "_0"
)
)
{
storeOldTime();
}
// Correct time index
timeIndex_ = this->time().timeIndex();
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::storeOldTime() const
{
if (field0Ptr_)
{
field0Ptr_->storeOldTime();
if (debug)
{
InfoInFunction
<< "Storing old time field for field" << endl
<< this->info() << endl;
}
*field0Ptr_ == *this;
field0Ptr_->timeIndex_ = timeIndex_;
if (field0Ptr_->field0Ptr_)
{
field0Ptr_->writeOpt() = this->writeOpt();
}
}
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::label Foam::GeometricField<Type, PatchField, GeoMesh>::nOldTimes() const
{
if (field0Ptr_)
{
return field0Ptr_->nOldTimes() + 1;
}
else
{
return 0;
}
}
template<class Type, template<class> class PatchField, class GeoMesh>
const Foam::GeometricField<Type, PatchField, GeoMesh>&
Foam::GeometricField<Type, PatchField, GeoMesh>::oldTime() const
{
if (!field0Ptr_)
{
field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
(
IOobject
(
this->name() + "_0",
this->time().timeName(),
this->db(),
IOobject::NO_READ,
IOobject::NO_WRITE,
this->registerObject()
),
*this
);
}
else
{
storeOldTimes();
}
return *field0Ptr_;
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>&
Foam::GeometricField<Type, PatchField, GeoMesh>::oldTime()
{
static_cast<const GeometricField<Type, PatchField, GeoMesh>&>(*this)
.oldTime();
return *field0Ptr_;
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::storePrevIter() const
{
if (!fieldPrevIterPtr_)
{
if (debug)
{
InfoInFunction
<< "Allocating previous iteration field" << endl
<< this->info() << endl;
}
fieldPrevIterPtr_ = new GeometricField<Type, PatchField, GeoMesh>
(
this->name() + "PrevIter",
*this
);
}
else
{
*fieldPrevIterPtr_ == *this;
}
}
template<class Type, template<class> class PatchField, class GeoMesh>
const Foam::GeometricField<Type, PatchField, GeoMesh>&
Foam::GeometricField<Type, PatchField, GeoMesh>::prevIter() const
{
if (!fieldPrevIterPtr_)
{
FatalErrorInFunction
<< "previous iteration field" << endl << this->info() << endl
<< " not stored."
<< " Use field.storePrevIter() at start of iteration."
<< abort(FatalError);
}
return *fieldPrevIterPtr_;
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::
correctBoundaryConditions()
{
this->setUpToDate();
storeOldTimes();
boundaryField_.evaluate();
}
template<class Type, template<class> class PatchField, class GeoMesh>
bool Foam::GeometricField<Type, PatchField, GeoMesh>::needReference() const
{
// Search all boundary conditions, if any are
// fixed-value or mixed (Robin) do not set reference level for solution.
bool needRef = true;
forAll(boundaryField_, patchi)
{
if (boundaryField_[patchi].fixesValue())
{
needRef = false;
break;
}
}
reduce(needRef, andOp<bool>());
return needRef;
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::relax(const scalar alpha)
{
if (debug)
{
InfoInFunction
<< "Relaxing" << endl << this->info() << " by " << alpha << endl;
}
operator==(prevIter() + alpha*(*this - prevIter()));
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::relax()
{
word name = this->name();
if
(
this->mesh().data::template lookupOrDefault<bool>
(
"finalIteration",
false
)
)
{
name += "Final";
}
if (this->mesh().relaxField(name))
{
relax(this->mesh().fieldRelaxationFactor(name));
}
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::word Foam::GeometricField<Type, PatchField, GeoMesh>::select
(
bool final
) const
{
if (final)
{
return this->name() + "Final";
}
else
{
return this->name();
}
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::writeMinMax
(
Ostream& os
) const
{
os << "min/max(" << this->name() << ") = "
<< Foam::min(*this).value() << ", "
<< Foam::max(*this).value()
<< endl;
}
template<class Type, template<class> class PatchField, class GeoMesh>
bool Foam::GeometricField<Type, PatchField, GeoMesh>::
writeData(Ostream& os) const
{
os << *this;
return os.good();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh>>
Foam::GeometricField<Type, PatchField, GeoMesh>::T() const
{
tmp<GeometricField<Type, PatchField, GeoMesh>> result
(
new GeometricField<Type, PatchField, GeoMesh>
(
IOobject
(
this->name() + ".T()",
this->instance(),
this->db()
),
this->mesh(),
this->dimensions()
)
);
Foam::T(result.ref().internalField(), internalField());
Foam::T(result.ref().boundaryFieldRef(), boundaryField());
return result;
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::tmp
<
Foam::GeometricField
<
typename Foam::GeometricField<Type, PatchField, GeoMesh>::cmptType,
PatchField,
GeoMesh
>
>
Foam::GeometricField<Type, PatchField, GeoMesh>::component
(
const direction d
) const
{
tmp<GeometricField<cmptType, PatchField, GeoMesh>> Component
(
new GeometricField<cmptType, PatchField, GeoMesh>
(
IOobject
(
this->name() + ".component(" + Foam::name(d) + ')',
this->instance(),
this->db()
),
this->mesh(),
this->dimensions()
)
);
Foam::component(Component.ref().internalField(), internalField(), d);
Foam::component(Component.ref().boundaryFieldRef(), boundaryField(), d);
return Component;
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::replace
(
const direction d,
const GeometricField
<
typename GeometricField<Type, PatchField, GeoMesh>::cmptType,
PatchField,
GeoMesh
>& gcf
)
{
internalField().replace(d, gcf.internalField());
boundaryFieldRef().replace(d, gcf.boundaryField());
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::replace
(
const direction d,
const dimensioned<cmptType>& ds
)
{
internalField().replace(d, ds.value());
boundaryFieldRef().replace(d, ds.value());
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::max
(
const dimensioned<Type>& dt
)
{
Foam::max(internalField(), internalField(), dt.value());
Foam::max(boundaryFieldRef(), boundaryField(), dt.value());
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::min
(
const dimensioned<Type>& dt
)
{
Foam::min(internalField(), internalField(), dt.value());
Foam::min(boundaryFieldRef(), boundaryField(), dt.value());
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::negate()
{
internalField().negate();
boundaryFieldRef().negate();
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
(
const GeometricField<Type, PatchField, GeoMesh>& gf
)
{
if (this == &gf)
{
FatalErrorInFunction
<< "attempted assignment to self"
<< abort(FatalError);
}
checkField(*this, gf, "=");
// Only assign field contents not ID
dimensionedInternalFieldRef() = gf.dimensionedInternalField();
boundaryFieldRef() = gf.boundaryField();
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
(
const tmp<GeometricField<Type, PatchField, GeoMesh>>& tgf
)
{
if (this == &(tgf()))
{
FatalErrorInFunction
<< "attempted assignment to self"
<< abort(FatalError);
}
const GeometricField<Type, PatchField, GeoMesh>& gf = tgf();
checkField(*this, gf, "=");
// Only assign field contents not ID
this->dimensions() = gf.dimensions();
// Transfer the storage from the tmp
internalField().transfer
(
const_cast<Field<Type>&>(gf.internalField())
);
boundaryFieldRef() = gf.boundaryField();
tgf.clear();
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
(
const dimensioned<Type>& dt
)
{
dimensionedInternalFieldRef() = dt;
boundaryFieldRef() = dt.value();
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::operator==
(
const tmp<GeometricField<Type, PatchField, GeoMesh>>& tgf
)
{
const GeometricField<Type, PatchField, GeoMesh>& gf = tgf();
checkField(*this, gf, "==");
// Only assign field contents not ID
dimensionedInternalFieldRef() = gf.dimensionedInternalField();
boundaryFieldRef() == gf.boundaryField();
tgf.clear();
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::operator==
(
const dimensioned<Type>& dt
)
{
dimensionedInternalFieldRef() = dt;
boundaryFieldRef() == dt.value();
}
#define COMPUTED_ASSIGNMENT(TYPE, op) \
\
template<class Type, template<class> class PatchField, class GeoMesh> \
void Foam::GeometricField<Type, PatchField, GeoMesh>::operator op \
( \
const GeometricField<TYPE, PatchField, GeoMesh>& gf \
) \
{ \
checkField(*this, gf, #op); \
\
dimensionedInternalFieldRef() op gf.dimensionedInternalField(); \
boundaryFieldRef() op gf.boundaryField(); \
} \
\
template<class Type, template<class> class PatchField, class GeoMesh> \
void Foam::GeometricField<Type, PatchField, GeoMesh>::operator op \
( \
const tmp<GeometricField<TYPE, PatchField, GeoMesh>>& tgf \
) \
{ \
operator op(tgf()); \
tgf.clear(); \
} \
\
template<class Type, template<class> class PatchField, class GeoMesh> \
void Foam::GeometricField<Type, PatchField, GeoMesh>::operator op \
( \
const dimensioned<TYPE>& dt \
) \
{ \
dimensionedInternalFieldRef() op dt; \
boundaryFieldRef() op dt.value(); \
}
COMPUTED_ASSIGNMENT(Type, +=)
COMPUTED_ASSIGNMENT(Type, -=)
COMPUTED_ASSIGNMENT(scalar, *=)
COMPUTED_ASSIGNMENT(scalar, /=)
#undef COMPUTED_ASSIGNMENT
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const GeometricField<Type, PatchField, GeoMesh>& gf
)
{
gf.dimensionedInternalField().writeData(os, "internalField");
os << nl;
gf.boundaryField().writeEntry("boundaryField", os);
// Check state of IOstream
os.check
(
"Ostream& operator<<(Ostream&, "
"const GeometricField<Type, PatchField, GeoMesh>&)"
);
return (os);
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const tmp<GeometricField<Type, PatchField, GeoMesh>>& tgf
)
{
os << tgf();
tgf.clear();
return os;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#undef checkField
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "GeometricBoundaryField.C"
#include "GeometricFieldFunctions.C"
// ************************************************************************* //