overlapGgi and turboFvMesh working now in parallel

This commit is contained in:
Oliver Borm (boroli) 2010-12-02 18:04:28 +01:00
parent 31a8b096f1
commit 3bd380a39d
24 changed files with 645 additions and 476 deletions

View file

@ -104,9 +104,9 @@ echo "run $args" > $PWD/gdbCommands
echo "where" >> $PWD/gdbCommands
echo "Constructed gdb initialization file $PWD/gdbCommands"
$ECHO "Choose running method: 0)normal 1)gdb+xterm 2)gdb 3)log 4)log+xterm 5)xterm+valgrind: \c"
$ECHO "Choose running method: 0)normal 1)gdb+xterm 2)gdb 3)log 4)log+xterm 5)xterm+valgrind 6)nemiver: \c"
read method
if [ "$method" -ne 0 -a "$method" -ne 1 -a "$method" -ne 2 -a "$method" -ne 3 -a "$method" -ne 4 -a "$method" -ne 5 ]; then
if [ "$method" -ne 0 -a "$method" -ne 1 -a "$method" -ne 2 -a "$method" -ne 3 -a "$method" -ne 4 -a "$method" -ne 5 -a "$method" -ne 6 ]; then
printUsage
exit 1
fi
@ -184,6 +184,12 @@ do
elif [ "$method" -eq 5 ]; then
echo "$sourceFoam; cd $PWD; valgrind $exec $args; read dummy" >> $procCmdFile
echo "${node}xterm -font fixed -title 'processor'$proc $geom -e $procCmdFile" >> $PWD/mpirun.schema
elif [ "$method" -eq 6 ]; then
## maybe one could use nemiver sessions for reloading breakpoints --session=<N> or --last
# echo "$sourceFoam; cd $PWD; nemiver --last $exec $args; read dummy" >> $procCmdFile
echo "$sourceFoam; cd $PWD; nemiver $exec $args; read dummy" >> $procCmdFile
# echo "$sourceFoam; cd $PWD; ddd --args $exec $args; read dummy" >> $procCmdFile
echo "${node} $procCmdFile" >> $PWD/mpirun.schema
fi
chmod +x $procCmdFile

View file

@ -25,6 +25,7 @@ License
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
Fethi Tekin, All rights reserved.
Oliver Borm, All rights reserved.
\*---------------------------------------------------------------------------*/
@ -33,6 +34,7 @@ Author
#include "addToRunTimeSelectionTable.H"
#include "demandDrivenData.H"
#include "polyPatchID.H"
#include "ZoneIDs.H"
#include "SubField.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -45,6 +47,43 @@ namespace Foam
addToRunTimeSelectionTable(polyPatch, overlapGgiPolyPatch, dictionary);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::overlapGgiPolyPatch::calcLocalParallel() const
{
// Calculate patch-to-zone addressing
if (localParallelPtr_)
{
FatalErrorIn("void ggiPolyPatch::calcLocalParallel() const")
<< "Local parallel switch already calculated"
<< abort(FatalError);
}
localParallelPtr_ = new bool(false);
bool& emptyOrComplete = *localParallelPtr_;
// Calculate localisation on master and shadow
emptyOrComplete =
(zone().size() == size() && shadow().zone().size() == shadow().size())
|| (size() == 0 && shadow().size() == 0);
reduce(emptyOrComplete, andOp<bool>());
if (debug && Pstream::parRun())
{
Info<< "GGI patch Master: " << name()
<< " Slave: " << shadowName() << " is ";
if (emptyOrComplete)
{
Info<< "local parallel" << endl;
}
else
{
Info<< "split between multiple processors" << endl;
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -59,12 +98,15 @@ Foam::overlapGgiPolyPatch::overlapGgiPolyPatch
:
coupledPolyPatch(name, size, start, index, bm),
shadowName_(word::null),
zoneName_(word::null),
shadowIndex_(-1),
zoneIndex_(-1),
rotationAxis_(vector(0.0, 0.0, 1.0)),
nCopies_(0),
expandedMasterPtr_(NULL),
expandedSlavePtr_(NULL),
patchToPatchPtr_(NULL),
localParallelPtr_(NULL),
reconFaceCellCentresPtr_(NULL)
{}
@ -78,18 +120,22 @@ Foam::overlapGgiPolyPatch::overlapGgiPolyPatch
const label index,
const polyBoundaryMesh& bm,
const word& shadowName,
const word& zoneName,
const vector& axis,
const scalar nCopies
)
:
coupledPolyPatch(name, size, start, index, bm),
shadowName_(shadowName),
zoneName_(zoneName),
shadowIndex_(-1),
zoneIndex_(-1),
rotationAxis_(axis),
nCopies_(nCopies),
expandedMasterPtr_(NULL),
expandedSlavePtr_(NULL),
patchToPatchPtr_(NULL),
localParallelPtr_(NULL),
reconFaceCellCentresPtr_(NULL)
{}
@ -105,12 +151,15 @@ Foam::overlapGgiPolyPatch::overlapGgiPolyPatch
:
coupledPolyPatch(name, dict, index, bm),
shadowName_(dict.lookup("shadowPatch")),
zoneName_(dict.lookup("zone")),
shadowIndex_(-1),
zoneIndex_(-1),
rotationAxis_(dict.lookup("rotationAxis")),
nCopies_(readScalar(dict.lookup("nCopies"))),
expandedMasterPtr_(NULL),
expandedSlavePtr_(NULL),
patchToPatchPtr_(NULL),
localParallelPtr_(NULL),
reconFaceCellCentresPtr_(NULL)
{}
@ -124,12 +173,15 @@ Foam::overlapGgiPolyPatch::overlapGgiPolyPatch
:
coupledPolyPatch(pp, bm),
shadowName_(pp.shadowName_),
zoneName_(pp.zoneName_),
shadowIndex_(-1),
zoneIndex_(-1),
rotationAxis_(pp.rotationAxis_),
nCopies_(pp.nCopies_),
expandedMasterPtr_(NULL),
expandedSlavePtr_(NULL),
patchToPatchPtr_(NULL),
localParallelPtr_(NULL),
reconFaceCellCentresPtr_(NULL)
{}
@ -146,12 +198,15 @@ Foam::overlapGgiPolyPatch::overlapGgiPolyPatch
:
coupledPolyPatch(pp, bm, index, newSize, newStart),
shadowName_(pp.shadowName_),
zoneName_(pp.zoneName_),
shadowIndex_(-1),
zoneIndex_(-1),
rotationAxis_(pp.rotationAxis_),
nCopies_(pp.nCopies_),
expandedMasterPtr_(NULL),
expandedSlavePtr_(NULL),
patchToPatchPtr_(NULL),
localParallelPtr_(NULL),
reconFaceCellCentresPtr_(NULL)
{}
@ -202,17 +257,56 @@ Foam::label Foam::overlapGgiPolyPatch::shadowIndex() const
}
}
// Force local parallel
localParallel();
return shadowIndex_;
}
Foam::label Foam::overlapGgiPolyPatch::zoneIndex() const
{
if (zoneIndex_ == -1 && zoneName_ != Foam::word::null)
{
// Grab zone patch index
faceZoneID zone(zoneName_, boundaryMesh().mesh().faceZones());
if (!zone.active())
{
FatalErrorIn("label overlapGgiPolyPatch::zoneIndex() const")
<< "Face zone name " << zoneName_
<< " not found. Please check your GGI interface definition."
<< abort(FatalError);
}
zoneIndex_ = zone.index();
}
return zoneIndex_;
}
const Foam::overlapGgiPolyPatch&
Foam::overlapGgiPolyPatch::shadow() const
{
return refCast<const overlapGgiPolyPatch>(boundaryMesh()[shadowIndex()]);
}
const Foam::faceZone& Foam::overlapGgiPolyPatch::zone() const
{
return boundaryMesh().mesh().faceZones()[zoneIndex()];
}
Foam::label Foam::overlapGgiPolyPatch::nCopies() const
bool Foam::overlapGgiPolyPatch::localParallel() const
{
// Calculate patch-to-zone addressing
if (!localParallelPtr_)
{
calcLocalParallel();
}
return *localParallelPtr_;
}
const Foam::label& Foam::overlapGgiPolyPatch::nCopies() const
{
// Read the number of copies to be made from the dictionary for the
// expanded slave and expanded master to cover 360 degrees
@ -224,7 +318,7 @@ bool Foam::overlapGgiPolyPatch::master() const
// The first overlapggi interface is master,second one is slave
if (angle() == shadow().angle())
{
return start() < shadow().start() ;
return index() < shadowIndex();
}
// Master is the one with the larger angle
@ -242,6 +336,8 @@ void Foam::overlapGgiPolyPatch::write(Ostream& os) const
<< token::END_STATEMENT << nl;
os.writeKeyword("shadowPatch") << shadowName_
<< token::END_STATEMENT << nl;
os.writeKeyword("zone") << zoneName_
<< token::END_STATEMENT << nl;
}

