CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM > OpenFOAM Running, Solving & CFD

patchInteractionModel vs collisionModel in DPMFoam

Register Blogs Community New Posts Updated Threads Search

Like Tree4Likes
  • 2 Post By dscian
  • 2 Post By richardt

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   July 5, 2023, 09:10
Default patchInteractionModel vs collisionModel in DPMFoam
  #1
New Member
 
Jon
Join Date: Mar 2013
Posts: 15
Rep Power: 13
CHUIKOV is on a distinguished road
Dear Foamers,

I'm dealing with a case in DPMFoam (ESI v2106) in which I need to consider both particle-wall interactions and interparticle collisions.

I'm a bit confused as to the right model input in kinematicCloudProperties, since I see that both patchInteractionModel localInteraction and collisionModel pairCollision both have parameters about the interaction with the wall.

any idea what is the right combination to include? which model has priority por particle - wall interactions if both patchInteraction and collisionModel are active?

many thanks in advance,

J
CHUIKOV is offline   Reply With Quote

Old   July 9, 2023, 17:47
Default
  #2
Member
 
Utkan Caliskan
Join Date: Aug 2014
Posts: 42
Rep Power: 12
dscian is on a distinguished road
When the colliding cloud (DPMFoam) is used the patchInteractionModel becomes dummy because patchInteractionModel for general lagrangian considers the centre of the particle to touch the wall. However, with DPMFoam, the surface of the particle touches the wall due to the wall collision model of collisionModel. Since the center of the particle won't touch the wall, patchInteractionModel will have no effect.
CHUIKOV and rezaeimahdi like this.

Last edited by dscian; July 9, 2023 at 21:50.
dscian is offline   Reply With Quote

Old   February 8, 2024, 10:16
Default
  #3
New Member
 
Richard Tribess
Join Date: Jul 2021
Posts: 8
Rep Power: 5
richardt is on a distinguished road
Greetings,

I think that this post is somehow related with the issue that I am currently facing - implementing a particle-wall deposition model.

In OF8 and OF1812, when using the kinematicCloud, we check if the center of mass of the parcel is intercepted by a boundaryFace in order to activate a patchInteractionModel. This means that we do not consider the real size of the parcel during the wall collision.

One way around this would be to use the collidingCloud, however, as stated by dscian, we can never activate the patchInteractionModel if the center of mass of the parcel does not touch the wall patch.

Does anyone know if there is a way to account for the real size of the parcel when it interacts with a wall boundary face when using the kinematicParcel? Furthermore, how would one activate the patchInteractionModel when the parcel radius is larger than the boundary cell size, and it collides with the wall while it is still outside the boundary cell?

We only activate a patchInteractionModel when a parcel hits a boundary face using the function "particle::hitFace". It would be interesting to be able to activate it when the distance between the center of mass and the wall boundary patch is smaller than the particle radius, and not only when the parcel intercepts a boundary cell face.

I managed to remove a particle from the domain while it was not at a boundary cell by modifying the hitFace algorithm as follows:

template<class TrackCloudType>
void Foam:article::hitFace
(
const vector& direction,
TrackCloudType& cloud,
trackingData& td
)
{
typename TrackCloudType:articleType& p =
static_cast<typename TrackCloudType:articleType&>(*this);
typename TrackCloudType:articleType::trackingData& ttd =
static_cast<typename TrackCloudType:articleType::trackingData&>(td);

scalar wallDist = cloud.wallDistance()[p.cell()];

if (!onFace())
{
return;
}
else if (onInternalFace())
{
if(wallDist <= p.d()/2.0)
{
td.keepParticle = false;
}
else
{
changeCell();
}
}

...

}

I tried to call the "p.hitWallPatch" function inside the proposed condition in order to activate the patchInteractionModel, but it did not worked, because the face that crossed the parcel path was an internal face and not a boundary face (obviously). Also, I really don't like the idea of checking this condition only when the parcel hits a face.

Would anyone have suggestions on how to implement this?

Thank you very much.
richardt is offline   Reply With Quote

Old   February 19, 2024, 12:51
Default
  #4
New Member
 
Richard Tribess
Join Date: Jul 2021
Posts: 8
Rep Power: 5
richardt is on a distinguished road
So, in case anyone is struggling with the same issue, I have managed to activate a patchInteractionModel for parcels that are not on a boundary face - in my case, at a wall patch.

The way around that I found was to ignore the class "patchData" (you have no access to it if p.face() is not equal to a boundaryFace ID) and get the required patch information from the mesh. We must first find the patchFacei that belongs to the celli on which the parcel is currently located.

For example, in the Rebound.C "patchInteractionModel::correct" function:

