mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: Added initial support for particle tracking across AMI patches
This commit is contained in:
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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&)
|
||||||
{}
|
{}
|
||||||
|
|||||||
@ -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
|
||||||
(
|
(
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user