From c7ccc2dee95131e2e225320a5ecb7958ca5dd55f Mon Sep 17 00:00:00 2001 From: Will Bainbridge Date: Thu, 18 Aug 2022 16:23:16 +0100 Subject: [PATCH] mappedPatchBase: Fixed mapping with interpolation Mapping with interpolation now behaves correctly when a single cell maps to multiple faces. In addition, the mapping structure is more compact and no longer results in copies being made of entire internal fields. This has been achieved by rewriting the mapping strategy in mappedPatchBase so that it maps from a reduced set of sampling locations to the patch faces, rather than directly from the cells/faces to the patch faces. This is more efficient, but it also permits multiple sampling locations to be sent to a single cell/face. Values can then be interpolated to these points before being sent back to the patch faces. Previously a single cell/face could only be sent a single location onto which to interpolate; typically that of the first associated patch face. The resulting interpolated value was then sent back to all associated patch faces. This meant that some (potentially most) patch faces did receive a value interpolated to the correct position. --- .../polyDistributionMap/distributionMapBase.C | 255 ++++---- .../primitives/RemoteData/RemoteData.H | 169 ++++++ .../primitives/RemoteData/RemoteDataI.H | 150 +++++ .../thermalBaffle1DFvPatchScalarField.C | 19 +- ...tureCoupledBaffleMixedFvPatchScalarField.C | 41 +- ...eratureRadCoupledMixedFvPatchScalarField.C | 54 +- .../mappedField/mappedPatchFieldBase.C | 75 ++- .../mappedFixedInternalValueFvPatchField.C | 9 +- .../mappedFlowRateFvPatchVectorField.C | 14 +- ...mappedVelocityFluxFixedValueFvPatchField.C | 16 +- .../SurfaceFilmModel/SurfaceFilmModel.C | 4 +- .../SurfaceFilmModel/SurfaceFilmModel.H | 12 +- .../ThermoSurfaceFilm/ThermoSurfaceFilm.H | 6 +- .../mappedPolyPatch/mappedPatchBase.C | 574 +++++++----------- .../mappedPolyPatch/mappedPatchBase.H | 98 ++- .../mappedPolyPatch/mappedPatchBaseI.H | 28 +- .../mappedPatchBaseTemplates.C | 127 ++-- .../mappedPolyPatch/mappedPolyPatch.H | 4 - .../mappedPolyPatch/mappedWallPolyPatch.H | 4 - .../faceSources/regionToFace/regionToFace.C | 41 +- .../radiationCoupledBase.C | 20 +- .../radiationCoupledBase.H | 2 +- .../regionModel/regionModel/regionModel.H | 6 +- .../regionModel/regionModelTemplates.C | 40 +- src/sampling/probes/patchProbes.C | 48 +- .../boundaryPoints/boundaryPoints.C | 64 +- .../sampledPatchInternalFieldTemplates.C | 79 ++- ...ableBaffleMassFractionFvPatchScalarField.C | 32 +- 28 files changed, 1011 insertions(+), 980 deletions(-) create mode 100644 src/OpenFOAM/primitives/RemoteData/RemoteData.H create mode 100644 src/OpenFOAM/primitives/RemoteData/RemoteDataI.H 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