ENH: Added initial support for particle tracking across AMI patches

This commit is contained in:
andy
2013-08-14 15:54:40 +01:00
parent 43d09748f7
commit 8e79bf1b82
7 changed files with 278 additions and 7 deletions

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -44,16 +44,22 @@ void Foam::Cloud<ParticleType>::checkPatches() const
{ {
if (isA<cyclicAMIPolyPatch>(pbm[patchI])) if (isA<cyclicAMIPolyPatch>(pbm[patchI]))
{ {
ok = false; const cyclicAMIPolyPatch& cami =
break; refCast<const cyclicAMIPolyPatch>(pbm[patchI]);
if (cami.owner())
{
ok = ok && (cami.AMI().singlePatchProc() != -1);
}
} }
} }
if (!ok) if (!ok)
{ {
WarningIn("void Foam::Cloud<ParticleType>::initCloud(const bool)") FatalErrorIn("void Foam::Cloud<ParticleType>::initCloud(const bool)")
<< "Particle tracking across AMI patches is not currently " << "Particle tracking across AMI patches is only currently "
<< "supported" << endl; << "supported for cases where the AMI patches reside on a "
<< "single processor" << abort(FatalError);
} }
} }

View File

@ -257,6 +257,15 @@ protected:
template<class TrackData> template<class TrackData>
void hitCyclicPatch(const cyclicPolyPatch&, TrackData& td); void hitCyclicPatch(const cyclicPolyPatch&, TrackData& td);
//- Overridable function to handle the particle hitting a cyclicAMIPatch
template<class TrackData>
void hitCyclicAMIPatch
(
const cyclicAMIPolyPatch&,
TrackData& td,
const vector& direction
);
//- Overridable function to handle the particle hitting a //- Overridable function to handle the particle hitting a
// processorPatch // processorPatch
template<class TrackData> template<class TrackData>

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -26,6 +26,7 @@ License
#include "IOPosition.H" #include "IOPosition.H"
#include "cyclicPolyPatch.H" #include "cyclicPolyPatch.H"
#include "cyclicAMIPolyPatch.H"
#include "processorPolyPatch.H" #include "processorPolyPatch.H"
#include "symmetryPolyPatch.H" #include "symmetryPolyPatch.H"
#include "wallPolyPatch.H" #include "wallPolyPatch.H"
@ -598,6 +599,15 @@ Foam::scalar Foam::particle::trackToFace
static_cast<const cyclicPolyPatch&>(patch), td static_cast<const cyclicPolyPatch&>(patch), td
); );
} }
else if (isA<cyclicAMIPolyPatch>(patch))
{
p.hitCyclicAMIPatch
(
static_cast<const cyclicAMIPolyPatch&>(patch),
td,
endPosition - position_
);
}
else if (isA<processorPolyPatch>(patch)) else if (isA<processorPolyPatch>(patch))
{ {
p.hitProcessorPatch p.hitProcessorPatch
@ -1010,6 +1020,78 @@ void Foam::particle::hitCyclicPatch
} }
template<class TrackData>
void Foam::particle::hitCyclicAMIPatch
(
const cyclicAMIPolyPatch& cpp,
TrackData& td,
const vector& direction
)
{
const cyclicAMIPolyPatch& receiveCpp = cpp.neighbPatch();
// patch face index on sending side
label patchFaceI = faceI_ - cpp.start();
// patch face index on receiving side - also updates position
patchFaceI = cpp.pointFace(patchFaceI, direction, position_);
if (patchFaceI < 0)
{
FatalErrorIn
(
"template<class TrackData>"
"void Foam::particle::hitCyclicAMIPatch"
"("
"const cyclicAMIPolyPatch&, "
"TrackData&, "
"const vector&"
")"
)
<< "Particle lost across " << cyclicAMIPolyPatch::typeName
<< " patches " << cpp.name() << " and " << receiveCpp.name()
<< " at position " << position_ << abort(FatalError);
}
// convert face index into global numbering
faceI_ = patchFaceI + receiveCpp.start();
cellI_ = mesh_.faceOwner()[faceI_];
tetFaceI_ = faceI_;
// See note in correctAfterParallelTransfer for tetPtI_ addressing.
tetPtI_ = mesh_.faces()[tetFaceI_].size() - 1 - tetPtI_;
// Now the particle is on the receiving side
// Have patch transform the position
receiveCpp.transformPosition(position_, patchFaceI);
// Transform the properties
if (!receiveCpp.parallel())
{
const tensor& T =
(
receiveCpp.forwardT().size() == 1
? receiveCpp.forwardT()[0]
: receiveCpp.forwardT()[patchFaceI]
);
transformProperties(T);
}
else if (receiveCpp.separated())
{
const vector& s =
(
(receiveCpp.separation().size() == 1)
? receiveCpp.separation()[0]
: receiveCpp.separation()[patchFaceI]
);
transformProperties(-s);
}
}
template<class TrackData> template<class TrackData>
void Foam::particle::hitProcessorPatch(const processorPolyPatch&, TrackData&) void Foam::particle::hitProcessorPatch(const processorPolyPatch&, TrackData&)
{} {}

