diff --git a/src/OpenFOAM/meshes/polyMesh/polyDistributionMap/distributionMapBase.C b/src/OpenFOAM/meshes/polyMesh/polyDistributionMap/distributionMapBase.C index 511b5e66b2..4ddab3e7d9 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyDistributionMap/distributionMapBase.C +++ b/src/OpenFOAM/meshes/polyMesh/polyDistributionMap/distributionMapBase.C @@ -846,16 +846,32 @@ void Foam::distributionMapBase::compact // from the submap and do the same to the constructMap locally // (and in same order). - // Send elemIsUsed field to neighbour. Use nonblocking code from - // distributionMapBase but in reverse order. + // Send elemIsUsed field to neighbours + List recvFields(Pstream::nProcs()); + + // "Send" to myself (i.e., write directly into recvFields) + { + const labelList& map = constructMap_[Pstream::myProcNo()]; + + recvFields[Pstream::myProcNo()].setSize(map.size()); + forAll(map, i) + { + recvFields[Pstream::myProcNo()][i] = accessAndFlip + ( + elemIsUsed, + map[i], + constructHasFlip_, + noOp() // do not flip elemIsUsed value + ); + } + } + + // Send to others. Use nonblocking code from distributionMapBase but in + // reverse order. if (Pstream::parRun()) { label startOfRequests = Pstream::nRequests(); - // Set up receives from neighbours - - List recvFields(Pstream::nProcs()); - for (label domain = 0; domain < Pstream::nProcs(); domain++) { const labelList& map = subMap_[domain]; @@ -874,7 +890,6 @@ void Foam::distributionMapBase::compact } } - List sendFields(Pstream::nProcs()); for (label domain = 0; domain < Pstream::nProcs(); domain++) @@ -907,62 +922,35 @@ void Foam::distributionMapBase::compact } } + Pstream::waitRequests(startOfRequests); + } + // Compact out all submap entries that are referring to unused elements + for (label domain = 0; domain < Pstream::nProcs(); domain++) + { + const labelList& map = subMap_[domain]; - // Set up 'send' to myself - write directly into recvFields + labelList newMap(map.size()); + label newI = 0; + forAll(map, i) { - const labelList& map = constructMap_[Pstream::myProcNo()]; - - recvFields[Pstream::myProcNo()].setSize(map.size()); - forAll(map, i) + if (recvFields[domain][i]) { - recvFields[Pstream::myProcNo()][i] = accessAndFlip - ( - elemIsUsed, - map[i], - constructHasFlip_, - noOp() // do not flip elemIsUsed value - ); + // So element is used on destination side + newMap[newI++] = map[i]; } } - - - // Wait for all to finish - - Pstream::waitRequests(startOfRequests); - - - // Compact out all submap entries that are referring to unused elements - for (label domain = 0; domain < Pstream::nProcs(); domain++) + if (newI < map.size()) { - const labelList& map = subMap_[domain]; - - labelList newMap(map.size()); - label newI = 0; - - forAll(map, i) - { - if (recvFields[domain][i]) - { - // So element is used on destination side - newMap[newI++] = map[i]; - } - } - if (newI < map.size()) - { - newMap.setSize(newI); - subMap_[domain].transfer(newMap); - } + newMap.setSize(newI); + subMap_[domain].transfer(newMap); } } - // 2. remove from construct map - since end-result (element in elemIsUsed) // not used. - label maxConstructIndex = -1; - for (label domain = 0; domain < Pstream::nProcs(); domain++) { const labelList& map = constructMap_[domain]; @@ -1013,16 +1001,32 @@ void Foam::distributionMapBase::compact // from the submap and do the same to the constructMap locally // (and in same order). - // Send elemIsUsed field to neighbour. Use nonblocking code from - // distributionMapBase but in reverse order. + // Send elemIsUsed field to neighbours + List recvFields(Pstream::nProcs()); + + // "Send" to myself (i.e., write directly into recvFields) + { + const labelList& map = constructMap_[Pstream::myProcNo()]; + + recvFields[Pstream::myProcNo()].setSize(map.size()); + forAll(map, i) + { + recvFields[Pstream::myProcNo()][i] = accessAndFlip + ( + elemIsUsed, + map[i], + constructHasFlip_, + noOp() // do not flip elemIsUsed value + ); + } + } + + // Send to others. Use nonblocking code from distributionMapBase but in + // reverse order. if (Pstream::parRun()) { label startOfRequests = Pstream::nRequests(); - // Set up receives from neighbours - - List recvFields(Pstream::nProcs()); - for (label domain = 0; domain < Pstream::nProcs(); domain++) { const labelList& map = subMap_[domain]; @@ -1041,7 +1045,6 @@ void Foam::distributionMapBase::compact } } - List sendFields(Pstream::nProcs()); for (label domain = 0; domain < Pstream::nProcs(); domain++) @@ -1054,12 +1057,13 @@ void Foam::distributionMapBase::compact subField.setSize(map.size()); forAll(map, i) { - label index = map[i]; - if (constructHasFlip_) - { - index = mag(index)-1; - } - subField[i] = elemIsUsed[index]; + subField[i] = accessAndFlip + ( + elemIsUsed, + map[i], + constructHasFlip_, + noOp() // do not flip elemIsUsed value + ); } OPstream::write @@ -1073,108 +1077,79 @@ void Foam::distributionMapBase::compact } } - - - // Set up 'send' to myself - write directly into recvFields - - { - const labelList& map = constructMap_[Pstream::myProcNo()]; - - recvFields[Pstream::myProcNo()].setSize(map.size()); - forAll(map, i) - { - label index = map[i]; - if (constructHasFlip_) - { - index = mag(index)-1; - } - recvFields[Pstream::myProcNo()][i] = elemIsUsed[index]; - } - } - - - // Wait for all to finish - Pstream::waitRequests(startOfRequests); + } + // Work out which elements on the sending side are needed + { + oldToNewSub.setSize(localSize, -1); + boolList sendElemIsUsed(localSize, false); - - // Work out which elements on the sending side are needed - { - oldToNewSub.setSize(localSize, -1); - - boolList sendElemIsUsed(localSize, false); - - for (label domain = 0; domain < Pstream::nProcs(); domain++) - { - const labelList& map = subMap_[domain]; - forAll(map, i) - { - if (recvFields[domain][i]) - { - label index = map[i]; - if (subHasFlip_) - { - index = mag(index)-1; - } - sendElemIsUsed[index] = true; - } - } - } - - label newI = 0; - forAll(sendElemIsUsed, i) - { - if (sendElemIsUsed[i]) - { - oldToNewSub[i] = newI++; - } - } - } - - - // Compact out all submap entries that are referring to unused elements for (label domain = 0; domain < Pstream::nProcs(); domain++) { const labelList& map = subMap_[domain]; - - labelList newMap(map.size()); - label newI = 0; - forAll(map, i) { if (recvFields[domain][i]) { - // So element is used on destination side label index = map[i]; - label sign = 1; if (subHasFlip_) { - if (index < 0) - { - sign = -1; - } index = mag(index)-1; } - label newIndex = oldToNewSub[index]; - if (subHasFlip_) - { - newIndex = sign*(newIndex+1); - } - newMap[newI++] = newIndex; + sendElemIsUsed[index] = true; } } - newMap.setSize(newI); - subMap_[domain].transfer(newMap); + } + + label newI = 0; + forAll(sendElemIsUsed, i) + { + if (sendElemIsUsed[i]) + { + oldToNewSub[i] = newI++; + } } } + // Compact out all submap entries that are referring to unused elements + for (label domain = 0; domain < Pstream::nProcs(); domain++) + { + const labelList& map = subMap_[domain]; + + labelList newMap(map.size()); + label newI = 0; + + forAll(map, i) + { + if (recvFields[domain][i]) + { + // So element is used on destination side + label index = map[i]; + label sign = 1; + if (subHasFlip_) + { + if (index < 0) + { + sign = -1; + } + index = mag(index)-1; + } + label newIndex = oldToNewSub[index]; + if (subHasFlip_) + { + newIndex = sign*(newIndex+1); + } + newMap[newI++] = newIndex; + } + } + newMap.setSize(newI); + subMap_[domain].transfer(newMap); + } // 2. remove from construct map - since end-result (element in elemIsUsed) // not used. - - oldToNewConstruct.setSize(elemIsUsed.size(), -1); constructSize_ = 0; forAll(elemIsUsed, i) diff --git a/src/OpenFOAM/primitives/RemoteData/RemoteData.H b/src/OpenFOAM/primitives/RemoteData/RemoteData.H new file mode 100644 index 0000000000..416a4e391c --- /dev/null +++ b/src/OpenFOAM/primitives/RemoteData/RemoteData.H @@ -0,0 +1,169 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Copyright (C) 2022 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 . + +Class + Foam::RemoteData + +Description + Struct for keeping processor, element (cell, face, point) and a piece of + data. Used for finding minimum values across multiple processes. + +SourceFiles + RemoteDataI.H + +\*---------------------------------------------------------------------------*/ + +#ifndef RemoteData_H +#define RemoteData_H + +#include "Istream.H" +#include "Ostream.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declaration of friend functions and operators +template +class RemoteData; +template +inline bool operator==(const RemoteData&, const RemoteData&); +template +inline bool operator!=(const RemoteData&, const RemoteData&); +template +inline Istream& operator>>(Istream&, RemoteData&); +template +inline Ostream& operator<<(Ostream&, const RemoteData&); + +/*---------------------------------------------------------------------------*\ + Class RemoteData Declaration +\*---------------------------------------------------------------------------*/ + +template +class RemoteData +{ +public: + + // Public Data + + //- Processor index + label proci; + + //- Element index + label elementi; + + //- Data + Type data; + + + // Constructors + + //- Construct null + inline RemoteData(); + + //- Construct from components + inline RemoteData(const label, const label, const Type&); + + //- Construct from stream + inline RemoteData(Istream& is); + + + // Public Classes + + //- Operator to take smallest valid value + struct smallestEqOp + { + inline void operator() + ( + RemoteData& x, + const RemoteData& y + ) const; + }; + + //- Operator to take smallest first valid value + struct smallestFirstEqOp + { + inline void operator() + ( + RemoteData& x, + const RemoteData& y + ) const; + }; + + + // Friend Operators + + //- Equality comparison + friend bool operator== + ( + const RemoteData& a, + const RemoteData& b + ); + + //- Inequality comparison + friend bool operator!= + ( + const RemoteData& a, + const RemoteData& b + ); + + + // IOstream Operators + + //- Write to stream + friend Ostream& operator<< + ( + Ostream& os, + const RemoteData& p + ); + + //- Read from stream + friend Istream& operator>> + ( + Istream& is, + RemoteData& p + ); +}; + + +template +struct pTraits> +{ + typedef RemoteData cmptType; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "RemoteDataI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/RemoteData/RemoteDataI.H b/src/OpenFOAM/primitives/RemoteData/RemoteDataI.H new file mode 100644 index 0000000000..7abcb4aa35 --- /dev/null +++ b/src/OpenFOAM/primitives/RemoteData/RemoteDataI.H @@ -0,0 +1,150 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Copyright (C) 2022 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 "RemoteData.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template +inline Foam::RemoteData::RemoteData() +: + proci(-1), + elementi(-1), + data() +{} + + +template +inline Foam::RemoteData::RemoteData +( + const label p, + const label e, + const Type& d +) +: + proci(p), + elementi(e), + data(d) +{} + + +template +inline Foam::RemoteData::RemoteData(Istream& is) +{ + is >> *this; +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +template +inline void Foam::RemoteData::smallestEqOp::operator() +( + RemoteData& x, + const RemoteData& y +) const +{ + if (y.proci != -1) + { + if (x.proci == -1) + { + x = y; + } + else if (y.data < x.data) + { + x = y; + } + } +} + + +template +inline void Foam::RemoteData::smallestFirstEqOp::operator() +( + RemoteData& x, + const RemoteData& y +) const +{ + if (y.proci != -1) + { + if (x.proci == -1) + { + x = y; + } + else if (y.data.first() < x.data.first()) + { + x = y; + } + } +} + + +// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * // + +template +inline bool Foam::operator== +( + const RemoteData& a, + const RemoteData& b +) +{ + return + a.proci == b.proci + && a.elementi == b.elementi + && a.data == b.data; +} + + +template +inline bool Foam::operator!= +( + const RemoteData& a, + const RemoteData& b +) +{ + return !(a == b); +} + + +// * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * * // + +template +inline Foam::Ostream& Foam::operator<<(Ostream& os, const RemoteData& p) +{ + return os + << p.proci << token::SPACE + << p.elementi << token::SPACE + << p.data; +} + + +template +inline Foam::Istream& Foam::operator>>(Istream& is, RemoteData& p) +{ + return is >> p.proci >> p.elementi >> p.data; +} + + +// ************************************************************************* // diff --git a/src/ThermophysicalTransportModels/derivedFvPatchFields/thermalBaffle1D/thermalBaffle1DFvPatchScalarField.C b/src/ThermophysicalTransportModels/derivedFvPatchFields/thermalBaffle1D/thermalBaffle1DFvPatchScalarField.C index 8d72e75762..397dce7744 100644 --- a/src/ThermophysicalTransportModels/derivedFvPatchFields/thermalBaffle1D/thermalBaffle1DFvPatchScalarField.C +++ b/src/ThermophysicalTransportModels/derivedFvPatchFields/thermalBaffle1D/thermalBaffle1DFvPatchScalarField.C @@ -252,13 +252,7 @@ baffleThickness() const { const mappedPatchBase& mpp = refCast(patch().patch()); - - tmp nbrBaffleThickness - ( - new scalarField(nbrField().baffleThickness()) - ); - mpp.distribute(nbrBaffleThickness.ref()); - return nbrBaffleThickness; + return mpp.distribute(nbrField().baffleThickness()); } } @@ -274,13 +268,7 @@ tmp thermalBaffle1DFvPatchScalarField::qs() const { const mappedPatchBase& mpp = refCast(patch().patch()); - - tmp nbrQs - ( - new scalarField(nbrField().qs()) - ); - mpp.distribute(nbrQs.ref()); - return nbrQs; + return mpp.distribute(nbrField().qs()); } } @@ -391,8 +379,7 @@ void thermalBaffle1DFvPatchScalarField::updateCoeffs() scalarField kappaDelta(kappap*patch().deltaCoeffs()); // Neighbour properties - scalarField nbrTp(nbrField()); - mpp.distribute(nbrTp); + const scalarField nbrTp(mpp.distribute(nbrField())); // Solid properties scalarField kappas(patch().size(), 0.0); diff --git a/src/ThermophysicalTransportModels/derivedFvPatchFields/turbulentTemperatureCoupledBaffleMixed/turbulentTemperatureCoupledBaffleMixedFvPatchScalarField.C b/src/ThermophysicalTransportModels/derivedFvPatchFields/turbulentTemperatureCoupledBaffleMixed/turbulentTemperatureCoupledBaffleMixedFvPatchScalarField.C index fe7bb87d26..894b24ef53 100644 --- a/src/ThermophysicalTransportModels/derivedFvPatchFields/turbulentTemperatureCoupledBaffleMixed/turbulentTemperatureCoupledBaffleMixedFvPatchScalarField.C +++ b/src/ThermophysicalTransportModels/derivedFvPatchFields/turbulentTemperatureCoupledBaffleMixed/turbulentTemperatureCoupledBaffleMixedFvPatchScalarField.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -216,27 +216,22 @@ void turbulentTemperatureCoupledBaffleMixedFvPatchScalarField::updateCoeffs() << "currently of type " << nbrTp.type() << exit(FatalError); } + const scalarField myKDelta(kappa(*this)*patch().deltaCoeffs()); + const thisType& nbrField = refCast(nbrTp); - // Swap to obtain full local values of neighbour internal field - tmp nbrIntFld(new scalarField(nbrField.size(), 0.0)); - tmp nbrKDelta(new scalarField(nbrField.size(), 0.0)); - - if (contactRes_ == 0.0) - { - nbrIntFld.ref() = nbrField.patchInternalField(); - nbrKDelta.ref() = nbrField.kappa(nbrField)*nbrPatch.deltaCoeffs(); - } - else - { - nbrIntFld.ref() = nbrField; - nbrKDelta.ref() = contactRes_; - } - - mpp.distribute(nbrIntFld.ref()); - mpp.distribute(nbrKDelta.ref()); - - tmp myKDelta = kappa(*this)*patch().deltaCoeffs(); + const scalarField nbrIntFld + ( + contactRes_ == 0 + ? mpp.distribute(nbrField.patchInternalField()) + : mpp.distribute(nbrField) + ); + const scalarField nbrKDelta + ( + contactRes_ == 0 + ? mpp.distribute(nbrField.kappa(nbrField)*nbrPatch.deltaCoeffs()) + : tmp(new scalarField(contactRes_, nbrField.size())) + ); // Both sides agree on // - temperature : (myKDelta*fld + nbrKDelta*nbrFld)/(myKDelta+nbrKDelta) @@ -251,11 +246,11 @@ void turbulentTemperatureCoupledBaffleMixedFvPatchScalarField::updateCoeffs() // same on both sides. This leads to the choice of // - refGradient = qs_/kappa; // - refValue = neighbour value - // - mixFraction = nbrKDelta / (nbrKDelta + myKDelta()) + // - mixFraction = nbrKDelta / (nbrKDelta + myKDelta) - this->refValue() = nbrIntFld(); + this->refValue() = nbrIntFld; this->refGrad() = qs_/kappa(*this); - this->valueFraction() = nbrKDelta()/(nbrKDelta() + myKDelta()); + this->valueFraction() = nbrKDelta/(nbrKDelta + myKDelta); mixedFvPatchScalarField::updateCoeffs(); diff --git a/src/ThermophysicalTransportModels/derivedFvPatchFields/turbulentTemperatureRadCoupledMixed/turbulentTemperatureRadCoupledMixedFvPatchScalarField.C b/src/ThermophysicalTransportModels/derivedFvPatchFields/turbulentTemperatureRadCoupledMixed/turbulentTemperatureRadCoupledMixedFvPatchScalarField.C index f31dcb3e01..044f0061c9 100644 --- a/src/ThermophysicalTransportModels/derivedFvPatchFields/turbulentTemperatureRadCoupledMixed/turbulentTemperatureRadCoupledMixedFvPatchScalarField.C +++ b/src/ThermophysicalTransportModels/derivedFvPatchFields/turbulentTemperatureRadCoupledMixed/turbulentTemperatureRadCoupledMixedFvPatchScalarField.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -182,7 +182,6 @@ void turbulentTemperatureRadCoupledMixedFvPatchScalarField::updateCoeffs() const fvPatch& nbrPatch = refCast(nbrMesh).boundary()[samplePatchi]; - scalarField Tc(patchInternalField()); scalarField& Tp = *this; @@ -204,36 +203,37 @@ void turbulentTemperatureRadCoupledMixedFvPatchScalarField::updateCoeffs() const thisType& nbrField = refCast(nbrTp); // Swap to obtain full local values of neighbour internal field - scalarField TcNbr(nbrField.patchInternalField()); - mpp.distribute(TcNbr); + const scalarField TcNbr(mpp.distribute(nbrField.patchInternalField())); + const scalarField KDelta(kappa(*this)*patch().deltaCoeffs()); // Swap to obtain full local values of neighbour K*delta - scalarField KDeltaNbr; - if (contactRes_ == 0.0) - { - KDeltaNbr = nbrField.kappa(nbrField)*nbrPatch.deltaCoeffs(); - } - else - { - KDeltaNbr.setSize(nbrField.size(), contactRes_); - } - mpp.distribute(KDeltaNbr); + const scalarField KDeltaNbr + ( + contactRes_ == 0 + ? mpp.distribute(nbrField.kappa(nbrField)*nbrPatch.deltaCoeffs()) + : tmp(new scalarField(nbrField.size(), contactRes_)) + ); - scalarField KDelta(kappa(*this)*patch().deltaCoeffs()); + const scalarField qr + ( + qrName_ != "none" + ? static_cast + ( + patch().lookupPatchField(qrName_) + ) + : scalarField(Tp.size(), 0) + ); - scalarField qr(Tp.size(), 0.0); - if (qrName_ != "none") - { - qr = patch().lookupPatchField(qrName_); - } - - scalarField qrNbr(Tp.size(), 0.0); - if (qrNbrName_ != "none") - { - qrNbr = nbrPatch.lookupPatchField(qrNbrName_); - mpp.distribute(qrNbr); - } + const scalarField qrNbr + ( + qrNbrName_ != "none" + ? mpp.distribute + ( + nbrPatch.lookupPatchField(qrNbrName_) + ) + : tmp(new scalarField(Tp.size(), 0)) + ); valueFraction() = KDeltaNbr/(KDeltaNbr + KDelta); refValue() = TcNbr; diff --git a/src/finiteVolume/fields/fvPatchFields/derived/mappedField/mappedPatchFieldBase.C b/src/finiteVolume/fields/fvPatchFields/derived/mappedField/mappedPatchFieldBase.C index 922b219653..97533573e0 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/mappedField/mappedPatchFieldBase.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/mappedField/mappedPatchFieldBase.C @@ -146,11 +146,7 @@ mappedPatchFieldBase::sampleField() const if (fieldName_ == patchField_.internalField().name()) { // Optimisation: bypass field lookup - return - dynamic_cast - ( - patchField_.internalField() - ); + return dynamic_cast(patchField_.internalField()); } else { @@ -170,14 +166,13 @@ tmp> mappedPatchFieldBase::mappedField() const { typedef GeometricField fieldType; + const fvMesh& nbrMesh = refCast(mapper_.sampleMesh()); + // Since we're inside initEvaluate/evaluate there might be processor // comms underway. Change the tag we use. int oldTag = UPstream::msgType(); UPstream::msgType() = oldTag + 1; - const fvMesh& thisMesh = patchField_.patch().boundaryMesh().mesh(); - const fvMesh& nbrMesh = refCast(mapper_.sampleMesh()); - // Result of obtaining remote values tmp> tnewValues(new Field(0)); Field& newValues = tnewValues.ref(); @@ -186,24 +181,10 @@ tmp> mappedPatchFieldBase::mappedField() const { case mappedPatchBase::NEARESTCELL: { - const distributionMap& distMap = mapper_.map(); - if (interpolationScheme_ != interpolationCell::typeName) { - // Send back sample points to the processor that holds the cell - vectorField samples(mapper_.samplePoints()); - distMap.reverseDistribute - ( - ( - mapper_.sameRegion() - ? thisMesh.nCells() - : nbrMesh.nCells() - ), - point::max, - samples - ); - - autoPtr> interpolator + // Create an interpolation + autoPtr> interpolatorPtr ( interpolation::New ( @@ -211,28 +192,43 @@ tmp> mappedPatchFieldBase::mappedField() const sampleField() ) ); - const interpolation& interp = interpolator(); + const interpolation& interpolator = interpolatorPtr(); - newValues.setSize(samples.size(), pTraits::max); - forAll(samples, celli) + // Cells on which samples are generated + const labelList& sampleCells = mapper_.mapIndices(); + + // Send the patch points to the cells + pointField samplePoints(mapper_.samplePoints()); + mapper_.map().reverseDistribute + ( + sampleCells.size(), + samplePoints + ); + + // Interpolate values + Field sampleValues(sampleCells.size()); + forAll(sampleCells, i) { - if (samples[celli] != point::max) + if (sampleCells[i] != -1) { - newValues[celli] = interp.interpolate - ( - samples[celli], - celli - ); + sampleValues[i] = + interpolator.interpolate + ( + samplePoints[i], + sampleCells[i] + ); } } + + // Send the values back to the patch + newValues = sampleValues; + mapper_.map().distribute(newValues); } else { - newValues = sampleField(); + newValues = mapper_.distribute(sampleField()); } - distMap.distribute(newValues); - break; } case mappedPatchBase::NEARESTPATCHFACE: @@ -252,8 +248,8 @@ tmp> mappedPatchFieldBase::mappedField() const const fieldType& nbrField = sampleField(); - newValues = nbrField.boundaryField()[nbrPatchID]; - mapper_.distribute(newValues); + newValues = + mapper_.distribute(nbrField.boundaryField()[nbrPatchID]); break; } @@ -275,8 +271,7 @@ tmp> mappedPatchFieldBase::mappedField() const } } - mapper_.distribute(allValues); - newValues.transfer(allValues); + newValues = mapper_.distribute(allValues); break; } diff --git a/src/finiteVolume/fields/fvPatchFields/derived/mappedFixedInternalValue/mappedFixedInternalValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/mappedFixedInternalValue/mappedFixedInternalValueFvPatchField.C index 666b5be0c9..5c05e44267 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/mappedFixedInternalValue/mappedFixedInternalValueFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/mappedFixedInternalValue/mappedFixedInternalValueFvPatchField.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -127,8 +127,8 @@ void Foam::mappedFixedInternalValueFvPatchField::updateCoeffs() const label samplePatchi = mpp.samplePolyPatch().index(); const fvPatchField& nbrPatchField = this->sampleField().boundaryField()[samplePatchi]; - nbrIntFld = nbrPatchField.patchInternalField(); - mpp.distribute(nbrIntFld); + + nbrIntFld = mpp.distribute(nbrPatchField.patchInternalField()); break; } @@ -151,8 +151,7 @@ void Foam::mappedFixedInternalValueFvPatchField::updateCoeffs() } } - mpp.distribute(allValues); - nbrIntFld.transfer(allValues); + nbrIntFld = mpp.distribute(allValues); break; } diff --git a/src/finiteVolume/fields/fvPatchFields/derived/mappedFlowRate/mappedFlowRateFvPatchVectorField.C b/src/finiteVolume/fields/fvPatchFields/derived/mappedFlowRate/mappedFlowRateFvPatchVectorField.C index fcf2aee875..d5329da5a8 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/mappedFlowRate/mappedFlowRateFvPatchVectorField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/mappedFlowRate/mappedFlowRateFvPatchVectorField.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -112,11 +112,13 @@ void Foam::mappedFlowRateFvPatchVectorField::updateCoeffs() nbrMesh ).boundary()[mpp.samplePolyPatch().index()]; - scalarList phi = - nbrPatch.lookupPatchField(nbrPhiName_); - - mpp.distribute(phi); - + const scalarField phi + ( + mpp.distribute + ( + nbrPatch.lookupPatchField(nbrPhiName_) + ) + ); const surfaceScalarField& phiName = db().lookupObject(phiName_); diff --git a/src/finiteVolume/fields/fvPatchFields/derived/mappedVelocityFluxFixedValue/mappedVelocityFluxFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/mappedVelocityFluxFixedValue/mappedVelocityFluxFixedValueFvPatchField.C index 8d6e92521b..3ccf4677f7 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/mappedVelocityFluxFixedValue/mappedVelocityFluxFixedValueFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/mappedVelocityFluxFixedValue/mappedVelocityFluxFixedValueFvPatchField.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -172,11 +172,8 @@ void Foam::mappedVelocityFluxFixedValueFvPatchField::updateCoeffs() } } - mpp.distribute(allUValues); - newUValues.transfer(allUValues); - - mpp.distribute(allPhiValues); - newPhiValues.transfer(allPhiValues); + newUValues = mpp.distribute(allUValues); + newPhiValues = mpp.distribute(allPhiValues); break; } @@ -186,11 +183,8 @@ void Foam::mappedVelocityFluxFixedValueFvPatchField::updateCoeffs() const label nbrPatchID = nbrMesh.boundaryMesh().findPatchID(mpp.samplePatch()); - newUValues = UField.boundaryField()[nbrPatchID]; - mpp.distribute(newUValues); - - newPhiValues = phiField.boundaryField()[nbrPatchID]; - mpp.distribute(newPhiValues); + newUValues = mpp.distribute(UField.boundaryField()[nbrPatchID]); + newPhiValues = mpp.distribute(phiField.boundaryField()[nbrPatchID]); break; } diff --git a/src/lagrangian/parcel/submodels/Momentum/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C b/src/lagrangian/parcel/submodels/Momentum/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C index 8761e49852..0f57ab7b33 100644 --- a/src/lagrangian/parcel/submodels/Momentum/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C +++ b/src/lagrangian/parcel/submodels/Momentum/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -200,7 +200,7 @@ void Foam::SurfaceFilmModel::cacheFilmFields diameterParcelPatch_ = filmModel.cloudDiameterTrans().boundaryField()[filmPatchi]; - filmModel.toPrimary(filmPatchi, diameterParcelPatch_, maxEqOp()); + filmModel.toPrimary(filmPatchi, diameterParcelPatch_); UFilmPatch_ = filmModel.U().boundaryField()[filmPatchi]; filmModel.toPrimary(filmPatchi, UFilmPatch_); diff --git a/src/lagrangian/parcel/submodels/Momentum/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H b/src/lagrangian/parcel/submodels/Momentum/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H index 4e6308fbf5..1155eaf1e5 100644 --- a/src/lagrangian/parcel/submodels/Momentum/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H +++ b/src/lagrangian/parcel/submodels/Momentum/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -83,19 +83,19 @@ protected: // Cached injector fields per film patch //- Parcel mass / patch face - scalarList massParcelPatch_; + scalarField massParcelPatch_; //- Parcel diameter / patch face - scalarList diameterParcelPatch_; + scalarField diameterParcelPatch_; //- Film velocity / patch face - List UFilmPatch_; + vectorField UFilmPatch_; //- Film density / patch face - scalarList rhoFilmPatch_; + scalarField rhoFilmPatch_; //- Film height of all film patches / patch face - scalarListList deltaFilmPatch_; + List deltaFilmPatch_; // Counters diff --git a/src/lagrangian/parcel/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.H b/src/lagrangian/parcel/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.H index 68c5f696eb..1c3820f796 100644 --- a/src/lagrangian/parcel/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.H +++ b/src/lagrangian/parcel/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -104,10 +104,10 @@ protected: // Cached injector fields per film patch //- Film temperature / patch face - scalarList TFilmPatch_; + scalarField TFilmPatch_; //- Film specific heat capacity / patch face - scalarList CpFilmPatch_; + scalarField CpFilmPatch_; // Interaction model data diff --git a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C index f817d1584b..d4bf3fa417 100644 --- a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C +++ b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C @@ -24,24 +24,20 @@ License \*---------------------------------------------------------------------------*/ #include "mappedPatchBase.H" -#include "addToRunTimeSelectionTable.H" -#include "ListListOps.H" #include "meshSearchMeshObject.H" #include "meshTools.H" -#include "OFstream.H" -#include "Random.H" +#include "OBJstream.H" #include "treeDataFace.H" -#include "treeDataPoint.H" +#include "treeDataCell.H" #include "indexedOctree.H" #include "polyMesh.H" #include "polyPatch.H" +#include "SubField.H" #include "Time.H" #include "distributionMap.H" -#include "SubField.H" #include "triPointRef.H" -#include "syncTools.H" -#include "treeDataCell.H" -#include "DynamicField.H" +#include "RemoteData.H" +#include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -53,14 +49,13 @@ namespace Foam const char* Foam::NamedEnum < Foam::mappedPatchBase::sampleMode, - 5 + 4 >::names[] = { "nearestCell", "nearestPatchFace", "nearestPatchFaceAMI", - "nearestFace", - "nearestOnlyCell" + "nearestFace" }; template<> @@ -77,7 +72,7 @@ namespace Foam } -const Foam::NamedEnum +const Foam::NamedEnum Foam::mappedPatchBase::sampleModeNames_; const Foam::NamedEnum @@ -86,76 +81,40 @@ const Foam::NamedEnum // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -void Foam::mappedPatchBase::collectSamples -( - pointField& samples, - labelList& patchFaceProcs, - labelList& patchFaces -) const -{ - // Collect all sample points and the faces they come from. - - { - List globalSamples(Pstream::nProcs()); - globalSamples[Pstream::myProcNo()] = samplePoints(); - Pstream::gatherList(globalSamples); - Pstream::scatterList(globalSamples); - - samples = ListListOps::combine - ( - globalSamples, - accessOp() - ); - } - - { - labelListList globalFaces(Pstream::nProcs()); - globalFaces[Pstream::myProcNo()] = identity(patch_.size()); - Pstream::gatherList(globalFaces); - Pstream::scatterList(globalFaces); - - patchFaces = ListListOps::combine - ( - globalFaces, - accessOp() - ); - } - - { - labelList nPerProc(Pstream::nProcs()); - nPerProc[Pstream::myProcNo()] = patch_.size(); - Pstream::gatherList(nPerProc); - Pstream::scatterList(nPerProc); - - patchFaceProcs.setSize(patchFaces.size()); - - label sampleI = 0; - forAll(nPerProc, proci) - { - for (label i = 0; i < nPerProc[proci]; i++) - { - patchFaceProcs[sampleI++] = proci; - } - } - } -} - - void Foam::mappedPatchBase::findSamples ( - const sampleMode mode, - const pointField& samples, - labelList& sampleProcs, + const globalIndex& patchGlobalIndex, + labelList& sampleGlobalPatchFaces, labelList& sampleIndices ) const { // Lookup the correct region const polyMesh& mesh = sampleMesh(); - // All the info for nearest. Construct to miss - List nearest(samples.size()); + // Gather the sample points into a single globally indexed list + List allPoints(patchGlobalIndex.size()); + { + List procSamplePoints(Pstream::nProcs()); + procSamplePoints[Pstream::myProcNo()] = this->samplePoints(); + Pstream::gatherList(procSamplePoints); + Pstream::scatterList(procSamplePoints); - switch (mode) + forAll(procSamplePoints, proci) + { + forAll(procSamplePoints[proci], procSamplei) + { + allPoints + [ + patchGlobalIndex.toGlobal(proci, procSamplei) + ] = procSamplePoints[proci][procSamplei]; + } + } + } + + // Nearest info + List> allNearest(patchGlobalIndex.size()); + + switch (mode_) { case NEARESTCELL: { @@ -163,82 +122,45 @@ void Foam::mappedPatchBase::findSamples { FatalErrorInFunction << "No need to supply a patch name when in " - << sampleModeNames_[mode] << " mode." << exit(FatalError); + << sampleModeNames_[mode_] << " mode." << exit(FatalError); } //- Note: face-diagonal decomposition const indexedOctree& tree = mesh.cellTree(); - forAll(samples, sampleI) + forAll(allPoints, alli) { - const point& sample = samples[sampleI]; + const point& p = allPoints[alli]; - label celli = tree.findInside(sample); + const label celli = tree.findInside(p); - if (celli == -1) - { - nearest[sampleI].second().first() = Foam::sqr(great); - nearest[sampleI].second().second() = Pstream::myProcNo(); - } - else + if (celli != -1) { const point& cc = mesh.cellCentres()[celli]; - nearest[sampleI].first() = pointIndexHit - ( - true, - cc, - celli - ); - nearest[sampleI].second().first() = magSqr(cc-sample); - nearest[sampleI].second().second() = Pstream::myProcNo(); + allNearest[alli].proci = Pstream::myProcNo(); + allNearest[alli].elementi = celli; + allNearest[alli].data = magSqr(cc - p); } } break; } - case NEARESTONLYCELL: - { - if (samplePatch_.size() && samplePatch_ != "none") - { - FatalErrorInFunction - << "No need to supply a patch name when in " - << sampleModeNames_[mode] << " mode." << exit(FatalError); - } - - //- Note: face-diagonal decomposition - const indexedOctree& tree = mesh.cellTree(); - - forAll(samples, sampleI) - { - const point& sample = samples[sampleI]; - - nearest[sampleI].first() = tree.findNearest(sample, sqr(great)); - nearest[sampleI].second().first() = magSqr - ( - nearest[sampleI].first().hitPoint() - -sample - ); - nearest[sampleI].second().second() = Pstream::myProcNo(); - } - break; - } - case NEARESTPATCHFACE: { const polyPatch& pp = samplePolyPatch(); if (pp.empty()) { - forAll(samples, sampleI) + forAll(allPoints, alli) { - nearest[sampleI].second().first() = Foam::sqr(great); - nearest[sampleI].second().second() = Pstream::myProcNo(); + allNearest[alli].proci = -1; + allNearest[alli].elementi = -1; + allNearest[alli].data = Foam::sqr(great); } } else { - // patch faces const labelList patchFaces(identity(pp.size()) + pp.start()); treeBoundBox patchBb @@ -260,30 +182,20 @@ void Foam::mappedPatchBase::findSamples 3.0 // duplicity ); - forAll(samples, sampleI) + forAll(allPoints, alli) { - const point& sample = samples[sampleI]; + const point& p = allPoints[alli]; - pointIndexHit& nearInfo = nearest[sampleI].first(); - nearInfo = boundaryTree.findNearest - ( - sample, - magSqr(patchBb.span()) - ); + const pointIndexHit pih = + boundaryTree.findNearest(p, magSqr(patchBb.span())); - if (!nearInfo.hit()) + if (pih.hit()) { - nearest[sampleI].second().first() = Foam::sqr(great); - nearest[sampleI].second().second() = - Pstream::myProcNo(); - } - else - { - point fc(pp[nearInfo.index()].centre(pp.points())); - nearInfo.setPoint(fc); - nearest[sampleI].second().first() = magSqr(fc-sample); - nearest[sampleI].second().second() = - Pstream::myProcNo(); + const point fc = pp[pih.index()].centre(pp.points()); + + allNearest[alli].proci = Pstream::myProcNo(); + allNearest[alli].elementi = pih.index(); + allNearest[alli].data = magSqr(fc - p); } } } @@ -296,36 +208,26 @@ void Foam::mappedPatchBase::findSamples { FatalErrorInFunction << "No need to supply a patch name when in " - << sampleModeNames_[mode] << " mode." << exit(FatalError); + << sampleModeNames_[mode_] << " mode." << exit(FatalError); } //- Note: face-diagonal decomposition const meshSearchMeshObject& meshSearchEngine = meshSearchMeshObject::New(mesh); - forAll(samples, sampleI) + forAll(allPoints, alli) { - const point& sample = samples[sampleI]; + const point& p = allPoints[alli]; - label facei = meshSearchEngine.findNearestFace(sample); + const label facei = meshSearchEngine.findNearestFace(p); - if (facei == -1) - { - nearest[sampleI].second().first() = Foam::sqr(great); - nearest[sampleI].second().second() = Pstream::myProcNo(); - } - else + if (facei != -1) { const point& fc = mesh.faceCentres()[facei]; - nearest[sampleI].first() = pointIndexHit - ( - true, - fc, - facei - ); - nearest[sampleI].second().first() = magSqr(fc-sample); - nearest[sampleI].second().second() = Pstream::myProcNo(); + allNearest[alli].proci = Pstream::myProcNo(); + allNearest[alli].elementi = facei; + allNearest[alli].data = magSqr(fc - p); } } break; @@ -333,56 +235,96 @@ void Foam::mappedPatchBase::findSamples case NEARESTPATCHFACEAMI: { - // nothing to do here - return; - } - - default: - { - FatalErrorInFunction - << "problem." << abort(FatalError); + break; } } // Find nearest. Combine on master. - Pstream::listCombineGather(nearest, nearestEqOp()); - Pstream::listCombineScatter(nearest); + Pstream::listCombineGather + ( + allNearest, + RemoteData::smallestEqOp() + ); + Pstream::listCombineScatter(allNearest); - if (debug) + // Determine the number of missing samples (no reduction necessary as this + // is computed from synchronised data) + label nNotFound = 0; + forAll(allPoints, alli) { - InfoInFunction - << "mesh " << sampleRegion() << " : " << endl; - - forAll(nearest, sampleI) + if (allNearest[alli].proci == -1) { - label proci = nearest[sampleI].second().second(); - label localI = nearest[sampleI].first().index(); - - Info<< " " << sampleI << " coord:"<< samples[sampleI] - << " found on processor:" << proci - << " in local cell/face/point:" << localI - << " with location:" << nearest[sampleI].first().rawPoint() - << endl; + nNotFound ++; } } - // Convert back into proc+local index - sampleProcs.setSize(samples.size()); - sampleIndices.setSize(samples.size()); - - forAll(nearest, sampleI) + // If any points were not found within cells then re-search for them using + // a nearest test, which should not fail. Warn that this is happening. If + // any points were not found for some other method, then fail. + if (nNotFound) { - if (!nearest[sampleI].first().hit()) + if (mode_ == NEARESTCELL) { - sampleProcs[sampleI] = -1; - sampleIndices[sampleI] = -1; + WarningInFunction + << "Did not find " << nNotFound + << " out of " << returnReduce(patch_.size(), sumOp