View file

@ -37,6 +37,7 @@ Description
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved
Fethi Tekin, All rights reserved.
Oliver Borm, All rights reserved.
SourceFiles
overlapGgiPolyPatch.C
@ -50,6 +51,7 @@ SourceFiles
#include "coupledPolyPatch.H"
#include "standAlonePatch.H"
#include "overlapGgiInterpolation.H"
#include "faceZone.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -69,9 +71,14 @@ class overlapGgiPolyPatch
//- Shadow patch name
const word shadowName_;
//- Interpolation zone name
const word zoneName_;
//- Shadow patch index. Delayed evaluation for construction
mutable label shadowIndex_;
//- Interpolation zone index. Delayed evaluation for construction
mutable label zoneIndex_;
//- Rotation parameter for the overlap
@ -79,40 +86,34 @@ class overlapGgiPolyPatch
const vector rotationAxis_;
// Number of copies in order to complete 360 degrees
const scalar nCopies_;
const label nCopies_;
// Interpolation
//- Pointer to expanded master patch
mutable standAlonePatch* expandedMasterPtr_;
//- Pointer to expanded faceCentres of Master
mutable vectorField* faceCentresPtr_;
//- Pointer to expanded faceareas of Master
mutable vectorField* faceAreasPtr_;
//- Pointer to expanded slave patch
mutable standAlonePatch* expandedSlavePtr_;
//- Patch-to-expanded-patch interpolation
mutable overlapGgiInterpolation* patchToPatchPtr_;
//- Is the patch localised on a single processor
// (single processor in a parallel run)?
// Used for parallel optimisation
mutable bool* localParallelPtr_;
//- Reconstructed patch neighbour cell centres
mutable vectorField* reconFaceCellCentresPtr_;
//- Reconstructed patch neighbour cell centres
mutable vectorField* reconFaceCellCentresPtr_;
// Private member functions
//- Return reference to patch-to-patch interpolation
const overlapGgiInterpolation& patchToPatch() const;
//- Calculate expanded master patch
void calcExpandedMaster() const;
//- Calculate expanded slave patch
void calcExpandedSlave() const;
//- Calculate expanded patch geometry
standAlonePatch* calcExpandedGeometry(label ncp, label index) const;
//- Return reference to expanded master patch
const standAlonePatch& expandedMaster() const;
@ -120,6 +121,9 @@ class overlapGgiPolyPatch
//- Return reference to expanded slave patch
const standAlonePatch& expandedSlave() const;
//- Calculate local parallel switch
void calcLocalParallel() const;
//- Calculate interpolation
void calcPatchToPatch() const;
@ -132,6 +136,9 @@ class overlapGgiPolyPatch
//- Check definition: angles and offsets
void checkDefinition() const;
//- Clear geometry
void clearGeom();
//- Clear out
void clearOut();
@ -186,6 +193,7 @@ public:
const label index,
const polyBoundaryMesh& bm,
const word& shadowName,
const word& zoneName,
const vector& axis,
const scalar nCopies
);
@ -260,12 +268,24 @@ public:
return shadowName_;
}
//- Return name of interpolation face zone
const word& zoneName() const
{
return zoneName_;
}
//- Return shadow patch index
int shadowIndex() const;
label shadowIndex() const;
//- Return zone patch index
label zoneIndex() const;
//- Return shadow patch
const overlapGgiPolyPatch& shadow() const;
//- Return interpolation face zone
const faceZone& zone() const;
//- Return rotation axis
const vector& rotationAxis() const
{
@ -279,7 +299,7 @@ public:
}
//- Return number of slave copies
label nCopies() const;
const label& nCopies() const;
//- Is this the master side?
bool master() const;
@ -290,15 +310,14 @@ public:
return !master();
}
//- Expand master face field to full for 360 degrees coverage
template<class Type>
tmp<Field<Type> > expandMasterData(const Field<Type>& spf) const;
//- Is the patch localised on a single processor
bool localParallel() const;
//- Expand slave face field to full for 360 degrees coverage
//- Expand face field to full for 360 degrees coverage
template<class Type>
tmp<Field<Type> > expandSlaveData(const Field<Type>& spf) const;
tmp<Field<Type> > expandData(const Field<Type>& spf) const;
//- Interpolate face field: given field on a the shadow side,
//- Interpolate face field: given field on the shadow side,
// create an interpolated field on this side
template<class Type>
tmp<Field<Type> > interpolate(const Field<Type>& pf) const;
@ -306,6 +325,9 @@ public:
template<class Type>
tmp<Field<Type> > interpolate(const tmp<Field<Type> >& tpf) const;
//- Filter zone field to patch size
template<class Type>
tmp<Field<Type> > filter(const Field<Type>& zf) const;
//- Return reconstructed cell centres
const vectorField& reconFaceCellCentres() const;

