/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2019-2023 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 "processorCyclicPolyPatch.H" #include "addToRunTimeSelectionTable.H" #include "SubField.H" #include "cyclicPolyPatch.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { defineTypeNameAndDebug(processorCyclicPolyPatch, 0); addToRunTimeSelectionTable(polyPatch, processorCyclicPolyPatch, dictionary); } // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // Foam::word Foam::processorCyclicPolyPatch::newName ( const word& cyclicPolyPatchName, const label myProcNo, const label neighbProcNo ) { return word ( processorPolyPatch::newName(myProcNo, neighbProcNo) + "through" + cyclicPolyPatchName ); } Foam::labelList Foam::processorCyclicPolyPatch::patchIDs ( const word& cyclicPolyPatchName, const polyBoundaryMesh& bm ) { return bm.indices ( wordRe ( "procBoundary.*to.*through" + cyclicPolyPatchName, wordRe::REGEX ) ); } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::processorCyclicPolyPatch::processorCyclicPolyPatch ( const label size, const label start, const label index, const polyBoundaryMesh& bm, const int myProcNo, const int neighbProcNo, const word& referPatchName, const transformType transform, const word& patchType ) : processorPolyPatch ( newName(referPatchName, myProcNo, neighbProcNo), size, start, index, bm, myProcNo, neighbProcNo, transform, patchType ), referPatchName_(referPatchName), tag_(-1), referPatchID_(-1) {} Foam::processorCyclicPolyPatch::processorCyclicPolyPatch ( const word& name, const dictionary& dict, const label index, const polyBoundaryMesh& bm, const word& patchType ) : processorPolyPatch(name, dict, index, bm, patchType), referPatchName_(dict.lookup("referPatch")), tag_(dict.getOrDefault("tag", -1)), referPatchID_(-1) {} Foam::processorCyclicPolyPatch::processorCyclicPolyPatch ( const processorCyclicPolyPatch& pp, const polyBoundaryMesh& bm ) : processorPolyPatch(pp, bm), referPatchName_(pp.referPatchName()), tag_(pp.tag()), referPatchID_(-1) {} Foam::processorCyclicPolyPatch::processorCyclicPolyPatch ( const processorCyclicPolyPatch& pp, const polyBoundaryMesh& bm, const label index, const label newSize, const label newStart ) : processorPolyPatch(pp, bm, index, newSize, newStart), referPatchName_(pp.referPatchName_), tag_(pp.tag()), referPatchID_(-1) {} Foam::processorCyclicPolyPatch::processorCyclicPolyPatch ( const processorCyclicPolyPatch& pp, const polyBoundaryMesh& bm, const label index, const label newSize, const label newStart, const word& referPatchName ) : processorPolyPatch(pp, bm, index, newSize, newStart), referPatchName_(referPatchName), tag_(-1), referPatchID_(-1) {} Foam::processorCyclicPolyPatch::processorCyclicPolyPatch ( const processorCyclicPolyPatch& pp, const polyBoundaryMesh& bm, const label index, const labelUList& mapAddressing, const label newStart ) : processorPolyPatch(pp, bm, index, mapAddressing, newStart), referPatchName_(pp.referPatchName()), tag_(-1), referPatchID_(-1) {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // Foam::label Foam::processorCyclicPolyPatch::referPatchID() const { if (referPatchID_ == -1) { referPatchID_ = this->boundaryMesh().findPatchID ( referPatchName_ ); if (referPatchID_ == -1) { FatalErrorInFunction << "Illegal referPatch name " << referPatchName_ << nl << "Valid patch names: " << this->boundaryMesh().names() << nl << exit(FatalError); } } return referPatchID_; } int Foam::processorCyclicPolyPatch::tag() const { if (tag_ == -1) { // Get unique tag to use for all comms. Make sure that both sides // use the same tag const cyclicPolyPatch& cycPatch = refCast ( referPatch() ); if (owner()) { tag_ = string::hasher()(cycPatch.name()) % 32768u; } else { tag_ = string::hasher()(cycPatch.neighbPatch().name()) % 32768u; } if (tag_ == UPstream::msgType() || tag_ == -1) { FatalErrorInFunction << "Tag calculated from cyclic patch name " << tag_ << " is the same as the current message type " << UPstream::msgType() << " or -1" << nl << "Please set a non-conflicting, unique, tag by hand" << " using the 'tag' entry" << exit(FatalError); } if (debug) { Pout<< "processorCyclicPolyPatch " << name() << " uses tag " << tag_ << endl; } } return tag_; } void Foam::processorCyclicPolyPatch::initGeometry(PstreamBuffers& pBufs) { // Send over processorPolyPatch data processorPolyPatch::initGeometry(pBufs); } void Foam::processorCyclicPolyPatch::calcGeometry(PstreamBuffers& pBufs) { // Receive and initialise processorPolyPatch data processorPolyPatch::calcGeometry(pBufs); if (UPstream::parRun()) { // Where do we store the calculated transformation? // - on the processor patch? // - on the underlying cyclic patch? // - or do we not auto-calculate the transformation but // have option of reading it. // Update underlying cyclic halves. Need to do both since only one // half might be present as a processorCyclic. coupledPolyPatch& pp = const_cast(referPatch()); pp.calcGeometry ( *this, faceCentres(), faceAreas(), faceCellCentres(), neighbFaceCentres(), neighbFaceAreas(), neighbFaceCellCentres() ); if (isA(pp)) { const cyclicPolyPatch& cpp = refCast(pp); const_cast(cpp.neighbPatch()).calcGeometry ( *this, neighbFaceCentres(), neighbFaceAreas(), neighbFaceCellCentres(), faceCentres(), faceAreas(), faceCellCentres() ); } } } void Foam::processorCyclicPolyPatch::initMovePoints ( PstreamBuffers& pBufs, const pointField& p ) { // Recalculate geometry initGeometry(pBufs); } void Foam::processorCyclicPolyPatch::movePoints ( PstreamBuffers& pBufs, const pointField& ) { calcGeometry(pBufs); } void Foam::processorCyclicPolyPatch::initUpdateMesh(PstreamBuffers& pBufs) { processorPolyPatch::initUpdateMesh(pBufs); } void Foam::processorCyclicPolyPatch::updateMesh(PstreamBuffers& pBufs) { referPatchID_ = -1; processorPolyPatch::updateMesh(pBufs); } void Foam::processorCyclicPolyPatch::initOrder ( PstreamBuffers& pBufs, const primitivePatch& pp ) const { // Send the patch points and faces across. Note that this is exactly the // same as the processorPolyPatch::initOrder in COINCIDENTFULLMATCH // mode. UOPstream toNeighbour(neighbProcNo(), pBufs); toNeighbour << pp.localPoints() << pp.localFaces(); } bool Foam::processorCyclicPolyPatch::order ( PstreamBuffers& pBufs, const primitivePatch& pp, labelList& faceMap, labelList& rotation ) const { // Receive the remote patch vectorField masterPts; faceList masterFaces; autoPtr masterPtr; { UIPstream fromNeighbour(neighbProcNo(), pBufs); fromNeighbour >> masterPts >> masterFaces; masterPtr.reset ( new primitivePatch(SubList(masterFaces), masterPts) ); } const cyclicPolyPatch& cycPatch = refCast(referPatch()); // (ab)use the cyclicPolyPatch ordering: // - owner side stores geometry // - neighbour side does ordering according to owner side cycPatch.neighbPatch().initOrder(pBufs, masterPtr()); return cycPatch.order(pBufs, pp, faceMap, rotation); } void Foam::processorCyclicPolyPatch::write(Ostream& os) const { processorPolyPatch::write(os); os.writeEntry("referPatch", referPatchName_); os.writeEntryIfDifferent