diff --git a/src/OpenFOAM/global/argList/argList.C b/src/OpenFOAM/global/argList/argList.C index fa2b1a57af0c5be246ec8ab7036421d538915378..16f6157a227fc12ecd16473a271184d1cb49e2e5 100644 --- a/src/OpenFOAM/global/argList/argList.C +++ b/src/OpenFOAM/global/argList/argList.C @@ -775,7 +775,7 @@ Foam::argList::argList << " floatTransfer : " << Pstream::floatTransfer << nl << " nProcsSimpleSum : " << Pstream::nProcsSimpleSum << nl << " commsType : " - << Pstream::commsTypeNames[Pstream::defaultCommsType] + << Pstream::commsTypeNames[Pstream::defaultCommsType] << nl << " polling iterations : " << Pstream::nPollProcInterfaces << endl; } diff --git a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/lduInterfaceField/lduInterfaceField.H b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/lduInterfaceField/lduInterfaceField.H index 6da295382602eb93972cba22791f5b69e56d3fcc..b8180a2b3ec086d043fc52e4c1d590f5bbd0ef87 100644 --- a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/lduInterfaceField/lduInterfaceField.H +++ b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/lduInterfaceField/lduInterfaceField.H @@ -60,6 +60,11 @@ class lduInterfaceField //- Reference to the coupled patch this field is defined for const lduInterface& interface_; + //- Update index used so that updateInterfaceMatrix is called only once + // during the construction of the matrix + bool updatedMatrix_; + + // Private Member Functions //- Disallow default bitwise copy construct @@ -68,12 +73,6 @@ class lduInterfaceField //- Disallow default bitwise assignment void operator=(const lduInterfaceField&); -protected: - - //- Update index used so that updateInterfaceMatrix is called only once - // during the construction of the matrix - bool updatedMatrix_; - public: //- Runtime type information diff --git a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixOperations.C b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixOperations.C index 45654d9731abed335b0b8bd7eb3da6bfda55b963..07260b4a91009fdbdc7265ab6ad6765f75183c40 100644 --- a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixOperations.C +++ b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixOperations.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -205,7 +205,15 @@ void Foam::lduMatrix::operator+=(const lduMatrix& A) if (debug > 1) { WarningIn("lduMatrix::operator+=(const lduMatrix& A)") - << "Unknown matrix type combination" + << "Unknown matrix type combination" << nl + << " this :" + << " diagonal:" << diagonal() + << " symmetric:" << symmetric() + << " asymmetric:" << asymmetric() << nl + << " A :" + << " diagonal:" << A.diagonal() + << " symmetric:" << A.symmetric() + << " asymmetric:" << A.asymmetric() << endl; } } @@ -276,7 +284,15 @@ void Foam::lduMatrix::operator-=(const lduMatrix& A) if (debug > 1) { WarningIn("lduMatrix::operator-=(const lduMatrix& A)") - << "Unknown matrix type combination" + << "Unknown matrix type combination" << nl + << " this :" + << " diagonal:" << diagonal() + << " symmetric:" << symmetric() + << " asymmetric:" << asymmetric() << nl + << " A :" + << " diagonal:" << A.diagonal() + << " symmetric:" << A.symmetric() + << " asymmetric:" << A.asymmetric() << endl; } } diff --git a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixUpdateMatrixInterfaces.C b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixUpdateMatrixInterfaces.C index c401c3e47764068938556e15bc3762e6cfa900e0..62d00b7626c7c04929f6f69bc18e6562e92dea0f 100644 --- a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixUpdateMatrixInterfaces.C +++ b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixUpdateMatrixInterfaces.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -87,7 +87,7 @@ void Foam::lduMatrix::initMatrixInterfaces } else { - FatalErrorIn("lduMatrix::initMatrixInterfaces") + FatalErrorIn("lduMatrix::initMatrixInterfaces(..)") << "Unsuported communications type " << Pstream::commsTypeNames[Pstream::defaultCommsType] << exit(FatalError); @@ -104,25 +104,92 @@ void Foam::lduMatrix::updateMatrixInterfaces const direction cmpt ) const { - if - ( - Pstream::defaultCommsType == Pstream::blocking - || Pstream::defaultCommsType == Pstream::nonBlocking - ) + if (Pstream::defaultCommsType == Pstream::blocking) { - // Block until all sends/receives have been finished - if - ( - Pstream::parRun() - && Pstream::defaultCommsType == Pstream::nonBlocking - ) + forAll(interfaces, interfaceI) { - UPstream::waitRequests(); + if (interfaces.set(interfaceI)) + { + interfaces[interfaceI].updateInterfaceMatrix + ( + psiif, + result, + *this, + coupleCoeffs[interfaceI], + cmpt, + Pstream::defaultCommsType + ); + } + } + } + else if (Pstream::defaultCommsType == Pstream::nonBlocking) + { + // Try and consume interfaces as they become available + bool allUpdated = false; + + for (label i = 0; i < UPstream::nPollProcInterfaces; i++) + { + allUpdated = true; + + forAll(interfaces, interfaceI) + { + if (interfaces.set(interfaceI)) + { + if (!interfaces[interfaceI].updatedMatrix()) + { + if (interfaces[interfaceI].ready()) + { + interfaces[interfaceI].updateInterfaceMatrix + ( + psiif, + result, + *this, + coupleCoeffs[interfaceI], + cmpt, + Pstream::defaultCommsType + ); + } + else + { + allUpdated = false; + } + } + } + } + + if (allUpdated) + { + break; + } + } + + // Block for everything + if (Pstream::parRun()) + { + if (allUpdated) + { + // All received. Just remove all storage of requests + // Note that we don't know what starting number of requests + // was before start of sends and receives (since set from + // initMatrixInterfaces) so set to 0 and loose any in-flight + // requests. + UPstream::resetRequests(0); + } + else + { + // Block for all requests and remove storage + UPstream::waitRequests(); + } } + // Consume forAll(interfaces, interfaceI) { - if (interfaces.set(interfaceI)) + if + ( + interfaces.set(interfaceI) + && !interfaces[interfaceI].updatedMatrix() + ) { interfaces[interfaceI].updateInterfaceMatrix ( @@ -199,7 +266,7 @@ void Foam::lduMatrix::updateMatrixInterfaces } else { - FatalErrorIn("lduMatrix::updateMatrixInterfaces") + FatalErrorIn("lduMatrix::updateMatrixInterfaces(..)") << "Unsuported communications type " << Pstream::commsTypeNames[Pstream::defaultCommsType] << exit(FatalError); diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.C index 3b6d1ee026590ef420f99f54137dfe5ff47a4b0f..b8fa744ff6b0673f1174fee7fc22bb43ca95eccd 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.C +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -80,11 +80,38 @@ void Foam::processorGAMGInterfaceField::initInterfaceMatrixUpdate const Pstream::commsTypes commsType ) const { - procInterface_.compressedSend - ( - commsType, - procInterface_.interfaceInternalField(psiInternal)() - ); + procInterface_.interfaceInternalField(psiInternal, scalarSendBuf_); + + if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer) + { + // Fast path. + scalarReceiveBuf_.setSize(scalarSendBuf_.size()); + outstandingRecvRequest_ = UPstream::nRequests(); + IPstream::read + ( + Pstream::nonBlocking, + procInterface_.neighbProcNo(), + reinterpret_cast<char*>(scalarReceiveBuf_.begin()), + scalarReceiveBuf_.byteSize(), + procInterface_.tag() + ); + + outstandingSendRequest_ = UPstream::nRequests(); + OPstream::write + ( + Pstream::nonBlocking, + procInterface_.neighbProcNo(), + reinterpret_cast<const char*>(scalarSendBuf_.begin()), + scalarSendBuf_.byteSize(), + procInterface_.tag() + ); + } + else + { + procInterface_.compressedSend(commsType, scalarSendBuf_); + } + + const_cast<processorGAMGInterfaceField&>(*this).updatedMatrix() = false; } @@ -98,18 +125,54 @@ void Foam::processorGAMGInterfaceField::updateInterfaceMatrix const Pstream::commsTypes commsType ) const { - scalarField pnf - ( - procInterface_.compressedReceive<scalar>(commsType, coeffs.size()) - ); - transformCoupleField(pnf, cmpt); + if (updatedMatrix()) + { + return; + } const labelUList& faceCells = procInterface_.faceCells(); - forAll(faceCells, elemI) + if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer) { - result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI]; + // Fast path. + if + ( + outstandingRecvRequest_ >= 0 + && outstandingRecvRequest_ < Pstream::nRequests() + ) + { + UPstream::waitRequest(outstandingRecvRequest_); + } + // Recv finished so assume sending finished as well. + outstandingSendRequest_ = -1; + outstandingRecvRequest_ = -1; + + // Consume straight from scalarReceiveBuf_ + + // Transform according to the transformation tensor + transformCoupleField(scalarReceiveBuf_, cmpt); + + // Multiply the field by coefficients and add into the result + forAll(faceCells, elemI) + { + result[faceCells[elemI]] -= coeffs[elemI]*scalarReceiveBuf_[elemI]; + } } + else + { + scalarField pnf + ( + procInterface_.compressedReceive<scalar>(commsType, coeffs.size()) + ); + transformCoupleField(pnf, cmpt); + + forAll(faceCells, elemI) + { + result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI]; + } + } + + const_cast<processorGAMGInterfaceField&>(*this).updatedMatrix() = true; } diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.H index c1bdac02460856c176ab80f4efc3f1ea893c986d..48d64baacf369908a2bec65f6cc88fabe2b669aa 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.H +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -65,6 +65,22 @@ class processorGAMGInterfaceField int rank_; + // Sending and receiving + + //- Outstanding request + mutable label outstandingSendRequest_; + + //- Outstanding request + mutable label outstandingRecvRequest_; + + //- Scalar send buffer + mutable Field<scalar> scalarSendBuf_; + + //- Scalar receive buffer + mutable Field<scalar> scalarReceiveBuf_; + + + // Private Member Functions //- Disallow default bitwise copy construct diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterface.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterface.H index 8f25335415cb61771af91da86573ac6459408a97..ed6c7ca7468009f6849e67e6e5ce173378287585 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterface.H +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterface.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -188,6 +188,14 @@ public: const UList<Type>& internalData ) const; + //- Get the interface internal field of the given field + template<class Type> + void interfaceInternalField + ( + const UList<Type>& internalData, + List<Type>& + ) const; + //- Return the values of the given internal data adjacent to // the interface as a field virtual tmp<labelField> interfaceInternalField diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterfaceTemplates.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterfaceTemplates.C index 0d42d04cef72ae192b4cddada9dbe19963ecf73e..4890618ab12781c44a18b40239c013386b89dbaf 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterfaceTemplates.C +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterfaceTemplates.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -34,14 +34,24 @@ Foam::tmp<Foam::Field<Type> > Foam::GAMGInterface::interfaceInternalField ) const { tmp<Field<Type> > tresult(new Field<Type>(size())); - Field<Type>& result = tresult(); + interfaceInternalField(iF, tresult()); + return tresult; +} + + +template<class Type> +void Foam::GAMGInterface::interfaceInternalField +( + const UList<Type>& iF, + List<Type>& result +) const +{ + result.setSize(size()); forAll(result, elemI) { result[elemI] = iF[faceCells_[elemI]]; } - - return tresult; } diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C index 70bba49de93522744d94af640b129325b7a381aa..a44ea4cc5c9c4f789006e4134a673d201cb53077 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C @@ -43,7 +43,12 @@ processorFvPatchField<Type>::processorFvPatchField ) : coupledFvPatchField<Type>(p, iF), - procPatch_(refCast<const processorFvPatch>(p)) + procPatch_(refCast<const processorFvPatch>(p)), + sendBuf_(0), + outstandingSendRequest_(-1), + outstandingRecvRequest_(-1), + scalarSendBuf_(0), + scalarReceiveBuf_(0) {} @@ -56,7 +61,12 @@ processorFvPatchField<Type>::processorFvPatchField ) : coupledFvPatchField<Type>(p, iF, f), - procPatch_(refCast<const processorFvPatch>(p)) + procPatch_(refCast<const processorFvPatch>(p)), + sendBuf_(0), + outstandingSendRequest_(-1), + outstandingRecvRequest_(-1), + scalarSendBuf_(0), + scalarReceiveBuf_(0) {} @@ -71,7 +81,12 @@ processorFvPatchField<Type>::processorFvPatchField ) : coupledFvPatchField<Type>(ptf, p, iF, mapper), - procPatch_(refCast<const processorFvPatch>(p)) + procPatch_(refCast<const processorFvPatch>(p)), + sendBuf_(0), + outstandingSendRequest_(-1), + outstandingRecvRequest_(-1), + scalarSendBuf_(0), + scalarReceiveBuf_(0) { if (!isA<processorFvPatch>(this->patch())) { @@ -91,6 +106,12 @@ processorFvPatchField<Type>::processorFvPatchField << " in file " << this->dimensionedInternalField().objectPath() << exit(FatalIOError); } + if (debug && !ptf.ready()) + { + FatalErrorIn("processorFvPatchField<Type>::processorFvPatchField(..)") + << "On patch " << procPatch_.name() << " outstanding request." + << abort(FatalError); + } } @@ -103,7 +124,12 @@ processorFvPatchField<Type>::processorFvPatchField ) : coupledFvPatchField<Type>(p, iF, dict), - procPatch_(refCast<const processorFvPatch>(p)) + procPatch_(refCast<const processorFvPatch>(p)), + sendBuf_(0), + outstandingSendRequest_(-1), + outstandingRecvRequest_(-1), + scalarSendBuf_(0), + scalarReceiveBuf_(0) { if (!isA<processorFvPatch>(p)) { @@ -134,8 +160,20 @@ processorFvPatchField<Type>::processorFvPatchField : processorLduInterfaceField(), coupledFvPatchField<Type>(ptf), - procPatch_(refCast<const processorFvPatch>(ptf.patch())) -{} + procPatch_(refCast<const processorFvPatch>(ptf.patch())), + sendBuf_(ptf.sendBuf_.xfer()), + outstandingSendRequest_(-1), + outstandingRecvRequest_(-1), + scalarSendBuf_(ptf.scalarSendBuf_.xfer()), + scalarReceiveBuf_(ptf.scalarReceiveBuf_.xfer()) +{ + if (debug && !ptf.ready()) + { + FatalErrorIn("processorFvPatchField<Type>::processorFvPatchField(..)") + << "On patch " << procPatch_.name() << " outstanding request." + << abort(FatalError); + } +} template<class Type> @@ -146,8 +184,20 @@ processorFvPatchField<Type>::processorFvPatchField ) : coupledFvPatchField<Type>(ptf, iF), - procPatch_(refCast<const processorFvPatch>(ptf.patch())) -{} + procPatch_(refCast<const processorFvPatch>(ptf.patch())), + sendBuf_(0), + outstandingSendRequest_(-1), + outstandingRecvRequest_(-1), + scalarSendBuf_(0), + scalarReceiveBuf_(0) +{ + if (debug && !ptf.ready()) + { + FatalErrorIn("processorFvPatchField<Type>::processorFvPatchField(..)") + << "On patch " << procPatch_.name() << " outstanding request." + << abort(FatalError); + } +} // * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * // @@ -162,6 +212,13 @@ processorFvPatchField<Type>::~processorFvPatchField() template<class Type> tmp<Field<Type> > processorFvPatchField<Type>::patchNeighbourField() const { + if (debug && !this->ready()) + { + FatalErrorIn("processorFvPatchField<Type>::patchNeighbourField()") + << "On patch " << procPatch_.name() + << " outstanding request." + << abort(FatalError); + } return *this; } @@ -174,7 +231,36 @@ void processorFvPatchField<Type>::initEvaluate { if (Pstream::parRun()) { - procPatch_.compressedSend(commsType, this->patchInternalField()()); + this->patchInternalField(sendBuf_); + + if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer) + { + // Fast path. Receive into *this + this->setSize(sendBuf_.size()); + outstandingRecvRequest_ = UPstream::nRequests(); + IPstream::read + ( + Pstream::nonBlocking, + procPatch_.neighbProcNo(), + reinterpret_cast<char*>(this->begin()), + this->byteSize(), + procPatch_.tag() + ); + + outstandingSendRequest_ = UPstream::nRequests(); + OPstream::write + ( + Pstream::nonBlocking, + procPatch_.neighbProcNo(), + reinterpret_cast<const char*>(sendBuf_.begin()), + this->byteSize(), + procPatch_.tag() + ); + } + else + { + procPatch_.compressedSend(commsType, sendBuf_); + } } } @@ -187,7 +273,25 @@ void processorFvPatchField<Type>::evaluate { if (Pstream::parRun()) { - procPatch_.compressedReceive<Type>(commsType, *this); + if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer) + { + // Fast path. Received into *this + + if + ( + outstandingRecvRequest_ >= 0 + && outstandingRecvRequest_ < Pstream::nRequests() + ) + { + UPstream::waitRequest(outstandingRecvRequest_); + } + outstandingSendRequest_ = -1; + outstandingRecvRequest_ = -1; + } + else + { + procPatch_.compressedReceive<Type>(commsType, *this); + } if (doTransform()) { @@ -215,18 +319,49 @@ void processorFvPatchField<Type>::initInterfaceMatrixUpdate const Pstream::commsTypes commsType ) const { - procPatch_.compressedSend - ( - commsType, - this->patch().patchInternalField(psiInternal)() - ); -} + this->patch().patchInternalField(psiInternal, scalarSendBuf_); + if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer) + { + // Fast path. + if (debug && !this->ready()) + { + FatalErrorIn + ( + "processorFvPatchField<Type>::initInterfaceMatrixUpdate(..)" + ) << "On patch " << procPatch_.name() + << " outstanding request." + << abort(FatalError); + } -template<class Type> -bool processorFvPatchField<Type>::ready() const -{ - return true; + + scalarReceiveBuf_.setSize(scalarSendBuf_.size()); + outstandingRecvRequest_ = UPstream::nRequests(); + IPstream::read + ( + Pstream::nonBlocking, + procPatch_.neighbProcNo(), + reinterpret_cast<char*>(scalarReceiveBuf_.begin()), + scalarReceiveBuf_.byteSize(), + procPatch_.tag() + ); + + outstandingSendRequest_ = UPstream::nRequests(); + OPstream::write + ( + Pstream::nonBlocking, + procPatch_.neighbProcNo(), + reinterpret_cast<const char*>(scalarSendBuf_.begin()), + scalarSendBuf_.byteSize(), + procPatch_.tag() + ); + } + else + { + procPatch_.compressedSend(commsType, scalarSendBuf_); + } + + const_cast<processorFvPatchField<Type>&>(*this).updatedMatrix() = false; } @@ -241,22 +376,92 @@ void processorFvPatchField<Type>::updateInterfaceMatrix const Pstream::commsTypes commsType ) const { - scalarField pnf - ( - procPatch_.compressedReceive<scalar>(commsType, this->size())() - ); + if (this->updatedMatrix()) + { + return; + } + + const labelUList& faceCells = this->patch().faceCells(); - // Transform according to the transformation tensor - transformCoupleField(pnf, cmpt); + if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer) + { + // Fast path. + if + ( + outstandingRecvRequest_ >= 0 + && outstandingRecvRequest_ < Pstream::nRequests() + ) + { + UPstream::waitRequest(outstandingRecvRequest_); + } + // Recv finished so assume sending finished as well. + outstandingSendRequest_ = -1; + outstandingRecvRequest_ = -1; - // Multiply the field by coefficients and add into the result + // Consume straight from scalarReceiveBuf_ + + // Transform according to the transformation tensor + transformCoupleField(scalarReceiveBuf_, cmpt); + + // Multiply the field by coefficients and add into the result + forAll(faceCells, elemI) + { + result[faceCells[elemI]] -= coeffs[elemI]*scalarReceiveBuf_[elemI]; + } + } + else + { + scalarField pnf + ( + procPatch_.compressedReceive<scalar>(commsType, this->size())() + ); + + // Transform according to the transformation tensor + transformCoupleField(pnf, cmpt); + + // Multiply the field by coefficients and add into the result + forAll(faceCells, elemI) + { + result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI]; + } + } + + const_cast<processorFvPatchField<Type>&>(*this).updatedMatrix() = true; +} - const labelUList& faceCells = this->patch().faceCells(); - forAll(faceCells, elemI) +template<class Type> +bool processorFvPatchField<Type>::ready() const +{ + if + ( + outstandingSendRequest_ >= 0 + && outstandingSendRequest_ < Pstream::nRequests() + ) { - result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI]; + bool finished = UPstream::finishedRequest(outstandingSendRequest_); + if (!finished) + { + return false; + } } + outstandingSendRequest_ = -1; + + if + ( + outstandingRecvRequest_ >= 0 + && outstandingRecvRequest_ < Pstream::nRequests() + ) + { + bool finished = UPstream::finishedRequest(outstandingRecvRequest_); + if (!finished) + { + return false; + } + } + outstandingRecvRequest_ = -1; + + return true; } diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H index 1ed07e42384ea45a6efb66fa7f6f251c412c1840..9541e80ea56a3f040837f5092cddee9e90320412 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H @@ -59,6 +59,22 @@ class processorFvPatchField //- Local reference cast into the processor patch const processorFvPatch& procPatch_; + // Sending and receiving + + //- Send buffer. + mutable Field<Type> sendBuf_; + + //- Outstanding request + mutable label outstandingSendRequest_; + + //- Outstanding request + mutable label outstandingRecvRequest_; + + //- Scalar send buffer + mutable Field<scalar> scalarSendBuf_; + + //- Scalar receive buffer + mutable Field<scalar> scalarReceiveBuf_; public: diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchScalarField.C b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchScalarField.C index b94e8049f9872ed4011cb56ebdcc6d9168491366..c15b1c1be7f8950c9354099b2913704bb2c41840 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchScalarField.C +++ b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchScalarField.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -43,11 +43,53 @@ void processorFvPatchField<scalar>::initInterfaceMatrixUpdate const Pstream::commsTypes commsType ) const { - procPatch_.compressedSend + this->patch().patchInternalField(psiInternal, scalarSendBuf_); + + if ( - commsType, - patch().patchInternalField(psiInternal)() - ); + Pstream::defaultCommsType == Pstream::nonBlocking + && !Pstream::floatTransfer + ) + { + // Fast path. + if (debug && !this->ready()) + { + FatalErrorIn + ( + "processorFvPatchField<scalar>::initInterfaceMatrixUpdate(..)" + ) << "On patch " << procPatch_.name() + << " outstanding request." + << abort(FatalError); + } + + + scalarReceiveBuf_.setSize(scalarSendBuf_.size()); + outstandingRecvRequest_ = UPstream::nRequests(); + IPstream::read + ( + Pstream::nonBlocking, + procPatch_.neighbProcNo(), + reinterpret_cast<char*>(scalarReceiveBuf_.begin()), + scalarReceiveBuf_.byteSize(), + procPatch_.tag() + ); + + outstandingSendRequest_ = UPstream::nRequests(); + OPstream::write + ( + Pstream::nonBlocking, + procPatch_.neighbProcNo(), + reinterpret_cast<const char*>(scalarSendBuf_.begin()), + scalarSendBuf_.byteSize(), + procPatch_.tag() + ); + } + else + { + procPatch_.compressedSend(commsType, scalarSendBuf_); + } + + const_cast<processorFvPatchField<scalar>&>(*this).updatedMatrix() = false; } @@ -62,17 +104,48 @@ void processorFvPatchField<scalar>::updateInterfaceMatrix const Pstream::commsTypes commsType ) const { - scalarField pnf - ( - procPatch_.compressedReceive<scalar>(commsType, this->size())() - ); + if (this->updatedMatrix()) + { + return; + } - const labelUList& faceCells = patch().faceCells(); + const labelUList& faceCells = this->patch().faceCells(); - forAll(faceCells, facei) + if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer) { - result[faceCells[facei]] -= coeffs[facei]*pnf[facei]; + // Fast path. + if + ( + outstandingRecvRequest_ >= 0 + && outstandingRecvRequest_ < Pstream::nRequests() + ) + { + UPstream::waitRequest(outstandingRecvRequest_); + } + outstandingSendRequest_ = -1; + outstandingRecvRequest_ = -1; + + + // Consume straight from scalarReceiveBuf_ + forAll(faceCells, elemI) + { + result[faceCells[elemI]] -= coeffs[elemI]*scalarReceiveBuf_[elemI]; + } } + else + { + scalarField pnf + ( + procPatch_.compressedReceive<scalar>(commsType, this->size())() + ); + + forAll(faceCells, elemI) + { + result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI]; + } + } + + const_cast<processorFvPatchField<scalar>&>(*this).updatedMatrix() = true; }