template<class CloudType>
bool Foam::IVT_Rebound<CloudType>::correct
(
typename CloudType:arcelType& p,
const polyPatch& pp,
bool& keepParticle
)
{
vector& U = p.U();

keepParticle = true;
p.active(true);

// Not getting patch information from the class patchData
/*
vector nw;
vector Up;

this->owner().patchData(p, pp, nw, Up);
*/
const fvMesh& mesh_ = this->owner().mesh();

label patchFacei = -1;

const volVectorField& U_ =
this->owner().mesh().objectRegistry::lookupObject<volVe ctorField>("U");

//- Patch of interest : wall
const label patchWallID = mesh_.boundaryMesh().findPatchID("wall");
const label patchAtmosphereID = mesh_.boundaryMesh().findPatchID("atmosphere");
const polyPatch& wall = mesh_.boundaryMesh()[patchWallID];
const polyPatch& atmosphere = mesh_.boundaryMesh()[patchAtmosphereID];
const label patchAtmosphereFaces = atmosphere.size();

const fvPatchVectorField Upatch_ = U_.boundaryField()[patchWall];
const vectorField nw_ = mesh_.Sf().boundaryField()[patchWall]/mesh_.magSf().boundaryField()[patchWall];

//- List of cells that owns the cellFaces of the patch of interest
const labelUList& wallBoundaryCells = wall.faceCells();

forAll(wallBoundaryCells, i)
{
//- Get the wallBoundaryCells labels
const label wallBoundaryCell = wallBoundaryCells[i];

//- Find the wallBoundaryCell in which the parcel is located
//- (check if the cell labels are the same)
if(wallBoundaryCell == p.cell())
{
//- Find the labels of the cellFaces that belong to the wallBoundaryCell
const cell& cellFaces = mesh_.cells()[wallBoundaryCell];

//- Fin the labels of facesi that belongs to to celli
forAll(cellFaces, j)
{
const label& cellFaceID = cellFaces[j];

//- Get the boundary cell face ID
if(cellFaceID > mesh_.nInternalFaces())
{
//- Attribute the new value the patchFacei (patch faces are numbered from 0
//- to n, not the same way as boundaryFaces, so we have to subtract the
//- internalFaces and the other boundaryFaces)
patchFacei = cellFaceID - mesh_.nInternalFaces() - patchAtmosphereFaces;
break;
}
}
break;
}
}

//- Attribute the values of Up and nw at the cellBoundaryFace on which the parcel is located
const vector Up_ = Upatch_[patchFacei];
const vector nwi_ = nw_[patchFacei];

// Calculate motion relative to patch velocity
U -= Up_;

scalar Un = U & nwi_;

if (Un > 0.0)
{
U -= UFactor_*2.0*Un*nwi_;
}

// Return velocity to global space
U += Up_;

return true;
}

Then, I have the call for the "patchInteractionModel::correct()" function in the "kinematicParcel::move()" function - after the "p.hitFace()" call. In there, we check if the distance between the center of mass and the wall patch is smaller than the radius of the parcel. If it is, we activate the patchInteractionModel. The wallDistance field is obtained from wallDist.H, interpolated to the parcel position. Be sure to update this field in your solver if you use AMR.

In KinematicCloud.C move function:

...

if (p.onFace() && ttd.keepParticle)
{
p.hitFace(s, cloud, ttd);
}

//----------------------------------------------------------------------------------------------//
// Creates an artificial cell face at the position of the parcel + an offset equal to //
// the parcel radius in order to account for the parcel size during an interaction //
// with a wall patch (so that we can activate a patchInteractionModel even if the //
// parcel is not at a boundaryFace). //
//----------------------------------------------------------------------------------------------//

const polyMesh& mesh_ = this->mesh();

//- Interpolates the value of the wallDist function to the parcel position
//- In kinematicCloudProperties -> interpolationSchemes -> y -> cellPointFace
scalar wallDist = td.wallDistance();

//- Patch of interest - wall patch for the activation of wallDepositionModels
const label patchWallID = mesh_.boundaryMesh().findPatchID("solidWalls");
const polyPatch& wall = mesh_.boundaryMesh()[patchWallID];

//- List of cells that own the cellFaces of the patch of interest
const labelUList& wallBoundaryCells = wall.faceCells();

//- List of cells that own the other patches
const labelUList& atmosphereBoundaryCells = atmosphere.faceCells();

forAll(wallBoundaryCells, i)
{
//- Get the wallBoundaryCells labels
const label wallBoundaryCell = wallBoundaryCells[i];

//- Find the wallBoundaryCell in which the parcel is located
//- (check if the cell labels are the same)
if(wallBoundaryCell == p.cell())
{
//- Find the labels of the cellFaces that belong to the wallBoundaryCell
const cell& cellFaces = mesh_.cells()[wallBoundaryCell];

forAll(cellFaces, j)
{
//- Find the label of the wallBoundaryFace of the cell on which the
//- parcel is located
const label& cellFaceID = cellFaces[j];

//- Check if the distance between the center of mass and the wall is
//- smaller than the parcel radius
if(cellFaceID > mesh_.nInternalFaces() && wallDist <= p.d()/2.0)
{
//- Calls the patchInteractionModel and returns bool keepParticle
//- (in my case this is important for the deposition model)

const polyPatch& pp = wall;

cloud.patchInteraction().correct(p, pp, ttd.keepParticle);
return ttd.keepParticle;

break;
}
}
break;
}
}

//----------------------------------------------------------------------------------------------//

}

...

In the attached image, the white line represents the offset from the wall equal to the particle radius. When the center of mass of the parcel hits the "offset wall face" the patchInteractionModel is activated.


We have to be careful if a localInteraction patchInteractionModel is employed. I have used my case specific patchNames when getting the patch information. This approach is limited to a boundary cell size (height) larger than the particle radius, but I have some idea of how to make it general.

Plese, feel free to tell me if this is nonsense or to give any suggestions in order to improve this idea. Would it now be possible to employ the collidingCloud particle-particle collision models together with patchInteractionModels?
CHUIKOV and swint like this.
richardt is offline   Reply With Quote

Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Unrealistic result with DPMFoam Turhan OpenFOAM Running, Solving & CFD 1 July 23, 2024 09:48
Adding heat generation and transfer to DPMFoam inc. buoyancy of fluid dussa OpenFOAM Programming & Development 4 July 8, 2022 13:35
DESHybrid with DPMFoam / DPMDyMFoam jairoandres OpenFOAM Running, Solving & CFD 2 February 28, 2020 19:15
particle time-step in DPMFoam Shuai_W OpenFOAM Running, Solving & CFD 11 May 24, 2018 12:49
DPMFoam - Serious Error --particle-laden flow in simple geometric config benz25 OpenFOAM Running, Solving & CFD 27 December 19, 2017 21:47


All times are GMT -4. The time now is 09:14.