|
[Sponsors] |
patchInteractionModel vs collisionModel in DPMFoam |
![]() |
|
LinkBack | Thread Tools | Search this Thread | Display Modes |
![]() |
![]() |
#1 |
New Member
Jon
Join Date: Mar 2013
Posts: 15
Rep Power: 13 ![]() |
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 |
|
![]() |
![]() |
![]() |
![]() |
#2 |
Member
Utkan Caliskan
Join Date: Aug 2014
Posts: 42
Rep Power: 12 ![]() |
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.
Last edited by dscian; July 9, 2023 at 20:50. |
|
![]() |
![]() |
![]() |
![]() |
#3 |
New Member
Richard Tribess
Join Date: Jul 2021
Posts: 7
Rep Power: 5 ![]() |
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: ![]() ( const vector& direction, TrackCloudType& cloud, trackingData& td ) { typename TrackCloudType: ![]() static_cast<typename TrackCloudType: ![]() typename TrackCloudType: ![]() static_cast<typename TrackCloudType: ![]() 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. |
|
![]() |
![]() |
![]() |
![]() |
#4 |
New Member
Richard Tribess
Join Date: Jul 2021
Posts: 7
Rep Power: 5 ![]() |
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: ![]() 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? |
|
![]() |
![]() |
![]() |
|
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
Unrealistic result with DPMFoam | Turhan | OpenFOAM Running, Solving & CFD | 1 | July 23, 2024 08:48 |
Adding heat generation and transfer to DPMFoam inc. buoyancy of fluid | dussa | OpenFOAM Programming & Development | 4 | July 8, 2022 12:35 |
DESHybrid with DPMFoam / DPMDyMFoam | jairoandres | OpenFOAM Running, Solving & CFD | 2 | February 28, 2020 18:15 |
particle time-step in DPMFoam | Shuai_W | OpenFOAM Running, Solving & CFD | 11 | May 24, 2018 11:49 |
DPMFoam - Serious Error --particle-laden flow in simple geometric config | benz25 | OpenFOAM Running, Solving & CFD | 27 | December 19, 2017 20:47 |