/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2017 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 "emptyPolyPatch.H" #include "commSchedule.H" #include "globalMeshData.H" #include "cyclicPolyPatch.H" template class PatchField, class GeoMesh> void Foam::GeometricField::Boundary:: readField ( const DimensionedField& field, const dictionary& dict ) { // Clear the boundary field if already initialised this->clear(); this->setSize(bmesh_.size()); if (debug) { InfoInFunction << endl; } label nUnset = this->size(); // 1. Handle explicit patch names. Note that there can be only one explicit // patch name since is key of dictionary. forAllConstIter(dictionary, dict, iter) { if (iter().isDict() && !iter().keyword().isPattern()) { label patchi = bmesh_.findPatchID(iter().keyword()); if (patchi != -1) { this->set ( patchi, PatchField::New ( bmesh_[patchi], field, iter().dict() ) ); nUnset--; } } } if (nUnset == 0) { return; } // 2. Patch-groups. (using non-wild card entries of dictionaries) // (patchnames already matched above) // Note: in reverse order of entries in the dictionary (last // patchGroups wins). This is so is consistent with dictionary wildcard // behaviour if (dict.size()) { for ( IDLList::const_reverse_iterator iter = dict.rbegin(); iter != dict.rend(); ++iter ) { const entry& e = iter(); if (e.isDict() && !e.keyword().isPattern()) { const labelList patchIDs = bmesh_.findIndices ( e.keyword(), true // use patchGroups ); forAll(patchIDs, i) { label patchi = patchIDs[i]; if (!this->set(patchi)) { this->set ( patchi, PatchField::New ( bmesh_[patchi], field, e.dict() ) ); } } } } } // 3. Wildcard patch overrides forAll(bmesh_, patchi) { if (!this->set(patchi)) { if (bmesh_[patchi].type() == emptyPolyPatch::typeName) { this->set ( patchi, PatchField::New ( emptyPolyPatch::typeName, bmesh_[patchi], field ) ); } else { bool found = dict.found(bmesh_[patchi].name()); if (found) { this->set ( patchi, PatchField::New ( bmesh_[patchi], field, dict.subDict(bmesh_[patchi].name()) ) ); } } } } // Check for any unset patches forAll(bmesh_, patchi) { if (!this->set(patchi)) { if (bmesh_[patchi].type() == cyclicPolyPatch::typeName) { FatalIOErrorInFunction ( dict ) << "Cannot find patchField entry for cyclic " << bmesh_[patchi].name() << endl << "Is your field uptodate with split cyclics?" << endl << "Run foamUpgradeCyclics to convert mesh and fields" << " to split cyclics." << exit(FatalIOError); } else { FatalIOErrorInFunction ( dict ) << "Cannot find patchField entry for " << bmesh_[patchi].name() << exit(FatalIOError); } } } } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template class PatchField, class GeoMesh> Foam::GeometricField::Boundary:: Boundary ( const BoundaryMesh& bmesh ) : FieldField(bmesh.size()), bmesh_(bmesh) {} template class PatchField, class GeoMesh> Foam::GeometricField::Boundary:: Boundary ( const BoundaryMesh& bmesh, const DimensionedField& field, const word& patchFieldType ) : FieldField(bmesh.size()), bmesh_(bmesh) { if (debug) { InfoInFunction << endl; } forAll(bmesh_, patchi) { this->set ( patchi, PatchField::New ( patchFieldType, bmesh_[patchi], field ) ); } } template class PatchField, class GeoMesh> Foam::GeometricField::Boundary:: Boundary ( const BoundaryMesh& bmesh, const DimensionedField& field, const wordList& patchFieldTypes, const wordList& constraintTypes ) : FieldField(bmesh.size()), bmesh_(bmesh) { if (debug) { InfoInFunction << endl; } if ( patchFieldTypes.size() != this->size() || (constraintTypes.size() && (constraintTypes.size() != this->size())) ) { FatalErrorInFunction << "Incorrect number of patch type specifications given" << nl << " Number of patches in mesh = " << bmesh.size() << " number of patch type specifications = " << patchFieldTypes.size() << abort(FatalError); } if (constraintTypes.size()) { forAll(bmesh_, patchi) { this->set ( patchi, PatchField::New ( patchFieldTypes[patchi], constraintTypes[patchi], bmesh_[patchi], field ) ); } } else { forAll(bmesh_, patchi) { this->set ( patchi, PatchField::New ( patchFieldTypes[patchi], bmesh_[patchi], field ) ); } } } template class PatchField, class GeoMesh> Foam::GeometricField::Boundary:: Boundary ( const BoundaryMesh& bmesh, const DimensionedField& field, const PtrList>& ptfl ) : FieldField(bmesh.size()), bmesh_(bmesh) { if (debug) { InfoInFunction << endl; } forAll(bmesh_, patchi) { this->set(patchi, ptfl[patchi].clone(field)); } } template class PatchField, class GeoMesh> Foam::GeometricField::Boundary:: Boundary ( const DimensionedField& field, const typename GeometricField:: Boundary& btf ) : FieldField(btf.size()), bmesh_(btf.bmesh_) { if (debug) { InfoInFunction << endl; } forAll(bmesh_, patchi) { this->set(patchi, btf[patchi].clone(field)); } } template class PatchField, class GeoMesh> Foam::GeometricField::Boundary:: Boundary ( const typename GeometricField:: Boundary& btf ) : FieldField(btf), bmesh_(btf.bmesh_) { if (debug) { InfoInFunction << endl; } } template class PatchField, class GeoMesh> Foam::GeometricField::Boundary:: Boundary ( const BoundaryMesh& bmesh, const DimensionedField& field, const dictionary& dict ) : FieldField(bmesh.size()), bmesh_(bmesh) { readField(field, dict); } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template class PatchField, class GeoMesh> void Foam::GeometricField::Boundary:: updateCoeffs() { if (debug) { InfoInFunction << endl; } forAll(*this, patchi) { this->operator[](patchi).updateCoeffs(); } } template class PatchField, class GeoMesh> void Foam::GeometricField::Boundary:: evaluate() { if (debug) { InfoInFunction << endl; } if ( Pstream::defaultCommsType == Pstream::commsTypes::blocking || Pstream::defaultCommsType == Pstream::commsTypes::nonBlocking ) { label nReq = Pstream::nRequests(); forAll(*this, patchi) { this->operator[](patchi).initEvaluate(Pstream::defaultCommsType); } // Block for any outstanding requests if ( Pstream::parRun() && Pstream::defaultCommsType == Pstream::commsTypes::nonBlocking ) { Pstream::waitRequests(nReq); } forAll(*this, patchi) { this->operator[](patchi).evaluate(Pstream::defaultCommsType); } } else if (Pstream::defaultCommsType == Pstream::commsTypes::scheduled) { const lduSchedule& patchSchedule = bmesh_.mesh().globalData().patchSchedule(); forAll(patchSchedule, patchEvali) { if (patchSchedule[patchEvali].init) { this->operator[](patchSchedule[patchEvali].patch) .initEvaluate(Pstream::commsTypes::scheduled); } else { this->operator[](patchSchedule[patchEvali].patch) .evaluate(Pstream::commsTypes::scheduled); } } } else { FatalErrorInFunction << "Unsuported communications type " << Pstream::commsTypeNames[Pstream::defaultCommsType] << exit(FatalError); } } template class PatchField, class GeoMesh> Foam::wordList Foam::GeometricField::Boundary:: types() const { const FieldField& pff = *this; wordList Types(pff.size()); forAll(pff, patchi) { Types[patchi] = pff[patchi].type(); } return Types; } template class PatchField, class GeoMesh> typename Foam::GeometricField::Boundary Foam::GeometricField::Boundary:: boundaryInternalField() const { typename GeometricField::Boundary BoundaryInternalField(*this); forAll(BoundaryInternalField, patchi) { BoundaryInternalField[patchi] == this->operator[](patchi).patchInternalField(); } return BoundaryInternalField; } template class PatchField, class GeoMesh> Foam::LduInterfaceFieldPtrsList Foam::GeometricField::Boundary:: interfaces() const { LduInterfaceFieldPtrsList interfaces(this->size()); forAll(interfaces, patchi) { if (isA>(this->operator[](patchi))) { interfaces.set ( patchi, &refCast> ( this->operator[](patchi) ) ); } } return interfaces; } template class PatchField, class GeoMesh> Foam::lduInterfaceFieldPtrsList Foam::GeometricField::Boundary:: scalarInterfaces() const { lduInterfaceFieldPtrsList interfaces(this->size()); forAll(interfaces, patchi) { if (isA(this->operator[](patchi))) { interfaces.set ( patchi, &refCast ( this->operator[](patchi) ) ); } } return interfaces; } template class PatchField, class GeoMesh> void Foam::GeometricField::Boundary:: writeEntry(const word& keyword, Ostream& os) const { os << keyword << nl << token::BEGIN_BLOCK << incrIndent << nl; forAll(*this, patchi) { os << indent << this->operator[](patchi).patch().name() << nl << indent << token::BEGIN_BLOCK << nl << incrIndent << this->operator[](patchi) << decrIndent << indent << token::END_BLOCK << endl; } os << decrIndent << token::END_BLOCK << endl; // Check state of IOstream os.check ( "GeometricField::Boundary::" "writeEntry(const word& keyword, Ostream& os) const" ); } // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template class PatchField, class GeoMesh> void Foam::GeometricField::Boundary:: operator= ( const typename GeometricField:: Boundary& bf ) { FieldField::operator=(bf); } template class PatchField, class GeoMesh> void Foam::GeometricField::Boundary:: operator= ( const FieldField& ptff ) { FieldField::operator=(ptff); } template class PatchField, class GeoMesh> void Foam::GeometricField::Boundary:: operator= ( const Type& t ) { FieldField::operator=(t); } template class PatchField, class GeoMesh> void Foam::GeometricField::Boundary:: operator== ( const typename GeometricField:: Boundary& bf ) { forAll((*this), patchi) { this->operator[](patchi) == bf[patchi]; } } template class PatchField, class GeoMesh> void Foam::GeometricField::Boundary:: operator== ( const FieldField& ptff ) { forAll((*this), patchi) { this->operator[](patchi) == ptff[patchi]; } } template class PatchField, class GeoMesh> void Foam::GeometricField::Boundary:: operator== ( const Type& t ) { forAll((*this), patchi) { this->operator[](patchi) == t; } } // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * // template class PatchField, class GeoMesh> Foam::Ostream& Foam::operator<< ( Ostream& os, const typename GeometricField:: Boundary& bf ) { os << static_cast&>(bf); return os; } // ************************************************************************* //