View file

@ -25,6 +25,7 @@ License
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
Fethi Tekin, All rights reserved.
Oliver Borm, All rights reserved.
\*---------------------------------------------------------------------------*/
@ -39,206 +40,95 @@ Author
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::overlapGgiPolyPatch::calcExpandedMaster() const
// Create expanded patch
Foam::standAlonePatch*
Foam::overlapGgiPolyPatch::calcExpandedGeometry(label ncp, label index) const
{
// Create expanded master patch interpolation
if (expandedMasterPtr_)
const scalar myAngle = 360.0/scalar(ncp);
// Create expanded master points and faces
const faceZone& geomZone = boundaryMesh().mesh().faceZones()[index];
const primitiveFacePatch& geom = geomZone();
const pointField& geomLocalPoints = geom.localPoints();
pointField expandedPoints(ncp*geomLocalPoints.size());
// Transform points
label nPointsGeom = 0;
for (label copyI = 0; copyI < ncp; copyI++)
{
FatalErrorIn("void overlapGgiPolyPatch::calcExpandedMaster() const")
<< "Expanded master already calculated"
<< abort(FatalError);
// Calculate transform
const tensor curRotation =
RodriguesRotation(rotationAxis_, copyI*myAngle);
forAll (geomLocalPoints, pointI)
{
expandedPoints[nPointsGeom] =
transform(curRotation, geomLocalPoints[pointI]);
nPointsGeom++;
}
}
if (master())
// Transform faces
const faceList& geomLocalFaces = geom.localFaces();
faceList expandedFaces(ncp*geomLocalFaces.size());
label nFacesGeom = 0;
for (label copyI = 0; copyI < ncp; copyI++)
{
// Create expanded master patch
const label ncpm = nCopies();
const label copyOffsetGeom = copyI*geomLocalPoints.size();
// Create expanded master points and faces
const polyPatch& master = boundaryMesh()[index()];
const pointField& masterLocalPoints = master.localPoints();
pointField MasterExpandedPoints(ncpm*masterLocalPoints.size());
const scalar masterAngle = angle();
// Transform points
label nPoints_master = 0;
for (label copyI = 0; copyI < ncpm; copyI++)
forAll (geomLocalFaces, faceI)
{
// Calculate transform
const tensor curRotation =
RodriguesRotation(rotationAxis_, copyI*(masterAngle));
const face& curGeomFace = geomLocalFaces[faceI];
forAll (masterLocalPoints, pointI)
face& curExpandedFace = expandedFaces[nFacesGeom];
// Copy face with offsets
curExpandedFace.setSize(curGeomFace.size());
forAll (curGeomFace, fpI)
{
MasterExpandedPoints[nPoints_master] =
transform(curRotation, masterLocalPoints[pointI]);
nPoints_master++;
curExpandedFace[fpI] = curGeomFace[fpI] + copyOffsetGeom;
}
}
// Transform faces
const faceList& masterLocalFaces = master.localFaces();
faceList MasterExpandedFaces(ncpm*masterLocalFaces.size());
label nFacesMaster = 0;
for (label copyI = 0; copyI < ncpm; copyI++)
{
const label copyOffsetMaster = copyI*masterLocalPoints.size();
forAll (masterLocalFaces, faceI)
{
const face& curMasterFace = masterLocalFaces[faceI];
face& MastercurExpandedFace =
MasterExpandedFaces[nFacesMaster];
// Copy face with offsets
MastercurExpandedFace.setSize(curMasterFace.size());
forAll (curMasterFace, fpI)
{
MastercurExpandedFace[fpI] =
curMasterFace[fpI] + copyOffsetMaster;
}
nFacesMaster++;
}
}
expandedMasterPtr_ =
new standAlonePatch(MasterExpandedFaces, MasterExpandedPoints);
if (debug > 1)
{
Info << "Writing expanded master patch as VTK" << endl;
const polyMesh& mesh = boundaryMesh().mesh();
fileName fvPath(mesh.time().path()/"VTK");
mkDir(fvPath);
standAlonePatch::writeVTK
(
fvPath/fileName("expandedMaster" + name() + shadow().name()),
MasterExpandedFaces,
MasterExpandedPoints
);
nFacesGeom++;
}
}
else
if (debug > 1)
{
FatalErrorIn("void overlapGgiPolyPatch::calcExpandedMaster() const")
<< "Attempting to create expanded master on a shadow"
<< abort(FatalError);
Info << "Writing expanded geom patch as VTK" << endl;
const polyMesh& mesh = boundaryMesh().mesh();
fileName fvPath(mesh.time().path()/"VTK");
mkDir(fvPath);
OStringStream outputFilename;
outputFilename << "expandedGeom" << name() << shadow().name()
<< index << "_" << mesh.time().timeName();
standAlonePatch::writeVTK
(
fvPath/fileName(outputFilename.str()),
expandedFaces,
expandedPoints
);
}
return new standAlonePatch(expandedFaces, expandedPoints);
}
void Foam::overlapGgiPolyPatch::calcExpandedSlave() const
{
// Create expanded slave patch interpolation
if (expandedSlavePtr_)
{
FatalErrorIn("void overlapGgiPolyPatch::calcExpandedSlave() const")
<< "Expanded slave already calculated"
<< abort(FatalError);
}
if (master())
{
// Create expanded patch
const label ncp = shadow().nCopies();
// Create expanded points and faces
const polyPatch& slave = boundaryMesh()[shadowIndex()];
const pointField& slaveLocalPoints = slave.localPoints();
pointField expandedPoints(ncp*slaveLocalPoints.size());
const scalar slaveAngle = shadow().angle();
// Transform points
label nPoints = 0;
for (label copyI = 0; copyI < ncp; copyI++)
{
// Calculate transform
const tensor curRotation =
RodriguesRotation(rotationAxis_, copyI*slaveAngle);
forAll (slaveLocalPoints, pointI)
{
expandedPoints[nPoints] =
transform(curRotation, slaveLocalPoints[pointI]);
nPoints++;
}
}
// Transform faces
const faceList& slaveLocalFaces = slave.localFaces();
faceList expandedFaces(ncp*slaveLocalFaces.size());
label nFaces = 0;
for (label copyI = 0; copyI < ncp; copyI++)
{
const label copyOffset = copyI*slaveLocalPoints.size();
forAll (slaveLocalFaces, faceI)
{
const face& curSlaveFace = slaveLocalFaces[faceI];
face& curExpandedFace = expandedFaces[nFaces];
// Copy face with offsets
curExpandedFace.setSize(curSlaveFace.size());
forAll (curSlaveFace, fpI)
{
curExpandedFace[fpI] = curSlaveFace[fpI] + copyOffset;
}
nFaces++;
}
}
expandedSlavePtr_ = new standAlonePatch(expandedFaces, expandedPoints);
if (debug > 1)
{
Info << "Writing expanded slave patch as VTK" << endl;
const polyMesh& mesh = boundaryMesh().mesh();
fileName fvPath(mesh.time().path()/"VTK");
mkDir(fvPath);
standAlonePatch::writeVTK
(
fvPath/fileName("expandedSlave" + name() + shadow().name()),
expandedFaces,
expandedPoints
);
}
}
else
{
FatalErrorIn("void overlapGgiPolyPatch::calcExpandedSlave() const")
<< "Attempting to create expanded slave on a shadow"
<< abort(FatalError);
}
}
const Foam::standAlonePatch& Foam::overlapGgiPolyPatch::expandedMaster() const
{
if (!expandedMasterPtr_)
{
calcExpandedMaster();
expandedMasterPtr_ =
calcExpandedGeometry( nCopies(), zoneIndex() );
}
return *expandedMasterPtr_;
@ -248,7 +138,8 @@ const Foam::standAlonePatch& Foam::overlapGgiPolyPatch::expandedSlave() const
{
if (!expandedSlavePtr_)
{
calcExpandedSlave();
expandedSlavePtr_ =
calcExpandedGeometry( shadow().nCopies(), shadow().zoneIndex() );
}
return *expandedSlavePtr_;
@ -279,6 +170,21 @@ void Foam::overlapGgiPolyPatch::calcPatchToPatch() const
0, // master overlap tolerance
0 // slave overlap tolerance
);
// Abort immediatly if uncovered faces are present
if
(
patchToPatch().uncoveredMasterFaces().size() > 0
||
patchToPatch().uncoveredSlaveFaces().size() > 0
)
{
FatalErrorIn("void overlapGgiPolyPatch::calcPatchToPatch() const")
<< "Found uncovered faces for GGI interface "
<< name() << "/" << shadowName() << endl
<< "This is an unrecoverable error. Aborting."
<< abort(FatalError);
}
}
else
{
@ -324,11 +230,16 @@ void Foam::overlapGgiPolyPatch::calcReconFaceCellCentres() const
const label shadowID = shadowIndex();
// Get the transformed and interpolated shadow face cell centers
vectorField delta = boundaryMesh()[shadowID].faceCellCentres()
- boundaryMesh()[shadowID].faceCentres();
reconFaceCellCentresPtr_ =
new vectorField(interpolate(delta) + faceCentres());
new vectorField
(
interpolate
(
boundaryMesh()[shadowID].faceCellCentres()
- boundaryMesh()[shadowID].faceCentres()
)
+ faceCentres()
);
}
else
{
@ -368,7 +279,7 @@ void Foam::overlapGgiPolyPatch::checkDefinition() const
}
void Foam::overlapGgiPolyPatch::clearOut()
void Foam::overlapGgiPolyPatch::clearGeom()
{
deleteDemandDrivenData(expandedMasterPtr_);
deleteDemandDrivenData(expandedSlavePtr_);
@ -377,6 +288,13 @@ void Foam::overlapGgiPolyPatch::clearOut()
}
void Foam::overlapGgiPolyPatch::clearOut()
{
clearGeom();
deleteDemandDrivenData(localParallelPtr_);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::vectorField&
@ -399,14 +317,19 @@ void Foam::overlapGgiPolyPatch::initGeometry()
void Foam::overlapGgiPolyPatch::calcGeometry()
{
polyPatch::calcGeometry();
// Note: Calculation of transforms must be forced before the
// reconFaceCellCentres in order to correctly set the transformation
// in the interpolation routines.
// HJ, 3/Jul/2009
calcTransforms();
// Reconstruct the cell face centres
if (patchToPatchPtr_ && master())
{
reconFaceCellCentres();
}
calcTransforms();
polyPatch::calcGeometry();
}
@ -421,7 +344,7 @@ void Foam::overlapGgiPolyPatch::movePoints(const pointField& p)
polyPatch::movePoints(p);
// Force recalculation of interpolation
clearOut();
clearGeom();
}

