diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/derivedFvPatchFields/solidWallMixedTemperatureCoupled/solidWallMixedTemperatureCoupledFvPatchScalarField.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/derivedFvPatchFields/solidWallMixedTemperatureCoupled/solidWallMixedTemperatureCoupledFvPatchScalarField.H index 5a78299a7a..34c32b1abf 100644 --- a/applications/solvers/heatTransfer/chtMultiRegionFoam/derivedFvPatchFields/solidWallMixedTemperatureCoupled/solidWallMixedTemperatureCoupledFvPatchScalarField.H +++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/derivedFvPatchFields/solidWallMixedTemperatureCoupled/solidWallMixedTemperatureCoupledFvPatchScalarField.H @@ -103,8 +103,8 @@ public: const dictionary& ); - //- Construct by mapping given solidWallMixedTemperatureCoupledFvPatchScalarField - // onto a new patch + //- Construct by mapping given + // solidWallMixedTemperatureCoupledFvPatchScalarField onto a new patch solidWallMixedTemperatureCoupledFvPatchScalarField ( const solidWallMixedTemperatureCoupledFvPatchScalarField&, diff --git a/etc/controlDict b/etc/controlDict index 5cbe331fe5..65058af1a6 100644 --- a/etc/controlDict +++ b/etc/controlDict @@ -360,7 +360,7 @@ DebugSwitches diagonal 0; dictionary 0; dimensionSet 1; - directMapped 0; + directMappedBase 0; directMappedPatch 0; directMappedVelocityFlux 0; directionMixed 0; diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H index 4687c8a4b1..3ccf810476 100644 --- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H +++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H @@ -131,18 +131,36 @@ public: return constructSize_; } + //- Constructed data size + label& constructSize() + { + return constructSize_; + } + //- From subsetted data back to original data const labelListList& subMap() const { return subMap_; } + //- From subsetted data back to original data + labelListList& subMap() + { + return subMap_; + } + //- From subsetted data to new reconstructed data const labelListList& constructMap() const { return constructMap_; } + //- From subsetted data to new reconstructed data + labelListList& constructMap() + { + return constructMap_; + } + //- Calculate a schedule. See above. static List schedule ( diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files index 99f3085854..1ad24ecd16 100644 --- a/src/finiteVolume/Make/files +++ b/src/finiteVolume/Make/files @@ -24,6 +24,7 @@ $(constraintFvPatches)/processor/processorFvPatch.C derivedFvPatches = $(fvPatches)/derived $(derivedFvPatches)/wall/wallFvPatch.C $(derivedFvPatches)/directMapped/directMappedFvPatch.C +$(derivedFvPatches)/directMapped/directMappedWallFvPatch.C wallDist = fvMesh/wallDist $(wallDist)/wallPointYPlus/wallPointYPlus.C diff --git a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C index 5322cbf47b..0c3bf43408 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C @@ -25,7 +25,7 @@ License \*---------------------------------------------------------------------------*/ #include "directMappedFixedValueFvPatchField.H" -#include "directMappedFvPatch.H" +#include "directMappedPatchBase.H" #include "volFields.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -61,7 +61,7 @@ directMappedFixedValueFvPatchField::directMappedFixedValueFvPatchField setAverage_(ptf.setAverage_), average_(ptf.average_) { - if (!isType(this->patch())) + if (!isA(this->patch().patch())) { FatalErrorIn ( @@ -74,7 +74,7 @@ directMappedFixedValueFvPatchField::directMappedFixedValueFvPatchField " const fvPatchFieldMapper&\n" ")\n" ) << "\n patch type '" << p.type() - << "' not type '" << typeName << "'" + << "' not type '" << directMappedPatchBase::typeName << "'" << "\n for patch " << p.name() << " of field " << this->dimensionedInternalField().name() << " in file " << this->dimensionedInternalField().objectPath() @@ -95,7 +95,7 @@ directMappedFixedValueFvPatchField::directMappedFixedValueFvPatchField setAverage_(readBool(dict.lookup("setAverage"))), average_(pTraits(dict.lookup("average"))) { - if (!isType(this->patch())) + if (!isA(this->patch().patch())) { FatalErrorIn ( @@ -107,12 +107,19 @@ directMappedFixedValueFvPatchField::directMappedFixedValueFvPatchField " const dictionary& dict\n" ")\n" ) << "\n patch type '" << p.type() - << "' not type '" << typeName << "'" + << "' not type '" << directMappedPatchBase::typeName << "'" << "\n for patch " << p.name() << " of field " << this->dimensionedInternalField().name() << " in file " << this->dimensionedInternalField().objectPath() << exit(FatalError); } + + // Force calculation of schedule (uses parallel comms) + const directMappedPatchBase& mpp = refCast + ( + this->patch().patch() + ); + (void)mpp.map().schedule(); } @@ -143,70 +150,6 @@ directMappedFixedValueFvPatchField::directMappedFixedValueFvPatchField // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -template -void directMappedFixedValueFvPatchField::getNewValues -( - const directMappedPolyPatch& mpp, - const Field& sendValues, - Field& newValues -) const -{ - // Get the scheduling information - const List& schedule = mpp.schedule(); - const labelListList& sendLabels = mpp.sendLabels(); - const labelListList& receiveFaceLabels = mpp.receiveFaceLabels(); - - forAll(schedule, i) - { - const labelPair& twoProcs = schedule[i]; - label sendProc = twoProcs[0]; - label recvProc = twoProcs[1]; - - if (Pstream::myProcNo() == sendProc) - { - OPstream toProc(Pstream::scheduled, recvProc); - toProc<< UIndirectList(sendValues, sendLabels[recvProc])(); - } - else - { - // I am receiver. Receive from sendProc. - IPstream fromProc(Pstream::scheduled, sendProc); - - Field fromFld(fromProc); - - // Destination faces - const labelList& faceLabels = receiveFaceLabels[sendProc]; - - forAll(fromFld, i) - { - label patchFaceI = faceLabels[i]; - - newValues[patchFaceI] = fromFld[i]; - } - } - } - - // Do data from myself - { - UIndirectList fromFld - ( - sendValues, - sendLabels[Pstream::myProcNo()] - ); - - // Destination faces - const labelList& faceLabels = receiveFaceLabels[Pstream::myProcNo()]; - - forAll(fromFld, i) - { - label patchFaceI = faceLabels[i]; - - newValues[patchFaceI] = fromFld[i]; - } - } -} - - template void directMappedFixedValueFvPatchField::updateCoeffs() { @@ -215,65 +158,94 @@ void directMappedFixedValueFvPatchField::updateCoeffs() return; } - // Get the directMappedPolyPatch - const directMappedPolyPatch& mpp = refCast + typedef GeometricField fieldType; + + // Get the scheduling information from the directMappedPatchBase + const directMappedPatchBase& mpp = refCast ( directMappedFixedValueFvPatchField::patch().patch() ); + const mapDistribute& distMap = mpp.map(); + const fvMesh& nbrMesh = refCast(mpp.sampleMesh()); + const word& fldName = this->dimensionedInternalField().name(); - Field newValues(this->size()); + // Result of obtaining remote values + Field newValues; switch (mpp.mode()) { - case directMappedPolyPatch::NEARESTCELL: + case directMappedPatchBase::NEARESTCELL: { - getNewValues(mpp, this->internalField(), newValues); + if (mpp.sameRegion()) + { + newValues = this->internalField(); + } + else + { + newValues = nbrMesh.lookupObject + ( + fldName + ).internalField(); + } + mapDistribute::distribute + ( + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), + newValues + ); break; } - case directMappedPolyPatch::NEARESTPATCHFACE: + case directMappedPatchBase::NEARESTPATCHFACE: { - const label patchID = - this->patch().patch().boundaryMesh().findPatchID - ( - mpp.samplePatch() - ); - if (patchID < 0) + const label nbrPatchID = nbrMesh.boundaryMesh().findPatchID + ( + mpp.samplePatch() + ); + if (nbrPatchID < 0) { FatalErrorIn ( "void directMappedFixedValueFvPatchField::" "updateCoeffs()" )<< "Unable to find sample patch " << mpp.samplePatch() + << " in region " << mpp.sampleRegion() << " for patch " << this->patch().name() << nl << abort(FatalError); } - typedef GeometricField fieldType; - const word& fieldName = this->dimensionedInternalField().name(); - const fieldType& sendField = - this->db().objectRegistry::lookupObject(fieldName); - getNewValues(mpp, sendField.boundaryField()[patchID], newValues); + const fieldType& nbrField = nbrMesh.lookupObject + ( + fldName + ); + newValues = nbrField.boundaryField()[nbrPatchID]; + mapDistribute::distribute + ( + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), + newValues + ); break; } - case directMappedPolyPatch::NEARESTFACE: + case directMappedPatchBase::NEARESTFACE: { - typedef GeometricField fieldType; - const word& fieldName = this->dimensionedInternalField().name(); - const fieldType& sendField = - this->db().objectRegistry::lookupObject(fieldName); + Field allValues(nbrMesh.nFaces(), pTraits::zero); - Field allValues + const fieldType& nbrField = nbrMesh.lookupObject ( - this->patch().patch().boundaryMesh().mesh().nFaces(), - pTraits::zero + fldName ); - - forAll(sendField.boundaryField(), patchI) + forAll(nbrField.boundaryField(), patchI) { const fvPatchField& pf = - sendField.boundaryField()[patchI]; + nbrField.boundaryField()[patchI]; label faceStart = pf.patch().patch().start(); forAll(pf, faceI) @@ -282,9 +254,17 @@ void directMappedFixedValueFvPatchField::updateCoeffs() } } - getNewValues(mpp, allValues, newValues); + mapDistribute::distribute + ( + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), + allValues + ); - newValues = this->patch().patchSlice(newValues); + newValues = this->patch().patchSlice(allValues); break; } diff --git a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H index 8c8da590a8..2382b32db8 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H @@ -62,18 +62,6 @@ class directMappedFixedValueFvPatchField // setAverage_ is set true Type average_; - - // Private member functions - - // Helper function to return the new field values - void getNewValues - ( - const directMappedPolyPatch& mpp, - const Field& sendValues, - Field& newValues - ) const; - - public: //- Runtime type information diff --git a/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C index 92bf63e8c6..5ac329fe31 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C @@ -26,7 +26,7 @@ License #include "directMappedVelocityFluxFixedValueFvPatchField.H" #include "fvPatchFieldMapper.H" -#include "directMappedFvPatch.H" +#include "directMappedPatchBase.H" #include "volFields.H" #include "surfaceFields.H" #include "addToRunTimeSelectionTable.H" @@ -62,12 +62,12 @@ directMappedVelocityFluxFixedValueFvPatchField fixedValueFvPatchVectorField(ptf, p, iF, mapper), phiName_(ptf.phiName_) { - if (!isType(patch())) + if (!isType(this->patch().patch())) { FatalErrorIn ( "directMappedVelocityFluxFixedValueFvPatchField::" - "directMappedFixedValueFvPatchField\n" + "directMappedVelocityFluxFixedValueFvPatchField\n" "(\n" " const directMappedVelocityFluxFixedValueFvPatchField&,\n" " const fvPatch&,\n" @@ -75,7 +75,7 @@ directMappedVelocityFluxFixedValueFvPatchField " const fvPatchFieldMapper&\n" ")\n" ) << "\n patch type '" << p.type() - << "' not type '" << typeName << "'" + << "' not type '" << directMappedPatchBase::typeName << "'" << "\n for patch " << p.name() << " of field " << dimensionedInternalField().name() << " in file " << dimensionedInternalField().objectPath() @@ -95,24 +95,31 @@ directMappedVelocityFluxFixedValueFvPatchField fixedValueFvPatchVectorField(p, iF, dict), phiName_(dict.lookup("phi")) { - if (!isType(patch())) + if (!isType(this->patch().patch())) { FatalErrorIn ( "directMappedVelocityFluxFixedValueFvPatchField::" - "directMappedFixedValueFvPatchField\n" + "directMappedVelocityFluxFixedValueFvPatchField\n" "(\n" " const fvPatch& p,\n" " const DimensionedField& iF,\n" " const dictionary& dict\n" ")\n" ) << "\n patch type '" << p.type() - << "' not type '" << typeName << "'" + << "' not type '" << directMappedPatchBase::typeName << "'" << "\n for patch " << p.name() << " of field " << dimensionedInternalField().name() << " in file " << dimensionedInternalField().objectPath() << exit(FatalError); } + + // Force calculation of schedule (uses parallel comms) + const directMappedPolyPatch& mpp = refCast + ( + patch().patch() + ); + (void)mpp.map().schedule(); } @@ -139,85 +146,6 @@ directMappedVelocityFluxFixedValueFvPatchField {} -void directMappedVelocityFluxFixedValueFvPatchField::getNewValues -( - const directMappedPolyPatch& mpp, - const vectorField& sendUValues, - const scalarField& sendPhiValues, - vectorField& newUValues, - scalarField& newPhiValues -) const -{ - // Get the scheduling information - const List& schedule = mpp.schedule(); - const labelListList& sendLabels = mpp.sendLabels(); - const labelListList& receiveFaceLabels = mpp.receiveFaceLabels(); - - forAll(schedule, i) - { - const labelPair& twoProcs = schedule[i]; - label sendProc = twoProcs[0]; - label recvProc = twoProcs[1]; - - if (Pstream::myProcNo() == sendProc) - { - OPstream toProc(Pstream::scheduled, recvProc); - toProc<< UIndirectList(sendUValues, sendLabels[recvProc])(); - toProc<< UIndirectList - ( - sendPhiValues, - sendLabels[recvProc] - )(); - } - else - { - // I am receiver. Receive from sendProc. - IPstream fromProc(Pstream::scheduled, sendProc); - - vectorField fromUFld(fromProc); - scalarField fromPhiFld(fromProc); - - // Destination faces - const labelList& faceLabels = receiveFaceLabels[sendProc]; - - forAll(fromUFld, i) - { - label patchFaceI = faceLabels[i]; - - newUValues[patchFaceI] = fromUFld[i]; - newPhiValues[patchFaceI] = fromPhiFld[i]; - } - } - } - - // Do data from myself - { - UIndirectList fromUFld - ( - sendUValues, - sendLabels[Pstream::myProcNo()] - ); - - UIndirectList fromPhiFld - ( - sendPhiValues, - sendLabels[Pstream::myProcNo()] - ); - - // Destination faces - const labelList& faceLabels = receiveFaceLabels[Pstream::myProcNo()]; - - forAll(fromUFld, i) - { - label patchFaceI = faceLabels[i]; - - newUValues[patchFaceI] = fromUFld[i]; - newPhiValues[patchFaceI] = fromPhiFld[i]; - } - } -} - - // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void directMappedVelocityFluxFixedValueFvPatchField::updateCoeffs() @@ -227,37 +155,33 @@ void directMappedVelocityFluxFixedValueFvPatchField::updateCoeffs() return; } - // Get the directMappedPolyPatch - const directMappedPolyPatch& mpp = refCast + // Get the directMappedPatchBase + const directMappedPatchBase& mpp = refCast ( directMappedVelocityFluxFixedValueFvPatchField::patch().patch() ); - - vectorField newUValues(size()); - scalarField newPhiValues(size()); - + const mapDistribute& distMap = mpp.map(); + const fvMesh& nbrMesh = refCast(mpp.sampleMesh()); const word& fieldName = dimensionedInternalField().name(); - const volVectorField& UField = db().lookupObject(fieldName); + const volVectorField& UField = nbrMesh.lookupObject + ( + fieldName + ); surfaceScalarField& phiField = const_cast ( - db().lookupObject(phiName_) + nbrMesh.lookupObject(phiName_) ); + vectorField newUValues; + scalarField newPhiValues; + switch (mpp.mode()) { case directMappedPolyPatch::NEARESTFACE: { - vectorField allUValues - ( - patch().patch().boundaryMesh().mesh().nFaces(), - vector::zero - ); - scalarField allPhiValues - ( - patch().patch().boundaryMesh().mesh().nFaces(), - 0.0 - ); + vectorField allUValues(nbrMesh.nFaces(), vector::zero); + scalarField allPhiValues(nbrMesh.nFaces(), 0.0); forAll(UField.boundaryField(), patchI) { @@ -273,34 +197,58 @@ void directMappedVelocityFluxFixedValueFvPatchField::updateCoeffs() } } - getNewValues + mapDistribute::distribute ( - mpp, - allUValues, - allPhiValues, - newUValues, + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), + allUValues + ); + newUValues = patch().patchSlice(newUValues); + + mapDistribute::distribute + ( + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), newPhiValues ); - - newUValues = patch().patchSlice(newUValues); newPhiValues = patch().patchSlice(newPhiValues); break; } case directMappedPolyPatch::NEARESTPATCHFACE: { - const label patchID = - patch().patch().boundaryMesh().findPatchID - ( - mpp.samplePatch() - ); - - getNewValues + const label nbrPatchID = nbrMesh.boundaryMesh().findPatchID ( - mpp, - UField.boundaryField()[patchID], - phiField.boundaryField()[patchID], - newUValues, + mpp.samplePatch() + ); + + newUValues = UField.boundaryField()[nbrPatchID]; + + mapDistribute::distribute + ( + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), + newUValues + ); + + newPhiValues = phiField.boundaryField()[nbrPatchID]; + + mapDistribute::distribute + ( + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), newPhiValues ); diff --git a/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.H index b92372eb3a..6ec34d62e1 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.H @@ -57,20 +57,6 @@ class directMappedVelocityFluxFixedValueFvPatchField //- Name of flux field word phiName_; - - // Private member functions - - // Helper function to return the new field values - void getNewValues - ( - const directMappedPolyPatch& mpp, - const vectorField& sendUValues, - const scalarField& sendPhiValues, - vectorField& newUValues, - scalarField& newPhiValues - ) const; - - public: //- Runtime type information diff --git a/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.C b/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.C new file mode 100644 index 0000000000..413d5f86c2 --- /dev/null +++ b/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.C @@ -0,0 +1,38 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "directMappedWallFvPatch.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(directMappedWallFvPatch, 0); + addToRunTimeSelectionTable(fvPatch, directMappedWallFvPatch, polyPatch); +} + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.H b/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.H new file mode 100644 index 0000000000..4be7eed592 --- /dev/null +++ b/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.H @@ -0,0 +1,84 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::directMappedWallFvPatch + +Description + Foam::directMappedWallFvPatch + +SourceFiles + directMappedWallFvPatch.C + +\*---------------------------------------------------------------------------*/ + +#ifndef directMappedWallFvPatch_H +#define directMappedWallFvPatch_H + +#include "fvPatch.H" +#include "directMappedWallPolyPatch.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class directMappedWallFvPatch Declaration +\*---------------------------------------------------------------------------*/ + +class directMappedWallFvPatch +: + public fvPatch +{ + +public: + + //- Runtime type information + TypeName(directMappedWallPolyPatch::typeName_()); + + + // Constructors + + //- Construct from components + directMappedWallFvPatch + ( + const polyPatch& patch, + const fvBoundaryMesh& bm + ) + : + fvPatch(patch, bm) + {} +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files index 9f849c5894..d5133cb33d 100644 --- a/src/meshTools/Make/files +++ b/src/meshTools/Make/files @@ -141,7 +141,10 @@ triSurface/triSurfaceTools/geompack/geompack.C twoDPointCorrector/twoDPointCorrector.C +directMapped/directMappedPolyPatch/directMappedPatchBase.C directMapped/directMappedPolyPatch/directMappedPolyPatch.C +directMapped/directMappedPolyPatch/directMappedWallPolyPatch.C directMapped/directMappedPointPatch/directMappedPointPatch.C +directMapped/directMappedPointPatch/directMappedWallPointPatch.C LIB = $(FOAM_LIBBIN)/libmeshTools diff --git a/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.C b/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.C new file mode 100644 index 0000000000..4633d73ecf --- /dev/null +++ b/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.C @@ -0,0 +1,52 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "directMappedWallPointPatch.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +defineTypeNameAndDebug(directMappedWallPointPatch, 0); + +// Add the patch constructor functions to the hash tables +addToRunTimeSelectionTable +( + facePointPatch, + directMappedWallPointPatch, + polyPatch +); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.H b/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.H new file mode 100644 index 0000000000..28bb877105 --- /dev/null +++ b/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.H @@ -0,0 +1,84 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::directMappedWallPointPatch + +Description + DirectMapped patch. + +SourceFiles + directMappedWallPointPatch.C + +\*---------------------------------------------------------------------------*/ + +#ifndef directMappedWallPointPatch_H +#define directMappedWallPointPatch_H + +#include "facePointPatch.H" +#include "directMappedWallPolyPatch.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class directMappedWallPointPatch Declaration +\*---------------------------------------------------------------------------*/ + +class directMappedWallPointPatch +: + public facePointPatch +{ + +public: + + //- Runtime type information + TypeName(directMappedWallPolyPatch::typeName_()); + + + // Constructors + + //- Construct from polyPatch + directMappedWallPointPatch + ( + const polyPatch& patch, + const pointBoundaryMesh& bm + ) + : + facePointPatch(patch, bm) + {} +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.C b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.C new file mode 100644 index 0000000000..4852a54c2e --- /dev/null +++ b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.C @@ -0,0 +1,656 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "directMappedPatchBase.H" +#include "addToRunTimeSelectionTable.H" +#include "ListListOps.H" +#include "meshSearch.H" +#include "meshTools.H" +#include "OFstream.H" +#include "Random.H" +#include "treeDataFace.H" +#include "indexedOctree.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(directMappedPatchBase, 0); + + template<> + const char* NamedEnum::names[] = + { + "nearestCell", + "nearestPatchFace", + "nearestFace" + }; + + const NamedEnum + directMappedPatchBase::sampleModeNames_; +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::directMappedPatchBase::collectSamples +( + pointField& samples, + labelList& patchFaceProcs, + labelList& patchFaces, + pointField& patchFc +) const +{ + + // Collect all sample points and the faces they come from. + List globalFc(Pstream::nProcs()); + List globalSamples(Pstream::nProcs()); + labelListList globalFaces(Pstream::nProcs()); + + globalFc[Pstream::myProcNo()] = patch_.faceCentres(); + globalSamples[Pstream::myProcNo()] = globalFc[Pstream::myProcNo()]+offset_; + globalFaces[Pstream::myProcNo()] = identity(patch_.size()); + + // Distribute to all processors + Pstream::gatherList(globalSamples); + Pstream::scatterList(globalSamples); + Pstream::gatherList(globalFaces); + Pstream::scatterList(globalFaces); + Pstream::gatherList(globalFc); + Pstream::scatterList(globalFc); + + // Rework into straight list + samples = ListListOps::combine + ( + globalSamples, + accessOp() + ); + patchFaces = ListListOps::combine + ( + globalFaces, + accessOp() + ); + patchFc = ListListOps::combine + ( + globalFc, + accessOp() + ); + + patchFaceProcs.setSize(patchFaces.size()); + labelList nPerProc + ( + ListListOps::subSizes + ( + globalFaces, + accessOp() + ) + ); + label sampleI = 0; + forAll(nPerProc, procI) + { + for (label i = 0; i < nPerProc[procI]; i++) + { + patchFaceProcs[sampleI++] = procI; + } + } +} + + +// Find the processor/cell containing the samples. Does not account +// for samples being found in two processors. +void Foam::directMappedPatchBase::findSamples +( + const pointField& samples, + labelList& sampleProcs, + labelList& sampleIndices, + pointField& sampleLocations +) const +{ + // Lookup the correct region + const polyMesh& mesh = sampleMesh(); + + // All the info for nearest. Construct to miss + List nearest(samples.size()); + + switch (mode_) + { + case NEARESTCELL: + { + if (samplePatch_.size() && samplePatch_ != "none") + { + FatalErrorIn + ( + "directMappedPatchBase::findSamples(const pointField&," + " labelList&, labelList&, pointField&) const" + ) << "No need to supply a patch name when in " + << sampleModeNames_[mode_] << " mode." << exit(FatalError); + } + + // Octree based search engine + meshSearch meshSearchEngine(mesh, false); + + forAll(samples, sampleI) + { + const point& sample = samples[sampleI]; + + label cellI = meshSearchEngine.findCell(sample); + + if (cellI == -1) + { + nearest[sampleI].second().first() = Foam::sqr(GREAT); + nearest[sampleI].second().second() = Pstream::myProcNo(); + } + else + { + 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(); + } + } + break; + } + + case NEARESTPATCHFACE: + { + Random rndGen(123456); + + const polyPatch& pp = samplePolyPatch(); + + if (pp.empty()) + { + forAll(samples, sampleI) + { + nearest[sampleI].second().first() = Foam::sqr(GREAT); + nearest[sampleI].second().second() = Pstream::myProcNo(); + } + } + else + { + // patch faces + const labelList patchFaces(identity(pp.size()) + pp.start()); + + treeBoundBox patchBb + ( + treeBoundBox(pp.points(), pp.meshPoints()).extend + ( + rndGen, + 1E-4 + ) + ); + patchBb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + patchBb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + + indexedOctree boundaryTree + ( + treeDataFace // all information needed to search faces + ( + false, // do not cache bb + mesh, + patchFaces // boundary faces only + ), + patchBb, // overall search domain + 8, // maxLevel + 10, // leafsize + 3.0 // duplicity + ); + + forAll(samples, sampleI) + { + const point& sample = samples[sampleI]; + + pointIndexHit& nearInfo = nearest[sampleI].first(); + nearInfo = boundaryTree.findNearest + ( + sample, + magSqr(patchBb.span()) + ); + + if (!nearInfo.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(); + } + } + } + break; + } + + case NEARESTFACE: + { + if (samplePatch_.size() && samplePatch_ != "none") + { + FatalErrorIn + ( + "directMappedPatchBase::findSamples(const pointField&," + " labelList&, labelList&, pointField&) const" + ) << "No need to supply a patch name when in " + << sampleModeNames_[mode_] << " mode." << exit(FatalError); + } + + // Octree based search engine + meshSearch meshSearchEngine(mesh, false); + + forAll(samples, sampleI) + { + const point& sample = samples[sampleI]; + + label faceI = meshSearchEngine.findNearestFace(sample); + + if (faceI == -1) + { + nearest[sampleI].second().first() = Foam::sqr(GREAT); + nearest[sampleI].second().second() = Pstream::myProcNo(); + } + else + { + 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(); + } + } + break; + } + + default: + { + FatalErrorIn("directMappedPatchBase::findSamples(..)") + << "problem." << abort(FatalError); + } + } + + + // Find nearest. + Pstream::listCombineGather(nearest, nearestEqOp()); + Pstream::listCombineScatter(nearest); + + if (debug) + { + Info<< "directMappedPatchBase::findSamples on mesh " << sampleRegion_ + << " : " << endl; + forAll(nearest, sampleI) + { + 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:" << localI + << " with cc:" << nearest[sampleI].first().rawPoint() << endl; + } + } + + // Check for samples not being found + forAll(nearest, sampleI) + { + if (!nearest[sampleI].first().hit()) + { + FatalErrorIn + ( + "directMappedPatchBase::findSamples" + "(const pointField&, labelList&" + ", labelList&, pointField&)" + ) << "Did not find sample " << samples[sampleI] + << " on any processor of region" << sampleRegion_ + << exit(FatalError); + } + } + + + // Convert back into proc+local index + sampleProcs.setSize(samples.size()); + sampleIndices.setSize(samples.size()); + sampleLocations.setSize(samples.size()); + + forAll(nearest, sampleI) + { + sampleProcs[sampleI] = nearest[sampleI].second().second(); + sampleIndices[sampleI] = nearest[sampleI].first().index(); + sampleLocations[sampleI] = nearest[sampleI].first().hitPoint(); + } +} + + +void Foam::directMappedPatchBase::calcMapping() const +{ + if (mapPtr_.valid()) + { + FatalErrorIn("directMappedPatchBase::calcMapping() const") + << "Mapping already calculated" << exit(FatalError); + } + + if + ( + offset_ == vector::zero + && sampleRegion_ == patch_.boundaryMesh().mesh().name() + ) + { + FatalErrorIn("directMappedPatchBase::calcMapping() const") + << "Invalid offset " << offset_ << endl + << "Offset is the vector added to the patch face centres to" + << " find the cell supplying the data." + << exit(FatalError); + } + + + // Get global list of all samples and the processor and face they come from. + pointField samples; + labelList patchFaceProcs; + labelList patchFaces; + pointField patchFc; + collectSamples(samples, patchFaceProcs, patchFaces, patchFc); + + // Find processor and cell/face samples are in and actual location. + labelList sampleProcs; + labelList sampleIndices; + pointField sampleLocations; + findSamples(samples, sampleProcs, sampleIndices, sampleLocations); + + + // Now we have all the data we need: + // - where sample originates from (so destination when mapping): + // patchFaces, patchFaceProcs. + // - cell/face sample is in (so source when mapping) + // sampleIndices, sampleProcs. + + //forAll(samples, i) + //{ + // Info<< i << " need data in region " + // << patch_.boundaryMesh().mesh().name() + // << " for proc:" << patchFaceProcs[i] + // << " face:" << patchFaces[i] + // << " at:" << patchFc[i] << endl + // << "Found data in region " << sampleRegion_ + // << " at proc:" << sampleProcs[i] + // << " face:" << sampleIndices[i] + // << " at:" << sampleLocations[i] + // << nl << endl; + //} + + + + if (debug && Pstream::master()) + { + OFstream str + ( + patch_.boundaryMesh().mesh().time().path() + / patch_.name() + + "_directMapped.obj" + ); + Pout<< "Dumping mapping as lines from patch faceCentres to" + << " sampled cellCentres to file " << str.name() << endl; + + label vertI = 0; + + forAll(patchFc, i) + { + meshTools::writeOBJ(str, patchFc[i]); + vertI++; + meshTools::writeOBJ(str, sampleLocations[i]); + vertI++; + str << "l " << vertI-1 << ' ' << vertI << nl; + } + } + + + // Check that actual offset vector (sampleLocations - patchFc) is more or + // less constant. + if (Pstream::master()) + { + const scalarField magOffset(mag(sampleLocations - patchFc)); + const scalar avgOffset(average(magOffset)); + + forAll(magOffset, sampleI) + { + if (mag(magOffset[sampleI]-avgOffset) > 0.001*avgOffset) + { + WarningIn("directMappedPatchBase::calcMapping() const") + << "The actual cell centres picked up using offset " + << offset_ << " are not" << endl + << " on a single plane." + << " This might give numerical problems." << endl + << " At patchface " << patchFc[sampleI] + << " the sampled cell " << sampleLocations[sampleI] << endl + << " is not on a plane " << avgOffset + << " offset from the patch." << endl + << " You might want to shift your plane offset." + << " Set the debug flag to get a dump of sampled cells." + << endl; + break; + } + } + } + + + // Determine schedule. + mapPtr_.reset(new mapDistribute(sampleProcs, patchFaceProcs)); + + // Rework the schedule from indices into samples to cell data to send, + // face data to receive. + + labelListList& subMap = mapPtr_().subMap(); + labelListList& constructMap = mapPtr_().constructMap(); + + forAll(subMap, procI) + { + subMap[procI] = UIndirectList