diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files index 2d5186a550..6789ff84f6 100644 --- a/src/finiteVolume/Make/files +++ b/src/finiteVolume/Make/files @@ -69,6 +69,7 @@ $(constraintFvPatchFields)/wedge/wedgeFvPatchScalarField.C derivedFvPatchFields = $(fvPatchFields)/derived $(derivedFvPatchFields)/advective/advectiveFvPatchFields.C $(derivedFvPatchFields)/directMappedFixedValue/directMappedFixedValueFvPatchFields.C +$(derivedFvPatchFields)/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C $(derivedFvPatchFields)/fan/fanFvPatchFields.C $(derivedFvPatchFields)/fixedFluxBuoyantPressure/fixedFluxBuoyantPressureFvPatchScalarField.C $(derivedFvPatchFields)/fixedFluxPressure/fixedFluxPressureFvPatchScalarField.C diff --git a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C index 6f48d62c76..279e72a0c5 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C @@ -144,59 +144,18 @@ directMappedFixedValueFvPatchField::directMappedFixedValueFvPatchField // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template -void directMappedFixedValueFvPatchField::updateCoeffs() +void directMappedFixedValueFvPatchField::getNewValues +( + const directMappedPolyPatch& mpp, + const Field& sendValues, + Field& newValues +) const { - if (this->updated()) - { - return; - } - - // Get the directMappedPolyPatch - const directMappedPolyPatch& mpp = refCast - ( - directMappedFixedValueFvPatchField::patch().patch() - ); - // Get the scheduling information const List& schedule = mpp.schedule(); const labelListList& sendLabels = mpp.sendLabels(); const labelListList& receiveFaceLabels = mpp.receiveFaceLabels(); - - Field newValues(this->size()); - Field sendValues(this->size()); - - switch(mpp.mode()) - { - case directMappedPolyPatch::NEARESTCELL: - { - sendValues = this->internalField(); - break; - } - case directMappedPolyPatch::NEARESTPATCHFACE: - { - const label patchID = - this->patch().patch().boundaryMesh().findPatchID - ( - mpp.samplePatch() - ); - typedef GeometricField fieldType; - const word& fieldName = this->dimensionedInternalField().name(); - const fieldType& sendField = - this->db().objectRegistry::lookupObject(fieldName); - sendValues = sendField.boundaryField()[patchID]; - break; - } - default: - { - FatalErrorIn - ( - "directMappedFixedValueFvPatchField::updateCoeffs()" - )<< "patch can only be used in NEARESTCELL or NEARESTPATCHFACE " - << "mode" << nl << abort(FatalError); - } - } - forAll(schedule, i) { const labelPair& twoProcs = schedule[i]; @@ -205,13 +164,13 @@ void directMappedFixedValueFvPatchField::updateCoeffs() if (Pstream::myProcNo() == sendProc) { - OPstream toProc(Pstream::blocking, recvProc); + OPstream toProc(Pstream::scheduled, recvProc); toProc<< IndirectList(sendValues, sendLabels[recvProc])(); } else { // I am receiver. Receive from sendProc. - IPstream fromProc(Pstream::blocking, sendProc); + IPstream fromProc(Pstream::scheduled, sendProc); Field fromFld(fromProc); @@ -241,6 +200,89 @@ void directMappedFixedValueFvPatchField::updateCoeffs() newValues[patchFaceI] = fromFld[i]; } } +} + + +template +void directMappedFixedValueFvPatchField::updateCoeffs() +{ + if (this->updated()) + { + return; + } + + // Get the directMappedPolyPatch + const directMappedPolyPatch& mpp = refCast + ( + directMappedFixedValueFvPatchField::patch().patch() + ); + + Field newValues(this->size()); + + switch (mpp.mode()) + { + case directMappedPolyPatch::NEARESTCELL: + { + getNewValues(mpp, this->internalField(), newValues); + + break; + } + case directMappedPolyPatch::NEARESTPATCHFACE: + { + const label patchID = + this->patch().patch().boundaryMesh().findPatchID + ( + mpp.samplePatch() + ); + typedef GeometricField fieldType; + const word& fieldName = this->dimensionedInternalField().name(); + const fieldType& sendField = + this->db().objectRegistry::lookupObject(fieldName); + + getNewValues(mpp, sendField.boundaryField()[patchID], newValues); + + break; + } + case directMappedPolyPatch::NEARESTFACE: + { + typedef GeometricField fieldType; + const word& fieldName = this->dimensionedInternalField().name(); + const fieldType& sendField = + this->db().objectRegistry::lookupObject(fieldName); + + Field allValues + ( + this->patch().patch().boundaryMesh().mesh().nFaces(), + pTraits::zero + ); + + forAll(sendField.boundaryField(), patchI) + { + const fvPatchField& pf = + sendField.boundaryField()[patchI]; + label faceStart = pf.patch().patch().start(); + + forAll(pf, faceI) + { + allValues[faceStart++] = pf[faceI]; + } + } + + getNewValues(mpp, allValues, newValues); + + newValues = this->patch().patchSlice(newValues); + + break; + } + default: + { + FatalErrorIn + ( + "directMappedFixedValueFvPatchField::updateCoeffs()" + )<< "Unknown sampling mode: " << mpp.mode() + << nl << abort(FatalError); + } + } if (setAverage_) { diff --git a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H index 4793c841d4..c3ad1cb662 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H @@ -63,6 +63,17 @@ class directMappedFixedValueFvPatchField 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 new file mode 100644 index 0000000000..e77e698533 --- /dev/null +++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C @@ -0,0 +1,345 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2008 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 "directMappedVelocityFluxFixedValueFvPatchField.H" +#include "fvPatchFieldMapper.H" +#include "directMappedFvPatch.H" +#include "volFields.H" +#include "surfaceFields.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +directMappedVelocityFluxFixedValueFvPatchField:: +directMappedVelocityFluxFixedValueFvPatchField +( + const fvPatch& p, + const DimensionedField& iF +) +: + fixedValueFvPatchVectorField(p, iF), + phiName_("undefinedPhi") +{} + + +directMappedVelocityFluxFixedValueFvPatchField:: +directMappedVelocityFluxFixedValueFvPatchField +( + const directMappedVelocityFluxFixedValueFvPatchField& ptf, + const fvPatch& p, + const DimensionedField& iF, + const fvPatchFieldMapper& mapper +) +: + fixedValueFvPatchVectorField(ptf, p, iF, mapper), + phiName_(ptf.phiName_) +{ + if (!isType(patch())) + { + FatalErrorIn + ( + "directMappedVelocityFluxFixedValueFvPatchField::" + "directMappedFixedValueFvPatchField\n" + "(\n" + " const directMappedVelocityFluxFixedValueFvPatchField&,\n" + " const fvPatch&,\n" + " const DimensionedField&,\n" + " const fvPatchFieldMapper&\n" + ")\n" + ) << "\n patch type '" << p.type() + << "' not type '" << typeName << "'" + << "\n for patch " << p.name() + << " of field " << dimensionedInternalField().name() + << " in file " << dimensionedInternalField().objectPath() + << exit(FatalError); + } +} + + +directMappedVelocityFluxFixedValueFvPatchField:: +directMappedVelocityFluxFixedValueFvPatchField +( + const fvPatch& p, + const DimensionedField& iF, + const dictionary& dict +) +: + fixedValueFvPatchVectorField(p, iF, dict), + phiName_(dict.lookup("phi")) +{ + if (!isType(patch())) + { + FatalErrorIn + ( + "directMappedVelocityFluxFixedValueFvPatchField::" + "directMappedFixedValueFvPatchField\n" + "(\n" + " const fvPatch& p,\n" + " const DimensionedField& iF,\n" + " const dictionary& dict\n" + ")\n" + ) << "\n patch type '" << p.type() + << "' not type '" << typeName << "'" + << "\n for patch " << p.name() + << " of field " << dimensionedInternalField().name() + << " in file " << dimensionedInternalField().objectPath() + << exit(FatalError); + } +} + + +directMappedVelocityFluxFixedValueFvPatchField:: +directMappedVelocityFluxFixedValueFvPatchField +( + const directMappedVelocityFluxFixedValueFvPatchField& ptf +) +: + fixedValueFvPatchVectorField(ptf), + phiName_(ptf.phiName_) +{} + + +directMappedVelocityFluxFixedValueFvPatchField:: +directMappedVelocityFluxFixedValueFvPatchField +( + const directMappedVelocityFluxFixedValueFvPatchField& ptf, + const DimensionedField& iF +) +: + fixedValueFvPatchVectorField(ptf, iF), + phiName_(ptf.phiName_) +{} + + +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<< IndirectList(sendUValues, sendLabels[recvProc])(); + toProc<< IndirectList + ( + 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 + { + IndirectList fromUFld + ( + sendUValues, + sendLabels[Pstream::myProcNo()] + ); + + IndirectList 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() +{ + if (updated()) + { + return; + } + + // Get the directMappedPolyPatch + const directMappedPolyPatch& mpp = refCast + ( + directMappedVelocityFluxFixedValueFvPatchField::patch().patch() + ); + + vectorField newUValues(size()); + scalarField newPhiValues(size()); + + const word& fieldName = dimensionedInternalField().name(); + const volVectorField& UField = db().lookupObject(fieldName); + surfaceScalarField& phiField = + const_cast + ( + db().lookupObject(phiName_) + ); + + switch (mpp.mode()) + { + case directMappedPolyPatch::NEARESTFACE: + { + vectorField allUValues + ( + patch().patch().boundaryMesh().mesh().nFaces(), + vector::zero + ); + scalarField allPhiValues + ( + patch().patch().boundaryMesh().mesh().nFaces(), + 0.0 + ); + + forAll(UField.boundaryField(), patchI) + { + const fvPatchVectorField& Upf = UField.boundaryField()[patchI]; + const scalarField& phipf = phiField.boundaryField()[patchI]; + + label faceStart = Upf.patch().patch().start(); + + forAll(Upf, faceI) + { + allUValues[faceStart++] = Upf[faceI]; + allPhiValues[faceStart] = phipf[faceI]; + } + } + + getNewValues + ( + mpp, + allUValues, + allPhiValues, + newUValues, + newPhiValues + ); + + newUValues = patch().patchSlice(newUValues); + newPhiValues = patch().patchSlice(newPhiValues); + + break; + } + case directMappedPolyPatch::NEARESTPATCHFACE: + { + const label patchID = + patch().patch().boundaryMesh().findPatchID + ( + mpp.samplePatch() + ); + + getNewValues + ( + mpp, + UField.boundaryField()[patchID], + phiField.boundaryField()[patchID], + newUValues, + newPhiValues + ); + + break; + } + default: + { + FatalErrorIn + ( + "directMappedVelocityFluxFixedValueFvPatchField::updateCoeffs()" + )<< "patch can only be used in NEARESTPATCHFACE or NEARESTFACE " + << "mode" << nl << abort(FatalError); + } + } + + operator==(newUValues); + phiField.boundaryField()[patch().index()] == newPhiValues; + + fixedValueFvPatchVectorField::updateCoeffs(); +} + + +void directMappedVelocityFluxFixedValueFvPatchField::write(Ostream& os) const +{ + fvPatchVectorField::write(os); + os.writeKeyword("phi") << phiName_ << token::END_STATEMENT << nl; + this->writeEntry("value", os); +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +makePatchTypeField +( + fvPatchVectorField, + directMappedVelocityFluxFixedValueFvPatchField +); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.H new file mode 100644 index 0000000000..c5a1818952 --- /dev/null +++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.H @@ -0,0 +1,163 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2008 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::directMappedVelocityFluxFixedValueFvPatchField + +Description + Recycles the velocity and flux at a patch to this patch + +SourceFiles + directMappedVelocityFluxFixedValueFvPatchField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef directMappedVelocityFluxFixedValueFvPatchField_H +#define directMappedVelocityFluxFixedValueFvPatchField_H + +#include "fixedValueFvPatchFields.H" +#include "directMappedFvPatch.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class directMappedVelocityFluxFixedValueFvPatch Declaration +\*---------------------------------------------------------------------------*/ + +class directMappedVelocityFluxFixedValueFvPatchField +: + public fixedValueFvPatchVectorField +{ + // Private data + + //- 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 + TypeName("directMappedVelocityFlux"); + + + // Constructors + + //- Construct from patch and internal field + directMappedVelocityFluxFixedValueFvPatchField + ( + const fvPatch&, + const DimensionedField& + ); + + //- Construct from patch, internal field and dictionary + directMappedVelocityFluxFixedValueFvPatchField + ( + const fvPatch&, + const DimensionedField&, + const dictionary& + ); + + //- Construct by mapping given + // directMappedVelocityFluxFixedValueFvPatchField + // onto a new patch + directMappedVelocityFluxFixedValueFvPatchField + ( + const directMappedVelocityFluxFixedValueFvPatchField&, + const fvPatch&, + const DimensionedField&, + const fvPatchFieldMapper& + ); + + //- Construct as copy + directMappedVelocityFluxFixedValueFvPatchField + ( + const directMappedVelocityFluxFixedValueFvPatchField& + ); + + //- Construct and return a clone + virtual tmp clone() const + { + return tmp + ( + new directMappedVelocityFluxFixedValueFvPatchField(*this) + ); + } + + //- Construct as copy setting internal field reference + directMappedVelocityFluxFixedValueFvPatchField + ( + const directMappedVelocityFluxFixedValueFvPatchField&, + const DimensionedField& + ); + + //- Construct and return a clone setting internal field reference + virtual tmp clone + ( + const DimensionedField& iF + ) const + { + return tmp + ( + new directMappedVelocityFluxFixedValueFvPatchField(*this, iF) + ); + } + + + // Member functions + + // Evaluation functions + + //- Update the coefficients associated with the patch field + virtual void updateCoeffs(); + + //- Write + virtual void write(Ostream&) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.C b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.C index 1c3ab42ffb..03c8d9a160 100644 --- a/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.C +++ b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.C @@ -196,57 +196,70 @@ void Foam::directMappedPolyPatch::findSamples const polyPatch& pp = boundaryMesh()[patchI]; - // patch faces - const labelList patchFaces(identity(pp.size()) + pp.start()); - - const treeBoundBox patchBb - ( - treeBoundBox(pp.points(), pp.meshPoints()).extend - ( - rndGen, - 1E-4 - ) - ); - - autoPtr > boundaryTree - ( - new indexedOctree - ( - 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) + if (pp.size() == 0) { - const point& sample = samples[sampleI]; - - pointIndexHit& nearInfo = nearest[sampleI].first(); - nearInfo = boundaryTree().findNearest - ( - sample, - magSqr(patchBb.max()-patchBb.min()) - ); - - if (!nearInfo.hit()) + forAll(samples, sampleI) { nearest[sampleI].second().first() = Foam::sqr(GREAT); nearest[sampleI].second().second() = Pstream::myProcNo(); } - else + } + else + { + // patch faces + const labelList patchFaces(identity(pp.size()) + pp.start()); + + const treeBoundBox patchBb + ( + treeBoundBox(pp.points(), pp.meshPoints()).extend + ( + rndGen, + 1E-4 + ) + ); + + autoPtr > boundaryTree + ( + new indexedOctree + ( + 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) { - 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& sample = samples[sampleI]; + + pointIndexHit& nearInfo = nearest[sampleI].first(); + nearInfo = boundaryTree().findNearest + ( + sample, + magSqr(patchBb.max()-patchBb.min()) + ); + + 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;