View file

@ -24,7 +24,8 @@ License
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
Fethi Tekin, All rights reserved. fethitekin@gmail.com
Fethi Tekin, All rights reserved.
Oliver Borm, All rights reserved.
\*---------------------------------------------------------------------------*/
@ -35,15 +36,32 @@ Author
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::overlapGgiPolyPatch::expandSlaveData(const Field<Type>& spf) const
Foam::overlapGgiPolyPatch::expandData(const Field<Type>& pf) const
{
const scalar slaveAngle = shadow().angle();
// Check and expand the field from patch size to zone size
if (pf.size() != size())
{
FatalErrorIn
(
"tmp<Field<Type> > overlapGgiPolyPatch::expandData"
"("
" const Field<Type>& pf"
") const"
) << "Incorrect patch field size. Field size: "
<< pf.size() << " patch size: " << size()
<< abort(FatalError);
}
const label ncp = shadow().nCopies();
const label ncp = nCopies();
tmp<Field<Type> > tef(new Field<Type>(ncp*spf.size()));
const scalar myAngle = 360.0/scalar(ncp);
Field<Type>& ef = tef();
tmp<Field<Type> > texpandField
(
new Field<Type>( ncp*zone().size(), pTraits<Type>::zero )
);
Field<Type>& expandField = texpandField();
label nFaces = 0;
@ -51,77 +69,63 @@ Foam::overlapGgiPolyPatch::expandSlaveData(const Field<Type>& spf) const
{
// Calculate transform
const tensor curRotation =
RodriguesRotation(rotationAxis_, copyI*slaveAngle);
RodriguesRotation(rotationAxis_, copyI*myAngle);
forAll (spf, faceI)
forAll (pf, faceI)
{
ef[nFaces] = transform(curRotation, spf[faceI]);
expandField[nFaces] = transform(curRotation, pf[faceI]);
nFaces++;
}
}
return tef;
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::overlapGgiPolyPatch::expandMasterData(const Field<Type>& spf) const
{
const scalar masterAngle = shadow().angle();
const label ncpm = shadow().nCopies();
tmp<Field<Type> > tef(new Field<Type>(ncpm*spf.size()));
Field<Type>& ef = tef();
label nFaces = 0;
for (label copyI = 0; copyI < ncpm; copyI++)
if (!localParallel())
{
// Calculate transform
const tensor curRotation =
RodriguesRotation(rotationAxis_, copyI*(masterAngle));
forAll (spf, faceI)
{
ef[nFaces] = transform(curRotation, spf[faceI]);
nFaces++;
}
reduce(expandField, sumOp<Field<Type> >());
}
return tef;
return texpandField;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::overlapGgiPolyPatch::interpolate(const Field<Type>& pf) const
{
// Check and expand the field from patch size to zone size
if (pf.size() != shadow().size())
{
FatalErrorIn
(
"tmp<Field<Type> > ggiPolyPatch::interpolate"
"("
" const Field<Type>& pf"
") const"
) << "Incorrect slave patch field size. Field size: "
<< pf.size() << " patch size: " << shadow().size()
<< abort(FatalError);
}
// Expand data
tmp<Field<Type> > expanddata = shadow().expandData(pf);
tmp<Field<Type> > tresult;
if (master())
{
// Expand slave data
tmp<Field<Type> > expandslave = expandSlaveData(pf);
tmp<Field<Type> > tresult= patchToPatch().slaveToMaster(expandslave);
// Truncate to size
tresult().setSize(size());
return tresult;
tresult= patchToPatch().slaveToMaster(expanddata);
}
else
{
// Expand master data
tmp<Field<Type> > expandmaster = expandMasterData(pf);
tmp<Field<Type> > tresult = patchToPatch().masterToSlave(expandmaster);
// Truncate to size
tresult().setSize(size());
return tresult;
tresult = patchToPatch().masterToSlave(expanddata);
}
// Truncate to size
tresult().setSize(size());
return tresult;
}
@ -129,30 +133,9 @@ template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::overlapGgiPolyPatch::interpolate(const tmp<Field<Type> >& tpf) const
{
if (master())
{
// Expand slave data
tmp<Field<Type> > expand = expandSlaveData(tpf());
tmp<Field<Type> > tresult = patchToPatch().slaveToMaster(expand);
// Truncate to size
tresult().setSize(size());
return tresult;
}
else
{
// Expand master data
tmp<Field<Type> > expandmaster = expandMasterData(tpf());
tmp<Field<Type> > tresult = patchToPatch().masterToSlave(expandmaster);
// Truncate to size
tresult().setSize(size());
return tresult;
}
tmp<Field<Type> > tint = interpolate(tpf());
tpf.clear();
return tint;
}
// ************************************************************************* //

View file

@ -14,7 +14,6 @@ FoamFile
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dynamicFvMeshLib "libtopoChangerFvMesh.so";
dynamicFvMesh turboFvMesh;
turboFvMeshCoeffs
@ -29,9 +28,14 @@ turboFvMeshCoeffs
rpm
{
Rotor1 60;
Rotor2 -30;
Stator 0;
Rotor1 60;
Rotor2 -30;
}
slider
{
Rotor1_faceZone 60;
Rotor2_faceZone -30;
}
}

View file

@ -22,35 +22,17 @@ License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Instructions:
This tool is used to have multiple rotating regions around the same origin
with different rpms.
Creating the cellZones is not implemented in this tool.
The steps to obtain the cellZones are :
1) use regionCellSets utility. With this command you can have different
cellSets for each region.
2) Change the name of the regions eg. CellRegion0 to Rotor1 ,CellRegion1
to Stator and vice versa.
3) run command " setsToZones -noFlipMap ". After this command the
cellSets are transformed to cellZones.
4) in dynamicMeshDict rpm section should be added.
5) The case is ready to be run.
Implemented by Fethi Tekin, 24.03.2010
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
Fethi Tekin, All rights reserved.
Oliver Borm, All rights reserved.
\*---------------------------------------------------------------------------*/
#include "turboFvMesh.H"
#include "Time.H"
#include "addToRunTimeSelectionTable.H"
#include "ZoneIDs.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -63,26 +45,6 @@ namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::turboFvMesh::addZonesAndModifiers()
{
// Add zones and modifiers for motion action
// No functionality is implemented
if (cellZones().size() > 0)
{
Info<< "void turboFvMesh::addZonesAndModifiers() : "
<< "Zones and modifiers already present. Skipping."
<< endl;
return;
}
else
{
FatalErrorIn("turboFvMesh")
<< "Cell Regions have to be created"
<< abort(FatalError);
}
}
void Foam::turboFvMesh::calcMovingPoints() const
{
if (debug)
@ -99,8 +61,8 @@ void Foam::turboFvMesh::calcMovingPoints() const
<< abort(FatalError);
}
// Retrieve the zone Names
const wordList zoneNames = cellZones().names();
// Retrieve the cell zone Names
const wordList cellZoneNames = cellZones().names();
// Set the points
movingPointsPtr_ = new vectorField(allPoints().size(),vector::zero);
@ -110,36 +72,75 @@ void Foam::turboFvMesh::calcMovingPoints() const
const cellList& c = cells();
const faceList& f = allFaces();
forAll(zoneNames,zoneI)
scalar rpm;
forAll(cellZoneNames,cellZoneI)
{
Info<< "Moving Region Zone Name:" << zoneNames[zoneI]<< nl<<endl;
const labelList& cellAddr =
cellZones()[cellZones().findZoneID(zoneNames[zoneI])];
cellZones()[cellZones().findZoneID(cellZoneNames[cellZoneI])];
rpm_ = readScalar(dict_.subDict("rpm").lookup(zoneNames[zoneI]));
Info<< "rpm:" << rpm_<<nl<<endl;
forAll (cellAddr, cellI)
if (dict_.subDict("rpm").found(cellZoneNames[cellZoneI]))
{
const cell& curCell = c[cellAddr[cellI]];
rpm = readScalar(dict_.subDict("rpm").lookup(cellZoneNames[cellZoneI]));
forAll (curCell, faceI)
Info<< "Moving Cell Zone Name: " << cellZoneNames[cellZoneI]
<< " rpm: " << rpm << endl;
forAll (cellAddr, cellI)
{
const face& curFace = f[curCell[faceI]];
const cell& curCell = c[cellAddr[cellI]];
forAll (curFace, pointI)
{
// The rotation data is saved within the cell data. For
// non-rotating regions rpm is zero, so mesh movement is
// also zero. The conversion of rotational speed
forAll (curCell, faceI)
{
const face& curFace = f[curCell[faceI]];
// Note: deltaT changes during the run: moved to
// turboFvMesh::update(). HJ, 14/Oct/2010
movingPoints[curFace[pointI]] =
vector(0, rpm_/60.0*360.0, 0);
}
forAll (curFace, pointI)
{
// The rotation data is saved within the cell data. For
// non-rotating regions rpm is zero, so mesh movement
// is also zero. The conversion of rotational speed
// Note: deltaT changes during the run: moved to
// turboFvMesh::update(). HJ, 14/Oct/2010
movingPoints[curFace[pointI]] =
vector(0, rpm/60.0*360.0, 0);
}
}
}
}
}
// Retrieve the face zone Names
const wordList faceZoneNames = faceZones().names();
// This is not bullet proof, as one could specify the wrong name of a
// faceZone, which is then not selected. The solver will crash after the
// first meshMotion iteration.
forAll (faceZoneNames, faceZoneI)
{
if (dict_.subDict("slider").found(faceZoneNames[faceZoneI]))
{
rpm = readScalar
(
dict_.subDict("slider").lookup(faceZoneNames[faceZoneI])
);
Info<< "Moving Face Zone Name: " << faceZoneNames[faceZoneI]
<< " rpm: " << rpm << endl;
faceZoneID zoneID(faceZoneNames[faceZoneI], faceZones());
const labelList& movingSliderAddr = faceZones()[zoneID.index()];
forAll (movingSliderAddr, faceI)
{
const face& curFace = f[movingSliderAddr[faceI]];
forAll (curFace, pointI)
{
movingPoints[curFace[pointI]] =
vector( 0, rpm/60.0*360.0, 0);
}
}
}
}
@ -177,11 +178,8 @@ Foam::turboFvMesh::turboFvMesh
dict_.subDict("coordinateSystem")
)
),
movingPointsPtr_(NULL)
{
addZonesAndModifiers();
Info<< "Turbomachine Mixer mesh:" << nl
<< " origin: " << cs().origin() << nl
<< " axis : " << cs().axis() << endl;

View file

@ -26,11 +26,31 @@ Class
turboFvMesh
Description
Simple mixer mesh using an overlapGGI interface
Simple mixer mesh using an ggi interfaces
This tool is used to have multiple rotating regions around the same origin
with different rpms. Creating the cellZones is not implemented in this tool.
The steps to obtain the cellZones and faceZones are:
1) use regionCellSets utility. With this command you can have different
cellSets for each region.
2) run command "setsToZones -noFlipMap". After this command the
cellSets are transformed to cellZones.
4) for each rotating cellZone add an entry in rpm subDict of
constant/dynamicMeshDict
5) in parallel you need to create from all rotating coupled-interface
patches faceZones (if you use a ggi interface between you have already
created these faceZones), Then you need to specify these faceZones with
the corresponding rpm in the additional "slider" subDict in
constant/dynamicMeshDict
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
Fethi Tekin, All rights reserved.
Oliver Borm, All rights reserved.
SourceFiles
turboFvMesh.C
@ -64,9 +84,6 @@ class turboFvMesh
//- Coordinate system
autoPtr<coordinateSystem> csPtr_;
// - Rotational speed in rotations per minute (rpm)
mutable scalar rpm_;
//- Markup field for points.
mutable vectorField* movingPointsPtr_;
@ -79,10 +96,6 @@ class turboFvMesh
//- Disallow default bitwise assignment
void operator=(const turboFvMesh&);
//- Add mixer zones
void addZonesAndModifiers();
//- Calculate moving Points
void calcMovingPoints() const;

