further updates to mapping

This commit is contained in:
andy
2008-09-16 11:25:08 +01:00
parent 85cbbbf6ec
commit 571d39c321
6 changed files with 669 additions and 94 deletions

View File

@ -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

View File

@ -144,59 +144,18 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
void directMappedFixedValueFvPatchField<Type>::getNewValues
(
const directMappedPolyPatch& mpp,
const Field<Type>& sendValues,
Field<Type>& newValues
) const
{
if (this->updated())
{
return;
}
// Get the directMappedPolyPatch
const directMappedPolyPatch& mpp = refCast<const directMappedPolyPatch>
(
directMappedFixedValueFvPatchField<Type>::patch().patch()
);
// Get the scheduling information
const List<labelPair>& schedule = mpp.schedule();
const labelListList& sendLabels = mpp.sendLabels();
const labelListList& receiveFaceLabels = mpp.receiveFaceLabels();
Field<Type> newValues(this->size());
Field<Type> 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<Type, fvPatchField, volMesh> fieldType;
const word& fieldName = this->dimensionedInternalField().name();
const fieldType& sendField =
this->db().objectRegistry::lookupObject<fieldType>(fieldName);
sendValues = sendField.boundaryField()[patchID];
break;
}
default:
{
FatalErrorIn
(
"directMappedFixedValueFvPatchField<Type>::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<Type>::updateCoeffs()
if (Pstream::myProcNo() == sendProc)
{
OPstream toProc(Pstream::blocking, recvProc);
OPstream toProc(Pstream::scheduled, recvProc);
toProc<< IndirectList<Type>(sendValues, sendLabels[recvProc])();
}
else
{
// I am receiver. Receive from sendProc.
IPstream fromProc(Pstream::blocking, sendProc);
IPstream fromProc(Pstream::scheduled, sendProc);
Field<Type> fromFld(fromProc);
@ -241,6 +200,89 @@ void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
newValues[patchFaceI] = fromFld[i];
}
}
}
template<class Type>
void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
{
if (this->updated())
{
return;
}
// Get the directMappedPolyPatch
const directMappedPolyPatch& mpp = refCast<const directMappedPolyPatch>
(
directMappedFixedValueFvPatchField<Type>::patch().patch()
);
Field<Type> 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<Type, fvPatchField, volMesh> fieldType;
const word& fieldName = this->dimensionedInternalField().name();
const fieldType& sendField =
this->db().objectRegistry::lookupObject<fieldType>(fieldName);
getNewValues(mpp, sendField.boundaryField()[patchID], newValues);
break;
}
case directMappedPolyPatch::NEARESTFACE:
{
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
const word& fieldName = this->dimensionedInternalField().name();
const fieldType& sendField =
this->db().objectRegistry::lookupObject<fieldType>(fieldName);
Field<Type> allValues
(
this->patch().patch().boundaryMesh().mesh().nFaces(),
pTraits<Type>::zero
);
forAll(sendField.boundaryField(), patchI)
{
const fvPatchField<Type>& 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<Type>::updateCoeffs()"
)<< "Unknown sampling mode: " << mpp.mode()
<< nl << abort(FatalError);
}
}
if (setAverage_)
{

View File

@ -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<Type>& sendValues,
Field<Type>& newValues
) const;
public:
//- Runtime type information

View File

@ -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<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(p, iF),
phiName_("undefinedPhi")
{}
directMappedVelocityFluxFixedValueFvPatchField::
directMappedVelocityFluxFixedValueFvPatchField
(
const directMappedVelocityFluxFixedValueFvPatchField& ptf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedValueFvPatchVectorField(ptf, p, iF, mapper),
phiName_(ptf.phiName_)
{
if (!isType<directMappedFvPatch>(patch()))
{
FatalErrorIn
(
"directMappedVelocityFluxFixedValueFvPatchField::"
"directMappedFixedValueFvPatchField\n"
"(\n"
" const directMappedVelocityFluxFixedValueFvPatchField&,\n"
" const fvPatch&,\n"
" const DimensionedField<vector, volMesh>&,\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<vector, volMesh>& iF,
const dictionary& dict
)
:
fixedValueFvPatchVectorField(p, iF, dict),
phiName_(dict.lookup("phi"))
{
if (!isType<directMappedFvPatch>(patch()))
{
FatalErrorIn
(
"directMappedVelocityFluxFixedValueFvPatchField::"
"directMappedFixedValueFvPatchField\n"
"(\n"
" const fvPatch& p,\n"
" const DimensionedField<vector, volMesh>& 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<vector, volMesh>& 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<labelPair>& 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<vector>(sendUValues, sendLabels[recvProc])();
toProc<< IndirectList<scalar>
(
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<vector> fromUFld
(
sendUValues,
sendLabels[Pstream::myProcNo()]
);
IndirectList<scalar> 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<const directMappedPolyPatch>
(
directMappedVelocityFluxFixedValueFvPatchField::patch().patch()
);
vectorField newUValues(size());
scalarField newPhiValues(size());
const word& fieldName = dimensionedInternalField().name();
const volVectorField& UField = db().lookupObject<volVectorField>(fieldName);
surfaceScalarField& phiField =
const_cast<surfaceScalarField&>
(
db().lookupObject<surfaceScalarField>(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
// ************************************************************************* //

View File

@ -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<vector, volMesh>&
);
//- Construct from patch, internal field and dictionary
directMappedVelocityFluxFixedValueFvPatchField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const dictionary&
);
//- Construct by mapping given
// directMappedVelocityFluxFixedValueFvPatchField
// onto a new patch
directMappedVelocityFluxFixedValueFvPatchField
(
const directMappedVelocityFluxFixedValueFvPatchField&,
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
directMappedVelocityFluxFixedValueFvPatchField
(
const directMappedVelocityFluxFixedValueFvPatchField&
);
//- Construct and return a clone
virtual tmp<fvPatchVectorField> clone() const
{
return tmp<fvPatchVectorField>
(
new directMappedVelocityFluxFixedValueFvPatchField(*this)
);
}
//- Construct as copy setting internal field reference
directMappedVelocityFluxFixedValueFvPatchField
(
const directMappedVelocityFluxFixedValueFvPatchField&,
const DimensionedField<vector, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchVectorField> clone
(
const DimensionedField<vector, volMesh>& iF
) const
{
return tmp<fvPatchVectorField>
(
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
// ************************************************************************* //

View File

@ -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<indexedOctree<treeDataFace> > boundaryTree
(
new indexedOctree<treeDataFace>
(
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<indexedOctree<treeDataFace> > boundaryTree
(
new indexedOctree<treeDataFace>
(
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;