View File

@ -1248,6 +1248,114 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToTarget
} }
template<class SourcePatch, class TargetPatch>
Foam::label Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcPointFace
(
const SourcePatch& srcPatch,
const TargetPatch& tgtPatch,
const vector& n,
const label tgtFaceI,
point& tgtPoint
)
const
{
const pointField& srcPoints = srcPatch.points();
// source face addresses that intersect target face tgtFaceI
const labelList& addr = tgtAddress_[tgtFaceI];
forAll(addr, i)
{
label srcFaceI = addr[i];
const face& f = srcPatch[tgtFaceI];
pointHit ray = f.ray(tgtPoint, n, srcPoints);
if (ray.hit())
{
tgtPoint = ray.rawPoint();
return srcFaceI;
}
}
// no hit registered - try with face normal instead of input normal
forAll(addr, i)
{
label srcFaceI = addr[i];
const face& f = srcPatch[tgtFaceI];
vector nFace(-srcPatch.faceNormals()[srcFaceI]);
nFace += tgtPatch.faceNormals()[tgtFaceI];
pointHit ray = f.ray(tgtPoint, nFace, srcPoints);
if (ray.hit())
{
tgtPoint = ray.rawPoint();
return srcFaceI;
}
}
return -1;
}
template<class SourcePatch, class TargetPatch>
Foam::label Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtPointFace
(
const SourcePatch& srcPatch,
const TargetPatch& tgtPatch,
const vector& n,
const label srcFaceI,
point& srcPoint
)
const
{
const pointField& tgtPoints = tgtPatch.points();
// target face addresses that intersect source face srcFaceI
const labelList& addr = srcAddress_[srcFaceI];
forAll(addr, i)
{
label tgtFaceI = addr[i];
const face& f = tgtPatch[tgtFaceI];
pointHit ray = f.ray(srcPoint, n, tgtPoints);
if (ray.hit())
{
srcPoint = ray.rawPoint();
return tgtFaceI;
}
}
// no hit registered - try with face normal instead of input normal
forAll(addr, i)
{
label tgtFaceI = addr[i];
const face& f = tgtPatch[tgtFaceI];
vector nFace(-srcPatch.faceNormals()[srcFaceI]);
nFace += tgtPatch.faceNormals()[tgtFaceI];
pointHit ray = f.ray(srcPoint, n, tgtPoints);
if (ray.hit())
{
srcPoint = ray.rawPoint();
return tgtFaceI;
}
}
return -1;
}
template<class SourcePatch, class TargetPatch> template<class SourcePatch, class TargetPatch>
void Foam::AMIInterpolation<SourcePatch, TargetPatch>::writeFaceConnectivity void Foam::AMIInterpolation<SourcePatch, TargetPatch>::writeFaceConnectivity
( (

View File

@ -454,6 +454,31 @@ public:
) const; ) const;
// Point intersections
//- Return source patch face index of point on target patch face
label srcPointFace
(
const SourcePatch& srcPatch,
const TargetPatch& tgtPatch,
const vector& n,
const label tgtFaceI,
point& tgtPoint
)
const;
//- Return target patch face index of point on source patch face
label tgtPointFace
(
const SourcePatch& srcPatch,
const TargetPatch& tgtPatch,
const vector& n,
const label srcFaceI,
point& srcPoint
)
const;
// Checks // Checks
//- Write face connectivity as OBJ file //- Write face connectivity as OBJ file

View File

@ -797,6 +797,38 @@ bool Foam::cyclicAMIPolyPatch::order
} }
Foam::label Foam::cyclicAMIPolyPatch::pointFace
(
const label faceI,
const vector& n,
point& p
) const
{
if (owner())
{
return AMI().tgtPointFace
(
*this,
neighbPatch(),
n,
faceI,
p
);
}
else
{
return neighbPatch().AMI().srcPointFace
(
neighbPatch(),
*this,
n,
faceI,
p
);
}
}
void Foam::cyclicAMIPolyPatch::write(Ostream& os) const void Foam::cyclicAMIPolyPatch::write(Ostream& os) const
{ {
coupledPolyPatch::write(os); coupledPolyPatch::write(os);

View File

@ -367,6 +367,15 @@ public:
labelList& rotation labelList& rotation
) const; ) const;
//- Return face index on neighbour patch which shares point p
// following trajectory vector n
label pointFace
(
const label faceI,
const vector& n,
point& p
) const;
//- Write the polyPatch data as a dictionary //- Write the polyPatch data as a dictionary
virtual void write(Ostream&) const; virtual void write(Ostream&) const;
}; };