/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd. \\/ 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 "GeometricField.H" #include "Time.H" #include "demandDrivenData.H" #include "dictionary.H" #include "data.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // check mesh for two fields #define checkField(gf1, gf2, op) \ if ((gf1).mesh() != (gf2).mesh()) \ { \ FatalErrorIn("checkField(gf1, gf2, op)") \ << "different mesh for fields " \ << (gf1).name() << " and " << (gf2).name() \ << " during operatrion " << op \ << abort(FatalError); \ } // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // template class PatchField, class GeoMesh> Foam::tmp < typename Foam::GeometricField:: GeometricBoundaryField > Foam::GeometricField::readField ( const dictionary& fieldDict ) { DimensionedField::readField(fieldDict, "internalField"); tmp tboundaryField ( new GeometricBoundaryField ( this->mesh().boundary(), *this, fieldDict.subDict("boundaryField") ) ); if (fieldDict.found("referenceLevel")) { Type fieldAverage(pTraits(fieldDict.lookup("referenceLevel"))); Field::operator+=(fieldAverage); GeometricBoundaryField& boundaryField = tboundaryField(); forAll(boundaryField, patchi) { boundaryField[patchi] == boundaryField[patchi] + fieldAverage; } } return tboundaryField; } template class PatchField, class GeoMesh> Foam::tmp < typename Foam::GeometricField:: GeometricBoundaryField > Foam::GeometricField::readField(Istream& is) { if (is.version() < 2.0) { FatalIOErrorIn ( "GeometricField::readField(Istream&)", is ) << "IO versions < 2.0 are not supported." << exit(FatalIOError); } return readField(dictionary(is)); } template class PatchField, class GeoMesh> bool Foam::GeometricField::readIfPresent() { if ( this->readOpt() == IOobject::MUST_READ || this->readOpt() == IOobject::MUST_READ_IF_MODIFIED ) { WarningIn ( "GeometricField::readIfPresent()" ) << "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()) { boundaryField_.transfer(readField(this->readStream(typeName))()); this->close(); // Check compatibility between field and mesh if (this->size() != GeoMesh::size(this->mesh())) { FatalIOErrorIn ( "GeometricField::" "readIfPresent()", 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 PatchField, class GeoMesh> bool Foam::GeometricField::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 ); if (field0.headerOk()) { if (debug) { Info<< "Reading old time level for field" << endl << this->info() << endl; } field0Ptr_ = new GeometricField ( field0, this->mesh() ); field0Ptr_->timeIndex_ = timeIndex_ - 1; if (!field0Ptr_->readOldTimeIfPresent()) { field0Ptr_->oldTime(); } return true; } return false; } // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // // Constructor given a GeometricField and dimensionSet // This allocates storage for the field but not values. // Note : This constructor should only be used to // construct TEMPORARY variables template class PatchField, class GeoMesh> Foam::GeometricField::GeometricField ( const IOobject& io, const Mesh& mesh, const dimensionSet& ds, const word& patchFieldType ) : DimensionedField(io, mesh, ds, false), timeIndex_(this->time().timeIndex()), field0Ptr_(NULL), fieldPrevIterPtr_(NULL), boundaryField_(mesh.boundary(), *this, patchFieldType) { if (debug) { Info<< "GeometricField::GeometricField : " "creating temporary" << endl << this->info() << endl; } readIfPresent(); } // Constructor given a GeometricField and dimensionSet // This allocates storage for the field but not values. // Note : This constructor should only be used to // construct TEMPORARY variables template class PatchField, class GeoMesh> Foam::GeometricField::GeometricField ( const IOobject& io, const Mesh& mesh, const dimensionSet& ds, const wordList& patchFieldTypes, const wordList& actualPatchTypes ) : DimensionedField(io, mesh, ds, false), timeIndex_(this->time().timeIndex()), field0Ptr_(NULL), fieldPrevIterPtr_(NULL), boundaryField_(mesh.boundary(), *this, patchFieldTypes, actualPatchTypes) { if (debug) { Info<< "GeometricField::GeometricField : " "creating temporary" << endl << this->info() << endl; } readIfPresent(); } // Constructor given a GeometricField and dimensioned template class PatchField, class GeoMesh> Foam::GeometricField::GeometricField ( const IOobject& io, const Mesh& mesh, const dimensioned& dt, const word& patchFieldType ) : DimensionedField(io, mesh, dt, false), timeIndex_(this->time().timeIndex()), field0Ptr_(NULL), fieldPrevIterPtr_(NULL), boundaryField_(mesh.boundary(), *this, patchFieldType) { if (debug) { Info<< "GeometricField::GeometricField : " "creating temporary" << endl << this->info() << endl; } boundaryField_ == dt.value(); readIfPresent(); } // Constructor given a GeometricField and dimensioned template class PatchField, class GeoMesh> Foam::GeometricField::GeometricField ( const IOobject& io, const Mesh& mesh, const dimensioned& dt, const wordList& patchFieldTypes, const wordList& actualPatchTypes ) : DimensionedField(io, mesh, dt, false), timeIndex_(this->time().timeIndex()), field0Ptr_(NULL), fieldPrevIterPtr_(NULL), boundaryField_(mesh.boundary(), *this, patchFieldTypes, actualPatchTypes) { if (debug) { Info<< "GeometricField::GeometricField : " "creating temporary" << endl << this->info() << endl; } boundaryField_ == dt.value(); readIfPresent(); } // construct from components template class PatchField, class GeoMesh> Foam::GeometricField::GeometricField ( const IOobject& io, const Mesh& mesh, const dimensionSet& ds, const Field& iField, const PtrList >& ptfl ) : DimensionedField(io, mesh, ds, iField), timeIndex_(this->time().timeIndex()), field0Ptr_(NULL), fieldPrevIterPtr_(NULL), boundaryField_(mesh.boundary(), *this, ptfl) { if (debug) { Info<< "GeometricField::GeometricField : " "constructing from components" << endl << this->info() << endl; } readIfPresent(); } template class PatchField, class GeoMesh> Foam::GeometricField::GeometricField ( const IOobject& io, const Mesh& mesh ) : DimensionedField(io, mesh, dimless, false), timeIndex_(this->time().timeIndex()), field0Ptr_(NULL), fieldPrevIterPtr_(NULL), boundaryField_(*this, readField(this->readStream(typeName))) { this->close(); // Check compatibility between field and mesh if (this->size() != GeoMesh::size(this->mesh())) { FatalIOErrorIn ( "GeometricField::GeometricField" "(const IOobject&, const Mesh&)", this->readStream(typeName) ) << " number of field elements = " << this->size() << " number of mesh elements = " << GeoMesh::size(this->mesh()) << exit(FatalIOError); } readOldTimeIfPresent(); if (debug) { Info<< "Finishing read-construct of " "GeometricField" << endl << this->info() << endl; } } template class PatchField, class GeoMesh> Foam::GeometricField::GeometricField ( const IOobject& io, const Mesh& mesh, Istream& is ) : DimensionedField(io, mesh, dimless, false), timeIndex_(this->time().timeIndex()), field0Ptr_(NULL), fieldPrevIterPtr_(NULL), boundaryField_(*this, readField(is)) { // Check compatibility between field and mesh if (this->size() != GeoMesh::size(this->mesh())) { FatalIOErrorIn ( "GeometricField::GeometricField" "(const IOobject&, const Mesh&, Istream&)", is ) << " number of field elements = " << this->size() << " number of mesh elements = " << GeoMesh::size(this->mesh()) << exit(FatalIOError); } readOldTimeIfPresent(); if (debug) { Info<< "Finishing read-construct of " "GeometricField" << endl << this->info() << endl; } } template class PatchField, class GeoMesh> Foam::GeometricField::GeometricField ( const IOobject& io, const Mesh& mesh, const dictionary& dict ) : DimensionedField(io, mesh, dimless, false), timeIndex_(this->time().timeIndex()), field0Ptr_(NULL), fieldPrevIterPtr_(NULL), boundaryField_(*this, readField(dict)) { // Check compatibility between field and mesh if (this->size() != GeoMesh::size(this->mesh())) { FatalErrorIn ( "GeometricField::GeometricField" "(const IOobject&, const Mesh&, const dictionary&)" ) << " number of field elements = " << this->size() << " number of mesh elements = " << GeoMesh::size(this->mesh()) << exit(FatalIOError); } readOldTimeIfPresent(); if (debug) { Info<< "Finishing dictionary-construct of " "GeometricField" << endl << this->info() << endl; } } // construct as copy template class PatchField, class GeoMesh> Foam::GeometricField::GeometricField ( const GeometricField& gf ) : DimensionedField(gf), timeIndex_(gf.timeIndex()), field0Ptr_(NULL), fieldPrevIterPtr_(NULL), boundaryField_(*this, gf.boundaryField_) { if (debug) { Info<< "GeometricField::GeometricField : " "constructing as copy" << endl << this->info() << endl; } if (gf.field0Ptr_) { field0Ptr_ = new GeometricField ( *gf.field0Ptr_ ); } this->writeOpt() = IOobject::NO_WRITE; } // construct as copy of tmp deleting argument #ifdef ConstructFromTmp template class PatchField, class GeoMesh> Foam::GeometricField::GeometricField ( const tmp >& tgf ) : DimensionedField ( const_cast&>(tgf()), tgf.isTmp() ), timeIndex_(tgf().timeIndex()), field0Ptr_(NULL), fieldPrevIterPtr_(NULL), boundaryField_(*this, tgf().boundaryField_) { if (debug) { Info<< "GeometricField::GeometricField : " "constructing as copy" << endl << this->info() << endl; } this->writeOpt() = IOobject::NO_WRITE; tgf.clear(); } #endif // construct as copy resetting IO parameters template class PatchField, class GeoMesh> Foam::GeometricField::GeometricField ( const IOobject& io, const GeometricField& gf ) : DimensionedField(io, gf), timeIndex_(gf.timeIndex()), field0Ptr_(NULL), fieldPrevIterPtr_(NULL), boundaryField_(*this, gf.boundaryField_) { if (debug) { Info<< "GeometricField::GeometricField : " "constructing as copy resetting IO params" << endl << this->info() << endl; } if (!readIfPresent() && gf.field0Ptr_) { field0Ptr_ = new GeometricField ( io.name() + "_0", *gf.field0Ptr_ ); } } // construct as copy resetting name template class PatchField, class GeoMesh> Foam::GeometricField::GeometricField ( const word& newName, const GeometricField& gf ) : DimensionedField(newName, gf), timeIndex_(gf.timeIndex()), field0Ptr_(NULL), fieldPrevIterPtr_(NULL), boundaryField_(*this, gf.boundaryField_) { if (debug) { Info<< "GeometricField::GeometricField : " "constructing as copy resetting name" << endl << this->info() << endl; } if (!readIfPresent() && gf.field0Ptr_) { field0Ptr_ = new GeometricField ( newName + "_0", *gf.field0Ptr_ ); } } // construct as copy resetting name #ifdef ConstructFromTmp template class PatchField, class GeoMesh> Foam::GeometricField::GeometricField ( const word& newName, const tmp >& tgf ) : DimensionedField ( newName, const_cast&>(tgf()), tgf.isTmp() ), timeIndex_(tgf().timeIndex()), field0Ptr_(NULL), fieldPrevIterPtr_(NULL), boundaryField_(*this, tgf().boundaryField_) { if (debug) { Info<< "GeometricField::GeometricField : " "constructing from tmp resetting name" << endl << this->info() << endl; } tgf.clear(); } #endif // construct as copy resetting IO parameters and patch type template class PatchField, class GeoMesh> Foam::GeometricField::GeometricField ( const IOobject& io, const GeometricField& gf, const word& patchFieldType ) : DimensionedField(io, gf), timeIndex_(gf.timeIndex()), field0Ptr_(NULL), fieldPrevIterPtr_(NULL), boundaryField_(this->mesh().boundary(), *this, patchFieldType) { if (debug) { Info<< "GeometricField::GeometricField : " "constructing as copy resetting IO params" << endl << this->info() << endl; } boundaryField_ == gf.boundaryField_; if (!readIfPresent() && gf.field0Ptr_) { field0Ptr_ = new GeometricField ( io.name() + "_0", *gf.field0Ptr_ ); } } // construct as copy resetting IO parameters and boundary types template class PatchField, class GeoMesh> Foam::GeometricField::GeometricField ( const IOobject& io, const GeometricField& gf, const wordList& patchFieldTypes, const wordList& actualPatchTypes ) : DimensionedField(io, gf), timeIndex_(gf.timeIndex()), field0Ptr_(NULL), fieldPrevIterPtr_(NULL), boundaryField_ ( this->mesh().boundary(), *this, patchFieldTypes, actualPatchTypes ) { if (debug) { Info<< "GeometricField::GeometricField : " "constructing as copy resetting IO params" << endl << this->info() << endl; } boundaryField_ == gf.boundaryField_; if (!readIfPresent() && gf.field0Ptr_) { field0Ptr_ = new GeometricField ( io.name() + "_0", *gf.field0Ptr_ ); } } // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * * // template class PatchField, class GeoMesh> Foam::GeometricField::~GeometricField() { deleteDemandDrivenData(field0Ptr_); deleteDemandDrivenData(fieldPrevIterPtr_); } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template class PatchField, class GeoMesh> typename Foam::GeometricField::DimensionedInternalField& Foam::GeometricField::dimensionedInternalField() { this->setUpToDate(); storeOldTimes(); return *this; } template class PatchField, class GeoMesh> typename Foam::GeometricField::InternalField& Foam::GeometricField::internalField() { this->setUpToDate(); storeOldTimes(); return *this; } // Return reference to GeometricBoundaryField template class PatchField, class GeoMesh> typename Foam::GeometricField::GeometricBoundaryField& Foam::GeometricField::boundaryField() { this->setUpToDate(); storeOldTimes(); return boundaryField_; } // Store old-time field template class PatchField, class GeoMesh> void Foam::GeometricField::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(); } // Store old-time field template class PatchField, class GeoMesh> void Foam::GeometricField::storeOldTime() const { if (field0Ptr_) { field0Ptr_->storeOldTime(); if (debug) { Info<< "Storing old time field for field" << endl << this->info() << endl; } *field0Ptr_ == *this; field0Ptr_->timeIndex_ = timeIndex_; if (field0Ptr_->field0Ptr_) { field0Ptr_->writeOpt() = this->writeOpt(); } } } // Return the number of old time fields stored template class PatchField, class GeoMesh> Foam::label Foam::GeometricField::nOldTimes() const { if (field0Ptr_) { return field0Ptr_->nOldTimes() + 1; } else { return 0; } } // Return old time internal field template class PatchField, class GeoMesh> const Foam::GeometricField& Foam::GeometricField::oldTime() const { if (!field0Ptr_) { field0Ptr_ = new GeometricField ( IOobject ( this->name() + "_0", this->time().timeName(), this->db() ), *this ); } else { storeOldTimes(); } return *field0Ptr_; } // Return old time internal field template class PatchField, class GeoMesh> Foam::GeometricField& Foam::GeometricField::oldTime() { static_cast&>(*this) .oldTime(); return *field0Ptr_; } // Store previous iteration field template class PatchField, class GeoMesh> void Foam::GeometricField::storePrevIter() const { if (!fieldPrevIterPtr_) { if (debug) { Info<< "Allocating previous iteration field" << endl << this->info() << endl; } fieldPrevIterPtr_ = new GeometricField ( this->name() + "PrevIter", *this ); } else { *fieldPrevIterPtr_ == *this; } } // Return previous iteration field template class PatchField, class GeoMesh> const Foam::GeometricField& Foam::GeometricField::prevIter() const { if (!fieldPrevIterPtr_) { FatalErrorIn ( "GeometricField::prevIter() const" ) << "previous iteration field" << endl << this->info() << endl << " not stored." << " Use field.storePrevIter() at start of iteration." << abort(FatalError); } return *fieldPrevIterPtr_; } // Correct the boundary conditions template class PatchField, class GeoMesh> void Foam::GeometricField:: correctBoundaryConditions() { this->setUpToDate(); storeOldTimes(); boundaryField_.evaluate(); } // Does the field need a reference level for solution template class PatchField, class GeoMesh> bool Foam::GeometricField::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()); return needRef; } template class PatchField, class GeoMesh> void Foam::GeometricField::relax(const scalar alpha) { if (debug) { InfoIn ( "GeometricField::relax" "(const scalar alpha)" ) << "Relaxing" << endl << this->info() << " by " << alpha << endl; } operator==(prevIter() + alpha*(*this - prevIter())); } template class PatchField, class GeoMesh> void Foam::GeometricField::relax() { word name = this->name(); if (this->mesh().data::lookupOrDefault("finalIteration", false)) { name += "Final"; } if (this->mesh().relax(name)) { relax(this->mesh().relaxationFactor(name)); } } template class PatchField, class GeoMesh> Foam::word Foam::GeometricField::select ( bool final ) const { if (final) { return this->name() + "Final"; } else { return this->name(); } } // writeData member function required by regIOobject template class PatchField, class GeoMesh> bool Foam::GeometricField:: writeData(Ostream& os) const { os << *this; return os.good(); } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template class PatchField, class GeoMesh> Foam::tmp > Foam::GeometricField::T() const { tmp > result ( new GeometricField ( IOobject ( this->name() + ".T()", this->instance(), this->db() ), this->mesh(), this->dimensions() ) ); Foam::T(result().internalField(), internalField()); Foam::T(result().boundaryField(), boundaryField()); return result; } template class PatchField, class GeoMesh> Foam::tmp < Foam::GeometricField < typename Foam::GeometricField::cmptType, PatchField, GeoMesh > > Foam::GeometricField::component ( const direction d ) const { tmp > Component ( new GeometricField ( IOobject ( this->name() + ".component(" + Foam::name(d) + ')', this->instance(), this->db() ), this->mesh(), this->dimensions() ) ); Foam::component(Component().internalField(), internalField(), d); Foam::component(Component().boundaryField(), boundaryField(), d); return Component; } template class PatchField, class GeoMesh> void Foam::GeometricField::replace ( const direction d, const GeometricField < typename GeometricField::cmptType, PatchField, GeoMesh >& gcf ) { internalField().replace(d, gcf.internalField()); boundaryField().replace(d, gcf.boundaryField()); } template class PatchField, class GeoMesh> void Foam::GeometricField::replace ( const direction d, const dimensioned& ds ) { internalField().replace(d, ds.value()); boundaryField().replace(d, ds.value()); } template class PatchField, class GeoMesh> void Foam::GeometricField::max ( const dimensioned& dt ) { Foam::max(internalField(), internalField(), dt.value()); Foam::max(boundaryField(), boundaryField(), dt.value()); } template class PatchField, class GeoMesh> void Foam::GeometricField::min ( const dimensioned& dt ) { Foam::min(internalField(), internalField(), dt.value()); Foam::min(boundaryField(), boundaryField(), dt.value()); } template class PatchField, class GeoMesh> void Foam::GeometricField::negate() { internalField().negate(); boundaryField().negate(); } // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template class PatchField, class GeoMesh> void Foam::GeometricField::operator= ( const GeometricField& gf ) { if (this == &gf) { FatalErrorIn ( "GeometricField::operator=" "(const GeometricField&)" ) << "attempted assignment to self" << abort(FatalError); } checkField(*this, gf, "="); // only equate field contents not ID dimensionedInternalField() = gf.dimensionedInternalField(); boundaryField() = gf.boundaryField(); } template class PatchField, class GeoMesh> void Foam::GeometricField::operator= ( const tmp >& tgf ) { if (this == &(tgf())) { FatalErrorIn ( "GeometricField::operator=" "(const tmp >&)" ) << "attempted assignment to self" << abort(FatalError); } const GeometricField& gf = tgf(); checkField(*this, gf, "="); // only equate field contents not ID this->dimensions() = gf.dimensions(); // This is dodgy stuff, don't try it at home. internalField().transfer ( const_cast&>(gf.internalField()) ); boundaryField() = gf.boundaryField(); tgf.clear(); } template class PatchField, class GeoMesh> void Foam::GeometricField::operator= ( const dimensioned& dt ) { dimensionedInternalField() = dt; boundaryField() = dt.value(); } template class PatchField, class GeoMesh> void Foam::GeometricField::operator== ( const tmp >& tgf ) { const GeometricField& gf = tgf(); checkField(*this, gf, "=="); // only equate field contents not ID dimensionedInternalField() = gf.dimensionedInternalField(); boundaryField() == gf.boundaryField(); tgf.clear(); } template class PatchField, class GeoMesh> void Foam::GeometricField::operator== ( const dimensioned& dt ) { dimensionedInternalField() = dt; boundaryField() == dt.value(); } #define COMPUTED_ASSIGNMENT(TYPE, op) \ \ template class PatchField, class GeoMesh> \ void Foam::GeometricField::operator op \ ( \ const GeometricField& gf \ ) \ { \ checkField(*this, gf, #op); \ \ dimensionedInternalField() op gf.dimensionedInternalField(); \ boundaryField() op gf.boundaryField(); \ } \ \ template class PatchField, class GeoMesh> \ void Foam::GeometricField::operator op \ ( \ const tmp >& tgf \ ) \ { \ operator op(tgf()); \ tgf.clear(); \ } \ \ template class PatchField, class GeoMesh> \ void Foam::GeometricField::operator op \ ( \ const dimensioned& dt \ ) \ { \ dimensionedInternalField() op dt; \ boundaryField() op dt.value(); \ } COMPUTED_ASSIGNMENT(Type, +=) COMPUTED_ASSIGNMENT(Type, -=) COMPUTED_ASSIGNMENT(scalar, *=) COMPUTED_ASSIGNMENT(scalar, /=) #undef COMPUTED_ASSIGNMENT // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // template class PatchField, class GeoMesh> Foam::Ostream& Foam::operator<< ( Ostream& os, const GeometricField& gf ) { gf.dimensionedInternalField().writeData(os, "internalField"); os << nl; gf.boundaryField().writeEntry("boundaryField", os); // Check state of IOstream os.check ( "Ostream& operator<<(Ostream&, " "const GeometricField&)" ); return (os); } template class PatchField, class GeoMesh> Foam::Ostream& Foam::operator<< ( Ostream& os, const tmp >& tgf ) { os << tgf(); tgf.clear(); return os; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #undef checkField // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #include "GeometricBoundaryField.C" #include "GeometricFieldFunctions.C" // ************************************************************************* //