View file

@ -446,6 +446,47 @@ void Foam::MRFZone::absoluteFlux
absoluteRhoFlux(rho, phi);
}
void Foam::MRFZone::faceU
(
surfaceVectorField& zoneFaceU
) const
{
const surfaceVectorField& Cf = mesh_.Cf();
const vector& origin = origin_.value();
const vector& Omega = Omega_.value();
// Internal faces
forAll(internalFaces_, i)
{
label facei = internalFaces_[i];
zoneFaceU[facei] = (Omega ^ (Cf[facei] - origin));
}
// Included patches
forAll(includedFaces_, patchi)
{
forAll(includedFaces_[patchi], i)
{
label patchFacei = includedFaces_[patchi][i];
zoneFaceU.boundaryField()[patchi][patchFacei] =
(Omega ^ (Cf.boundaryField()[patchi][patchFacei] - origin));
}
}
// Excluded patches
forAll(excludedFaces_, patchi)
{
forAll(excludedFaces_[patchi], i)
{
label patchFacei = excludedFaces_[patchi][i];
zoneFaceU.boundaryField()[patchi][patchFacei] =
(Omega ^ (Cf.boundaryField()[patchi][patchFacei] - origin));
}
}
}
void Foam::MRFZone::correctBoundaryVelocity(volVectorField& U) const
{

View file

@ -199,6 +199,9 @@ public:
surfaceScalarField& phi
) const;
//- Compute the pseudo face velocity of the MRF region
void faceU(surfaceVectorField& zoneFaceU) const;
//- Correct the boundary velocity for the roation of the MRF region
void correctBoundaryVelocity(volVectorField& U) const;

