multi-region directMapped

This commit is contained in:
mattijs 2009-04-16 18:45:01 +01:00
parent 485ea4c84f
commit c42f04e843
20 changed files with 1753 additions and 940 deletions

View File

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

View File

@ -360,7 +360,7 @@ DebugSwitches
diagonal 0;
dictionary 0;
dimensionSet 1;
directMapped 0;
directMappedBase 0;
directMappedPatch 0;
directMappedVelocityFlux 0;
directionMixed 0;

View File

@ -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<labelPair> schedule
(

View File

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

View File

@ -25,7 +25,7 @@ License
\*---------------------------------------------------------------------------*/
#include "directMappedFixedValueFvPatchField.H"
#include "directMappedFvPatch.H"
#include "directMappedPatchBase.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -61,7 +61,7 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
setAverage_(ptf.setAverage_),
average_(ptf.average_)
{
if (!isType<directMappedFvPatch>(this->patch()))
if (!isA<directMappedPatchBase>(this->patch().patch()))
{
FatalErrorIn
(
@ -74,7 +74,7 @@ directMappedFixedValueFvPatchField<Type>::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<Type>::directMappedFixedValueFvPatchField
setAverage_(readBool(dict.lookup("setAverage"))),
average_(pTraits<Type>(dict.lookup("average")))
{
if (!isType<directMappedFvPatch>(this->patch()))
if (!isA<directMappedPatchBase>(this->patch().patch()))
{
FatalErrorIn
(
@ -107,12 +107,19 @@ directMappedFixedValueFvPatchField<Type>::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<const directMappedPatchBase>
(
this->patch().patch()
);
(void)mpp.map().schedule();
}
@ -143,70 +150,6 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void directMappedFixedValueFvPatchField<Type>::getNewValues
(
const directMappedPolyPatch& mpp,
const Field<Type>& sendValues,
Field<Type>& newValues
) 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<< UIndirectList<Type>(sendValues, sendLabels[recvProc])();
}
else
{
// I am receiver. Receive from sendProc.
IPstream fromProc(Pstream::scheduled, sendProc);
Field<Type> 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<Type> 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<class Type>
void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
{
@ -215,65 +158,94 @@ void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
return;
}
// Get the directMappedPolyPatch
const directMappedPolyPatch& mpp = refCast<const directMappedPolyPatch>
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
// Get the scheduling information from the directMappedPatchBase
const directMappedPatchBase& mpp = refCast<const directMappedPatchBase>
(
directMappedFixedValueFvPatchField<Type>::patch().patch()
);
const mapDistribute& distMap = mpp.map();
const fvMesh& nbrMesh = refCast<const fvMesh>(mpp.sampleMesh());
const word& fldName = this->dimensionedInternalField().name();
Field<Type> newValues(this->size());
// Result of obtaining remote values
Field<Type> 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<fieldType>
(
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<Type>::"
"updateCoeffs()"
)<< "Unable to find sample patch " << mpp.samplePatch()
<< " in region " << mpp.sampleRegion()
<< " for patch " << this->patch().name() << nl
<< abort(FatalError);
}
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);
const fieldType& nbrField = nbrMesh.lookupObject<fieldType>
(
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<Type, fvPatchField, volMesh> fieldType;
const word& fieldName = this->dimensionedInternalField().name();
const fieldType& sendField =
this->db().objectRegistry::lookupObject<fieldType>(fieldName);
Field<Type> allValues(nbrMesh.nFaces(), pTraits<Type>::zero);
Field<Type> allValues
const fieldType& nbrField = nbrMesh.lookupObject<fieldType>
(
this->patch().patch().boundaryMesh().mesh().nFaces(),
pTraits<Type>::zero
fldName
);
forAll(sendField.boundaryField(), patchI)
forAll(nbrField.boundaryField(), patchI)
{
const fvPatchField<Type>& pf =
sendField.boundaryField()[patchI];
nbrField.boundaryField()[patchI];
label faceStart = pf.patch().patch().start();
forAll(pf, faceI)
@ -282,9 +254,17 @@ void directMappedFixedValueFvPatchField<Type>::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;
}

View File

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

View File

@ -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<directMappedFvPatch>(patch()))
if (!isType<directMappedPatchBase>(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<directMappedFvPatch>(patch()))
if (!isType<directMappedPatchBase>(this->patch().patch()))
{
FatalErrorIn
(
"directMappedVelocityFluxFixedValueFvPatchField::"
"directMappedFixedValueFvPatchField\n"
"directMappedVelocityFluxFixedValueFvPatchField\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 << "'"
<< "' 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<const directMappedPolyPatch>
(
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<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<< UIndirectList<vector>(sendUValues, sendLabels[recvProc])();
toProc<< UIndirectList<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
{
UIndirectList<vector> fromUFld
(
sendUValues,
sendLabels[Pstream::myProcNo()]
);
UIndirectList<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()
@ -227,37 +155,33 @@ void directMappedVelocityFluxFixedValueFvPatchField::updateCoeffs()
return;
}
// Get the directMappedPolyPatch
const directMappedPolyPatch& mpp = refCast<const directMappedPolyPatch>
// Get the directMappedPatchBase
const directMappedPatchBase& mpp = refCast<const directMappedPatchBase>
(
directMappedVelocityFluxFixedValueFvPatchField::patch().patch()
);
vectorField newUValues(size());
scalarField newPhiValues(size());
const mapDistribute& distMap = mpp.map();
const fvMesh& nbrMesh = refCast<const fvMesh>(mpp.sampleMesh());
const word& fieldName = dimensionedInternalField().name();
const volVectorField& UField = db().lookupObject<volVectorField>(fieldName);
const volVectorField& UField = nbrMesh.lookupObject<volVectorField>
(
fieldName
);
surfaceScalarField& phiField = const_cast<surfaceScalarField&>
(
db().lookupObject<surfaceScalarField>(phiName_)
nbrMesh.lookupObject<surfaceScalarField>(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
);

View File

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

View File

@ -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);
}
// ************************************************************************* //

View File

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

View File

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

View File

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

View File

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

View File

@ -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<directMappedPatchBase::sampleMode, 3>::names[] =
{
"nearestCell",
"nearestPatchFace",
"nearestFace"
};
const NamedEnum<directMappedPatchBase::sampleMode, 3>
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<pointField> globalFc(Pstream::nProcs());
List<pointField> 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<pointField>
(
globalSamples,
accessOp<pointField>()
);
patchFaces = ListListOps::combine<labelList>
(
globalFaces,
accessOp<labelList>()
);
patchFc = ListListOps::combine<pointField>
(
globalFc,
accessOp<pointField>()
);
patchFaceProcs.setSize(patchFaces.size());
labelList nPerProc
(
ListListOps::subSizes
(
globalFaces,
accessOp<labelList>()
)
);
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<nearInfo> 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<treeDataFace> 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<label>
(
sampleIndices,
subMap[procI]
);
constructMap[procI] = UIndirectList<label>
(
patchFaces,
constructMap[procI]
);
if (debug)
{
Pout<< "To proc:" << procI << " sending values of cells/faces:"
<< subMap[procI] << endl;
Pout<< "From proc:" << procI << " receiving values of patch faces:"
<< constructMap[procI] << endl;
}
}
// Redo constructSize
mapPtr_().constructSize() = patch_.size();
if (debug)
{
// Check that all elements get a value.
PackedBoolList used(patch_.size());
forAll(constructMap, procI)
{
const labelList& map = constructMap[procI];
forAll(map, i)
{
label faceI = map[i];
if (used[faceI] == 0)
{
used[faceI] = 1;
}
else
{
FatalErrorIn("directMappedPatchBase::calcMapping() const")
<< "On patch " << patch_.name()
<< " patchface " << faceI
<< " is assigned to more than once."
<< abort(FatalError);
}
}
}
forAll(used, faceI)
{
if (used[faceI] == 0)
{
FatalErrorIn("directMappedPatchBase::calcMapping() const")
<< "On patch " << patch_.name()
<< " patchface " << faceI
<< " is never assigned to."
<< abort(FatalError);
}
}
}
}
// * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * * * //
Foam::directMappedPatchBase::directMappedPatchBase
(
const polyPatch& pp
)
:
patch_(pp),
sampleRegion_(patch_.boundaryMesh().mesh().name()),
mode_(NEARESTPATCHFACE),
samplePatch_("none"),
offset_(vector::zero),
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
mapPtr_(NULL)
{}
Foam::directMappedPatchBase::directMappedPatchBase
(
const polyPatch& pp,
const dictionary& dict
)
:
patch_(pp),
sampleRegion_
(
dict.lookupOrDefault
(
"sampleRegion",
patch_.boundaryMesh().mesh().name()
)
),
mode_(sampleModeNames_.read(dict.lookup("sampleMode"))),
samplePatch_(dict.lookup("samplePatch")),
offset_(dict.lookup("offset")),
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
mapPtr_(NULL)
{}
Foam::directMappedPatchBase::directMappedPatchBase
(
const polyPatch& pp,
const directMappedPatchBase& dmp
)
:
patch_(pp),
sampleRegion_(dmp.sampleRegion_),
mode_(dmp.mode_),
samplePatch_(dmp.samplePatch_),
offset_(dmp.offset_),
sameRegion_(dmp.sameRegion_),
mapPtr_(NULL)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::directMappedPatchBase::~directMappedPatchBase()
{
clearOut();
}
void Foam::directMappedPatchBase::clearOut()
{
mapPtr_.clear();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::polyMesh& Foam::directMappedPatchBase::sampleMesh() const
{
return patch_.boundaryMesh().mesh().time().lookupObject<polyMesh>
(
sampleRegion_
);
}
const Foam::polyPatch& Foam::directMappedPatchBase::samplePolyPatch() const
{
const polyMesh& nbrMesh = sampleMesh();
label patchI = nbrMesh.boundaryMesh().findPatchID(samplePatch_);
if (patchI == -1)
{
FatalErrorIn("directMappedPatchBase::samplePolyPatch() ")
<< "Cannot find patch " << samplePatch_
<< " in region " << sampleRegion_ << endl
<< "Valid patches are " << nbrMesh.boundaryMesh().names()
<< exit(FatalError);
}
return nbrMesh.boundaryMesh()[patchI];
}
void Foam::directMappedPatchBase::write(Ostream& os) const
{
os.writeKeyword("sampleMode") << sampleModeNames_[mode_]
<< token::END_STATEMENT << nl;
os.writeKeyword("sampleRegion") << sampleRegion_
<< token::END_STATEMENT << nl;
os.writeKeyword("samplePatch") << samplePatch_
<< token::END_STATEMENT << nl;
os.writeKeyword("offset") << offset_ << token::END_STATEMENT << nl;
}
// ************************************************************************* //

View File

@ -0,0 +1,248 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::directMappedPatchBase
Description
Determines a mapping between patch face centres and mesh cell or face
centres and processors they're on.
Note
Storage is not optimal. It temporary collects all (patch)face centres
on all processors to keep the addressing calculation simple.
SourceFiles
directMappedPatchBase.C
\*---------------------------------------------------------------------------*/
#ifndef directMappedPatchBase_H
#define directMappedPatchBase_H
#include "pointField.H"
#include "Tuple2.H"
#include "pointIndexHit.H"
#include "mapDistribute.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class polyPatch;
class polyMesh;
/*---------------------------------------------------------------------------*\
Class directMappedPatchBase Declaration
\*---------------------------------------------------------------------------*/
class directMappedPatchBase
{
public:
//- Mesh items to sample
enum sampleMode
{
NEARESTCELL,
NEARESTPATCHFACE,
NEARESTFACE
};
private:
// Private data
static const NamedEnum<sampleMode, 3> sampleModeNames_;
//- Patch to sample
const polyPatch& patch_;
//- Region to sample
const word sampleRegion_;
//- What to sample
const sampleMode mode_;
//- Patch (only if NEARESTBOUNDARY)
const word samplePatch_;
//- Offset vector
const vector offset_;
//- Same region
const bool sameRegion_;
// Derived information
//- Communication schedule:
// - Cells/faces to sample per processor
// - Patch faces to receive per processor
// - schedule
mutable autoPtr<mapDistribute> mapPtr_;
// Private Member Functions
//- Collect single list of samples and originating processor+face.
void collectSamples
(
pointField&,
labelList& patchFaceProcs,
labelList& patchFaces,
pointField& patchFc
) const;
//- Find cells/faces containing samples
void findSamples
(
const pointField&,
labelList& sampleProcs, // processor containing sample
labelList& sampleIndices, // local index of cell/face
pointField& sampleLocations // actual representative location
) const;
//- Calculate matching
void calcMapping() const;
// Private class
//- Private class for finding nearest
// - point+local index
// - sqr(distance)
// - processor
typedef Tuple2<pointIndexHit, Tuple2<scalar, label> > nearInfo;
class nearestEqOp
{
public:
void operator()(nearInfo& x, const nearInfo& y) const
{
if (y.first().hit())
{
if (!x.first().hit())
{
x = y;
}
else if (y.second().first() < x.second().first())
{
x = y;
}
}
}
};
public:
//- Runtime type information
ClassName("directMappedPatchBase");
// Constructors
//- Construct from components
directMappedPatchBase(const polyPatch&);
//- Construct from dictionary
directMappedPatchBase(const polyPatch&, const dictionary&);
//- Construct as copy, resetting patch
directMappedPatchBase(const polyPatch&, const directMappedPatchBase&);
// Destructor
~directMappedPatchBase();
void clearOut();
// Member functions
//- What to sample
const sampleMode& mode() const
{
return mode_;
}
//- Region to sample
const word& sampleRegion() const
{
return sampleRegion_;
}
//- Patch (only if NEARESTBOUNDARY)
const word& samplePatch() const
{
return samplePatch_;
}
//- Offset vector (from patch faces to destination mesh objects)
const vector& offset() const
{
return offset_;
}
//- Return reference to the parallel distribution map
const mapDistribute& map() const
{
if (mapPtr_.empty())
{
calcMapping();
}
return mapPtr_();
}
//- Cached sampleRegion != mesh.name()
bool sameRegion() const
{
return sameRegion_;
}
//- Get the region mesh
const polyMesh& sampleMesh() const;
//- Get the patch on the region
const polyPatch& samplePolyPatch() const;
//- Write as a dictionary
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -26,14 +26,6 @@ License
#include "directMappedPolyPatch.H"
#include "addToRunTimeSelectionTable.H"
#include "ListListOps.H"
#include "meshSearch.H"
#include "mapDistribute.H"
#include "meshTools.H"
#include "OFstream.H"
#include "Random.H"
#include "treeDataFace.H"
#include "indexedOctree.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -43,469 +35,11 @@ namespace Foam
addToRunTimeSelectionTable(polyPatch, directMappedPolyPatch, word);
addToRunTimeSelectionTable(polyPatch, directMappedPolyPatch, dictionary);
template<>
const char* NamedEnum<directMappedPolyPatch::sampleMode, 3>::names[] =
{
"nearestCell",
"nearestPatchFace",
"nearestFace"
};
const NamedEnum<directMappedPolyPatch::sampleMode, 3>
directMappedPolyPatch::sampleModeNames_;
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::directMappedPolyPatch::collectSamples
(
pointField& samples,
labelList& patchFaceProcs,
labelList& patchFaces,
pointField& patchFc
) const
{
// Collect all sample points and the faces they come from.
List<pointField> globalFc(Pstream::nProcs());
List<pointField> globalSamples(Pstream::nProcs());
labelListList globalFaces(Pstream::nProcs());
globalFc[Pstream::myProcNo()] = this->faceCentres();
globalSamples[Pstream::myProcNo()] = globalFc[Pstream::myProcNo()]+offset_;
globalFaces[Pstream::myProcNo()] = identity(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<pointField>
(
globalSamples,
accessOp<pointField>()
);
patchFaces = ListListOps::combine<labelList>
(
globalFaces,
accessOp<labelList>()
);
patchFc = ListListOps::combine<pointField>
(
globalFc,
accessOp<pointField>()
);
patchFaceProcs.setSize(patchFaces.size());
labelList nPerProc
(
ListListOps::subSizes
(
globalFaces,
accessOp<labelList>()
)
);
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::directMappedPolyPatch::findSamples
(
const pointField& samples,
labelList& sampleProcs,
labelList& sampleIndices,
pointField& sampleLocations
) const
{
const polyMesh& mesh = boundaryMesh().mesh();
// All the info for nearest. Construct to miss
List<nearInfo> nearest(samples.size());
switch (mode_)
{
case NEARESTCELL:
{
if (samplePatch_.size() && samplePatch_ != "none")
{
FatalErrorIn
(
"directMappedPolyPatch::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:
{
label patchI = boundaryMesh().findPatchID(samplePatch_);
if (patchI == -1)
{
FatalErrorIn("directMappedPolyPatch::findSamples(..)")
<< "Cannot find patch " << samplePatch_ << endl
<< "Valid patches are " << boundaryMesh().names()
<< exit(FatalError);
}
Random rndGen(123456);
const polyPatch& pp = boundaryMesh()[patchI];
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);
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)
{
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
(
"directMappedPolyPatch::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("directMappedPolyPatch::findSamples(..)")
<< "problem." << abort(FatalError);
}
}
// Find nearest.
Pstream::listCombineGather(nearest, nearestEqOp());
Pstream::listCombineScatter(nearest);
if (debug)
{
Info<< "directMappedPolyPatch::findSamples : " << 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
(
"directMappedPolyPatch::findSamples"
"(const pointField&, labelList&"
", labelList&, pointField&)"
) << "Did not find sample " << samples[sampleI]
<< " on any processor." << 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::directMappedPolyPatch::calcMapping() const
{
if (sendLabelsPtr_.valid())
{
FatalErrorIn("directMappedPolyPatch::calcMapping() const")
<< "Mapping already calculated" << exit(FatalError);
}
if (offset_ == vector::zero)
{
FatalErrorIn("directMappedPolyPatch::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.
if (debug && Pstream::master())
{
OFstream str
(
boundaryMesh().mesh().time().path()
/ 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("directMappedPolyPatch::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.
mapDistribute distMap(sampleProcs, patchFaceProcs);
// Rework the schedule to cell data to send, face data to receive.
schedulePtr_.reset(new List<labelPair>(distMap.schedule()));
const labelListList& subMap = distMap.subMap();
const labelListList& constructMap = distMap.constructMap();
// Extract the particular data I need to send and receive.
sendLabelsPtr_.reset(new labelListList(subMap.size()));
labelListList& sendLabels = sendLabelsPtr_();
forAll(subMap, procI)
{
sendLabels[procI] = UIndirectList<label>
(
sampleIndices,
subMap[procI]
);
if (debug)
{
Pout<< "To proc:" << procI << " sending values of cells/faces:"
<< sendLabels[procI] << endl;
}
}
receiveFaceLabelsPtr_.reset(new labelListList(constructMap.size()));
labelListList& receiveFaceLabels = receiveFaceLabelsPtr_();
forAll(constructMap, procI)
{
receiveFaceLabels[procI] =
UIndirectList<label>(patchFaces, constructMap[procI]);
if (debug)
{
Pout<< "From proc:" << procI << " receiving values of patch faces:"
<< receiveFaceLabels[procI] << endl;
}
}
}
// * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * * * //
@ -519,12 +53,7 @@ Foam::directMappedPolyPatch::directMappedPolyPatch
)
:
polyPatch(name, size, start, index, bm),
mode_(NEARESTPATCHFACE),
samplePatch_("none"),
offset_(vector::zero),
schedulePtr_(NULL),
sendLabelsPtr_(NULL),
receiveFaceLabelsPtr_(NULL)
directMappedPatchBase(static_cast<const polyPatch&>(*this))
{}
@ -537,12 +66,7 @@ Foam::directMappedPolyPatch::directMappedPolyPatch
)
:
polyPatch(name, dict, index, bm),
mode_(sampleModeNames_.read(dict.lookup("sampleMode"))),
samplePatch_(dict.lookup("samplePatch")),
offset_(dict.lookup("offset")),
schedulePtr_(NULL),
sendLabelsPtr_(NULL),
receiveFaceLabelsPtr_(NULL)
directMappedPatchBase(*this, dict)
{}
@ -553,12 +77,11 @@ Foam::directMappedPolyPatch::directMappedPolyPatch
)
:
polyPatch(pp, bm),
mode_(pp.mode_),
samplePatch_(pp.samplePatch_),
offset_(pp.offset_),
schedulePtr_(NULL),
sendLabelsPtr_(NULL),
receiveFaceLabelsPtr_(NULL)
directMappedPatchBase
(
*this,
static_cast<const directMappedPatchBase&>(*this)
)
{}
@ -572,12 +95,11 @@ Foam::directMappedPolyPatch::directMappedPolyPatch
)
:
polyPatch(pp, bm, index, newSize, newStart),
mode_(pp.mode_),
samplePatch_(pp.samplePatch_),
offset_(pp.offset_),
schedulePtr_(NULL),
sendLabelsPtr_(NULL),
receiveFaceLabelsPtr_(NULL)
directMappedPatchBase
(
*this,
static_cast<const directMappedPatchBase&>(*this)
)
{}
@ -585,28 +107,59 @@ Foam::directMappedPolyPatch::directMappedPolyPatch
Foam::directMappedPolyPatch::~directMappedPolyPatch()
{
clearOut();
directMappedPatchBase::clearOut();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::directMappedPolyPatch::clearOut()
//- Initialise the calculation of the patch geometry
void Foam::directMappedPolyPatch::initGeometry()
{
schedulePtr_.clear();
sendLabelsPtr_.clear();
receiveFaceLabelsPtr_.clear();
polyPatch::initGeometry();
directMappedPatchBase::clearOut();
}
//- Calculate the patch geometry
void Foam::directMappedPolyPatch::calcGeometry()
{
polyPatch::calcGeometry();
directMappedPatchBase::clearOut();
}
//- Initialise the patches for moving points
void Foam::directMappedPolyPatch::initMovePoints(const pointField& p)
{
polyPatch::initMovePoints(p);
directMappedPatchBase::clearOut();
}
//- Correct patches after moving points
void Foam::directMappedPolyPatch::movePoints(const pointField& p)
{
polyPatch::movePoints(p);
directMappedPatchBase::clearOut();
}
//- Initialise the update of the patch topology
void Foam::directMappedPolyPatch::initUpdateMesh()
{
polyPatch::initUpdateMesh();
directMappedPatchBase::clearOut();
}
//- Update of the patch topology
void Foam::directMappedPolyPatch::updateMesh()
{
polyPatch::updateMesh();
directMappedPatchBase::clearOut();
}
void Foam::directMappedPolyPatch::write(Ostream& os) const
{
polyPatch::write(os);
os.writeKeyword("sampleMode") << sampleModeNames_[mode_]
<< token::END_STATEMENT << nl;
os.writeKeyword("samplePatch") << samplePatch_
<< token::END_STATEMENT << nl;
os.writeKeyword("offset") << offset_ << token::END_STATEMENT << nl;
directMappedPatchBase::write(os);
}

View File

@ -42,9 +42,7 @@ SourceFiles
#define directMappedPolyPatch_H
#include "polyPatch.H"
#include "labelPair.H"
#include "Tuple2.H"
#include "pointIndexHit.H"
#include "directMappedPatchBase.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -52,148 +50,37 @@ SourceFiles
namespace Foam
{
class polyMesh;
/*---------------------------------------------------------------------------*\
Class directMappedPolyPatch Declaration
\*---------------------------------------------------------------------------*/
class directMappedPolyPatch
:
public polyPatch
public polyPatch,
public directMappedPatchBase
{
public:
//- Mesh items to sample
enum sampleMode
{
NEARESTCELL,
NEARESTPATCHFACE,
NEARESTFACE
};
private:
// Private data
static const NamedEnum<sampleMode, 3> sampleModeNames_;
//- What to sample
sampleMode mode_;
//- Patch (only if NEARESTBOUNDARY)
const word samplePatch_;
//- Offset vector
const vector offset_;
// Derived information
//- Communication schedule.
mutable autoPtr<List<labelPair> > schedulePtr_;
//- Cells/faces to sample per processor
mutable autoPtr<labelListList> sendLabelsPtr_;
//- Patch faces to receive per processor
mutable autoPtr<labelListList> receiveFaceLabelsPtr_;
// Private Member Functions
//- Collect single list of samples and originating processor+face.
void collectSamples
(
pointField&,
labelList& patchFaceProcs,
labelList& patchFaces,
pointField& patchFc
) const;
//- Find cells/faces containing samples
void findSamples
(
const pointField&,
labelList& sampleProcs, // processor containing sample
labelList& sampleIndices, // local index of cell/face
pointField& sampleLocations // actual representative location
) const;
//- Calculate matching
void calcMapping() const;
// Private class
//- Private class for finding nearest
// - point+local index
// - sqr(distance)
// - processor
typedef Tuple2<pointIndexHit, Tuple2<scalar, label> > nearInfo;
class nearestEqOp
{
public:
void operator()(nearInfo& x, const nearInfo& y) const
{
if (y.first().hit())
{
if (!x.first().hit())
{
x = y;
}
else if (y.second().first() < x.second().first())
{
x = y;
}
}
}
};
protected:
void clearOut();
//- Initialise the calculation of the patch geometry
virtual void initGeometry()
{
clearOut();
}
virtual void initGeometry();
//- Calculate the patch geometry
virtual void calcGeometry()
{
clearOut();
}
virtual void calcGeometry();
//- Initialise the patches for moving points
virtual void initMovePoints(const pointField&)
{
clearOut();
}
virtual void initMovePoints(const pointField&);
//- Correct patches after moving points
virtual void movePoints(const pointField& p)
{
clearOut();
}
virtual void movePoints(const pointField&);
//- Initialise the update of the patch topology
virtual void initUpdateMesh()
{
clearOut();
}
virtual void initUpdateMesh();
//- Update of the patch topology
virtual void updateMesh()
{
clearOut();
}
virtual void updateMesh();
public:
@ -271,72 +158,6 @@ public:
// Member functions
//- What to sample
const sampleMode& mode() const
{
return mode_;
}
//- Patch (only if NEARESTBOUNDARY)
const word& samplePatch() const
{
return samplePatch_;
}
//- Offset vector (from patch faces to destination mesh objects)
const vector& offset() const
{
return offset_;
}
//- Access to communication.
const List<labelPair>& schedule() const
{
if (schedulePtr_.empty())
{
calcMapping();
}
return schedulePtr_();
}
//- Cells/faces to sample per processor
const labelListList& sendLabels() const
{
if (debug)
{
Pout<< "Asking for sendLabels." << endl;
}
if (sendLabelsPtr_.empty())
{
if (debug)
{
Pout<< "Calculating mapping." << endl;
calcMapping();
}
}
return sendLabelsPtr_();
}
//- Patch faces to receive per processor
const labelListList& receiveFaceLabels() const
{
if (debug)
{
Pout<< "Asking for receiveFaceLabels." << endl;
}
if (receiveFaceLabelsPtr_.empty())
{
if (debug)
{
Pout<< "Calculating mapping." << endl;
calcMapping();
}
}
return receiveFaceLabelsPtr_();
}
//- Write the polyPatch data as a dictionary
virtual void write(Ostream&) const;
};

View File

@ -0,0 +1,171 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "directMappedWallPolyPatch.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(directMappedWallPolyPatch, 0);
addToRunTimeSelectionTable(polyPatch, directMappedWallPolyPatch, word);
addToRunTimeSelectionTable
(
polyPatch,
directMappedWallPolyPatch,
dictionary
);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * * * //
Foam::directMappedWallPolyPatch::directMappedWallPolyPatch
(
const word& name,
const label size,
const label start,
const label index,
const polyBoundaryMesh& bm
)
:
wallPolyPatch(name, size, start, index, bm),
directMappedPatchBase(static_cast<const polyPatch&>(*this))
{}
Foam::directMappedWallPolyPatch::directMappedWallPolyPatch
(
const word& name,
const dictionary& dict,
const label index,
const polyBoundaryMesh& bm
)
:
wallPolyPatch(name, dict, index, bm),
directMappedPatchBase(*this, dict)
{}
Foam::directMappedWallPolyPatch::directMappedWallPolyPatch
(
const directMappedWallPolyPatch& pp,
const polyBoundaryMesh& bm
)
:
wallPolyPatch(pp, bm),
directMappedPatchBase
(
*this,
static_cast<const directMappedPatchBase&>(*this)
)
{}
Foam::directMappedWallPolyPatch::directMappedWallPolyPatch
(
const directMappedWallPolyPatch& pp,
const polyBoundaryMesh& bm,
const label index,
const label newSize,
const label newStart
)
:
wallPolyPatch(pp, bm, index, newSize, newStart),
directMappedPatchBase
(
*this,
static_cast<const directMappedPatchBase&>(*this)
)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::directMappedWallPolyPatch::~directMappedWallPolyPatch()
{
directMappedPatchBase::clearOut();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
//- Initialise the calculation of the patch geometry
void Foam::directMappedWallPolyPatch::initGeometry()
{
wallPolyPatch::initGeometry();
directMappedPatchBase::clearOut();
}
//- Calculate the patch geometry
void Foam::directMappedWallPolyPatch::calcGeometry()
{
wallPolyPatch::calcGeometry();
directMappedPatchBase::clearOut();
}
//- Initialise the patches for moving points
void Foam::directMappedWallPolyPatch::initMovePoints(const pointField& p)
{
wallPolyPatch::initMovePoints(p);
directMappedPatchBase::clearOut();
}
//- Correct patches after moving points
void Foam::directMappedWallPolyPatch::movePoints(const pointField& p)
{
wallPolyPatch::movePoints(p);
directMappedPatchBase::clearOut();
}
//- Initialise the update of the patch topology
void Foam::directMappedWallPolyPatch::initUpdateMesh()
{
wallPolyPatch::initUpdateMesh();
directMappedPatchBase::clearOut();
}
//- Update of the patch topology
void Foam::directMappedWallPolyPatch::updateMesh()
{
wallPolyPatch::updateMesh();
directMappedPatchBase::clearOut();
}
void Foam::directMappedWallPolyPatch::write(Ostream& os) const
{
wallPolyPatch::write(os);
directMappedPatchBase::write(os);
}
// ************************************************************************* //

View File

@ -0,0 +1,181 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::directMappedWallPolyPatch
Description
Determines a mapping between patch face centres and mesh cell or face
centres and processors they're on.
Note
Storage is not optimal. It stores all face centres and cells on all
processors to keep the addressing calculation simple.
SourceFiles
directMappedWallPolyPatch.C
\*---------------------------------------------------------------------------*/
#ifndef directMappedWallPolyPatch_H
#define directMappedWallPolyPatch_H
#include "wallPolyPatch.H"
#include "directMappedPatchBase.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class polyMesh;
/*---------------------------------------------------------------------------*\
Class directMappedWallPolyPatch Declaration
\*---------------------------------------------------------------------------*/
class directMappedWallPolyPatch
:
public wallPolyPatch,
public directMappedPatchBase
{
protected:
//- Initialise the calculation of the patch geometry
virtual void initGeometry();
//- Calculate the patch geometry
virtual void calcGeometry();
//- Initialise the patches for moving points
virtual void initMovePoints(const pointField&);
//- Correct patches after moving points
virtual void movePoints(const pointField&);
//- Initialise the update of the patch topology
virtual void initUpdateMesh();
//- Update of the patch topology
virtual void updateMesh();
public:
//- Runtime type information
TypeName("directMappedPatch");
// Constructors
//- Construct from components
directMappedWallPolyPatch
(
const word& name,
const label size,
const label start,
const label index,
const polyBoundaryMesh& bm
);
//- Construct from dictionary
directMappedWallPolyPatch
(
const word& name,
const dictionary& dict,
const label index,
const polyBoundaryMesh& bm
);
//- Construct as copy, resetting the boundary mesh
directMappedWallPolyPatch
(
const directMappedWallPolyPatch&,
const polyBoundaryMesh&
);
//- Construct given the original patch and resetting the
// face list and boundary mesh information
directMappedWallPolyPatch
(
const directMappedWallPolyPatch& pp,
const polyBoundaryMesh& bm,
const label index,
const label newSize,
const label newStart
);
//- Construct and return a clone, resetting the boundary mesh
virtual autoPtr<polyPatch> clone(const polyBoundaryMesh& bm) const
{
return autoPtr<polyPatch>(new directMappedWallPolyPatch(*this, bm));
}
//- Construct and return a clone, resetting the face list
// and boundary mesh
virtual autoPtr<polyPatch> clone
(
const polyBoundaryMesh& bm,
const label index,
const label newSize,
const label newStart
) const
{
return autoPtr<polyPatch>
(
new directMappedWallPolyPatch
(
*this,
bm,
index,
newSize,
newStart
)
);
}
// Destructor
~directMappedWallPolyPatch();
// Member functions
//- Write the polyPatch data as a dictionary
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -23,6 +23,7 @@ dictionaryReplacement
{
type directMappedPatch;
offset ( 0.0495 0 0 );
sampleRegion region0;
sampleMode nearestCell;
samplePatch none;
}