View file

@ -28,7 +28,6 @@ License
#include "fvMesh.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "geometricOneField.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //

View file

@ -85,6 +85,33 @@ Foam::tmp<Foam::surfaceScalarField> Foam::MRFZones::fluxCorrection() const
return tMRFZonesPhiCorr;
}
Foam::tmp<Foam::surfaceVectorField> Foam::MRFZones::faceU() const
{
tmp<surfaceVectorField> tMRFZonesFaceU
(
new surfaceVectorField
(
IOobject
(
"MRFZonesFaceU",
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
dimensionedVector("zero", dimVelocity, vector::zero)
)
);
surfaceVectorField& MRFZonesFaceU = tMRFZonesFaceU();
forAll(*this, i)
{
operator[](i).faceU(MRFZonesFaceU);
}
return tMRFZonesFaceU;
}
void Foam::MRFZones::addCoriolis(fvVectorMatrix& UEqn) const
{

View file

@ -81,6 +81,9 @@ public:
//- Return raw correction flux
tmp<surfaceScalarField> fluxCorrection() const;
//- Return pseudo mesh flux
tmp<surfaceVectorField> faceU() const;
// Incompressible MRF
//- Add the Coriolis force contribution to the momentum equation

View file

@ -40,13 +40,17 @@ boundaryField
type movingWallVelocity;
value uniform (0 0 0);
}
rotor_cyclics
rotor_cyclic_upper
{
type cyclic;
type cyclicGgi;
}
rotor_cyclic_lower
{
type cyclicGgi;
}
stator_cyclics
{
type cyclic;
type cyclic;
}
interface1
{

View file

@ -37,9 +37,13 @@ boundaryField
{
type zeroGradient;
}
rotor_cyclics
rotor_cyclic_upper
{
type cyclic;
type cyclicGgi;
}
rotor_cyclic_lower
{
type cyclicGgi;
}
stator_cyclics
{

View file

@ -4,10 +4,16 @@
. $WM_PROJECT_DIR/bin/tools/CleanFunctions
cleanCase
rm -rf VTK log*
rm -rf constant/polyMesh/points* \
constant/polyMesh/face* \
constant/polyMesh/owner* \
constant/polyMesh/neighbour* \
constant/polyMesh/*Zones* \
constant/polyMesh/sets
rm -rf constant/polyMesh/boundary
# rm -rf VTK log*
# rm -rf constant/polyMesh/points* \
# constant/polyMesh/face* \
# constant/polyMesh/owner* \
# constant/polyMesh/neighbour* \
# constant/polyMesh/*Zones* \
# constant/polyMesh/sets
#
# rm -rf processor*
find -iname "*~" | xargs rm -rf

View file

@ -6,6 +6,9 @@ application="icoDyMFoam"
runApplication blockMesh
cp constant/polyMesh/boundary.org constant/polyMesh/boundary
runApplication setSet -batch setBatch
runApplication regionCellSets
runApplication setsToZones -noFlipMap
runApplication $application
runApplication decomposePar
# # runApplication $application
runParallel icoDyMFoam 4

View file

@ -29,7 +29,14 @@ turboFvMeshCoeffs
rpm
{
cellRegion0 60;
cellRegion1 0;
// cellRegion1 0;
}
slider
{
interface1_faces 60;
rotor_cyclic_upper_faces 60;
rotor_cyclic_lower_faces 60;
}
}

View file

@ -96,10 +96,13 @@ patches
(12 14 15 13)
(0 2 3 1)
)
cyclic rotor_cyclics
cyclicGgi rotor_cyclic_upper
(
(14 16 17 15)
)
cyclicGgi rotor_cyclic_lower
(
(2 4 5 3)
(14 16 17 15)
)
cyclic stator_cyclics
(

View file

@ -1,78 +0,0 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM Extend Project: Open Source CFD |
| \\ / O peration | Version: 1.6-ext |
| \\ / A nd | Web: www.extend-project.de |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class polyBoundaryMesh;
location "constant/polyMesh";
object boundary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
8
(
inlet
{
type patch;
nFaces 200;
startFace 28100;
}
outlet
{
type patch;
nFaces 200;
startFace 28300;
}
fixedWalls
{
type wall;
nFaces 1400;
startFace 28500;
}
movingwalls
{
type patch;
nFaces 1400;
startFace 29900;
}
rotor_cyclics
{
type cyclic;
nFaces 100;
startFace 31300;
featureCos 0.9;
}
stator_cyclics
{
type cyclic;
nFaces 100;
startFace 31400;
featureCos 0.9;
}
interface1
{
type overlapGgi;
nFaces 200;
startFace 31500;
rotationAxis (0 0 1);
nCopies 0;
shadowPatch ;
}
interface2
{
type overlapGgi;
nFaces 200;
startFace 31700;
rotationAxis (0 0 1);
nCopies 0;
shadowPatch ;
}
)
// ************************************************************************* //

View file

@ -1,6 +1,6 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM Extend Project: Open Source CFD |
| \\ / F ield | OpenFOAM Extend Project: Open source CFD |
| \\ / O peration | Version: 1.6-ext |
| \\ / A nd | Web: www.extend-project.de |
| \\/ M anipulation | |
@ -15,7 +15,7 @@ FoamFile
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
8
9
(
inlet
{
@ -41,12 +41,29 @@ FoamFile
nFaces 1400;
startFace 29900;
}
rotor_cyclics
rotor_cyclic_upper
{
type cyclic;
nFaces 100;
type cyclicGgi;
nFaces 50;
startFace 31300;
featureCos 0.9;
shadowPatch rotor_cyclic_lower;
zone rotor_cyclic_upper_faces;
bridgeOverlap false;
rotationAxis (0 0 1);
rotationAngle -30;
separationOffset (0 0 0);
}
rotor_cyclic_lower
{
type cyclicGgi;
nFaces 50;
startFace 31350;
shadowPatch rotor_cyclic_upper;
zone rotor_cyclic_lower_faces;
bridgeOverlap false;
rotationAxis (0 0 1);
rotationAngle 30;
separationOffset (0 0 0);
}
stator_cyclics
{
@ -63,6 +80,7 @@ FoamFile
rotationAxis (0 0 1);
nCopies 12;
shadowPatch interface2;
zone interface1_faces;
}
interface2
{
@ -72,6 +90,7 @@ FoamFile
rotationAxis (0 0 1);
nCopies 12;
shadowPatch interface1;
zone interface2_faces;
}
)

View file

@ -0,0 +1,5 @@
faceSet interface1_faces new patchToFace interface1
faceSet interface2_faces new patchToFace interface2
faceSet rotor_cyclic_upper_faces new patchToFace rotor_cyclic_upper
faceSet rotor_cyclic_lower_faces new patchToFace rotor_cyclic_lower
quit

View file

@ -16,13 +16,13 @@ FoamFile
application icoDyMFoam;
startFrom latestTime;
startFrom startTime;
startTime 0;
stopAt endTime;
endTime 1;
endTime 1;
deltaT 0.0001;
@ -43,6 +43,7 @@ timeFormat general;
timePrecision 4;
runTimeModifiable yes;
adjustTimeStep yes;
maxCo 0.8;

View file

@ -0,0 +1,77 @@
/*---------------------------------------------------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: 1.0 |
| \\ / A nd | Web: http://www.openfoam.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object decomposeParDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Keep owner and neighbour on same processor for faces in zones:
// preserveFaceZones ( interface1_faces interface2_faces );
//- Keep owner and neighbour on same processor for faces in patches:
// preservePatches ( interface1 interface2 );
globalFaceZones
(
interface1_faces
interface2_faces
rotor_cyclic_upper_faces
rotor_cyclic_lower_faces
); // Those are the names of the face zones created previously
numberOfSubdomains 4; // The problem will be decomposed in 4 different processors
method scotch;
// method metis;
simpleCoeffs
{
n (2 2 1);
delta 0.001;
}
metisCoeffs
{
/*
processorWeights
(
1
1
1
1
);
*/
}
scotchCoeffs
{
//processorWeights
//(
// 1
// 1
// 1
// 1
//);
//writeGraph true;
//strategy "b";
}
distributed no;
roots
(
);
// ************************************************************************* //