centerPoint enhanced & DEMsystem modified for id

- center points enhanced to select particle ids based on the particles located in box, sphere and cylinder
- readme.md modified
- DEMsystem is modified to pass id
This commit is contained in:
Hamidreza 2025-05-22 09:37:07 +03:30
parent 832d1fb16b
commit c89a297e6f
10 changed files with 79 additions and 20 deletions

View File

@ -66,12 +66,13 @@ pFlow::uniquePtr<pFlow::DEMSystem>
word demSystemName, word demSystemName,
const std::vector<box>& domains, const std::vector<box>& domains,
int argc, int argc,
char* argv[] char* argv[],
bool requireRVel
) )
{ {
if( wordvCtorSelector_.search(demSystemName) ) if( wordvCtorSelector_.search(demSystemName) )
{ {
return wordvCtorSelector_[demSystemName] (demSystemName, domains, argc, argv); return wordvCtorSelector_[demSystemName] (demSystemName, domains, argc, argv, requireRVel);
} }
else else
{ {

View File

@ -71,13 +71,15 @@ public:
word demSystemName, word demSystemName,
const std::vector<box>& domains, const std::vector<box>& domains,
int argc, int argc,
char* argv[] char* argv[],
bool requireRVel
), ),
( (
demSystemName, demSystemName,
domains, domains,
argc, argc,
argv argv,
requireRVel
)); ));
realx3 g()const realx3 g()const
@ -119,7 +121,10 @@ public:
span<const int32> parIndexInDomain(int32 domIndx)const = 0; span<const int32> parIndexInDomain(int32 domIndx)const = 0;
virtual virtual
span<real> diameter() = 0; span<real> diameter() = 0;
virtual
span<uint32> particleId() = 0;
virtual virtual
span<real> courseGrainFactor() = 0; span<real> courseGrainFactor() = 0;
@ -176,7 +181,8 @@ public:
word demSystemName, word demSystemName,
const std::vector<box>& domains, const std::vector<box>& domains,
int argc, int argc,
char* argv[]); char* argv[],
bool requireRVel=false);
}; };

View File

@ -163,6 +163,12 @@ pFlow::grainDEMSystem::parIndexInDomain(int32 di)const
return particleDistribution_->particlesInDomain(di); return particleDistribution_->particlesInDomain(di);
} }
pFlow::span<pFlow::uint32> pFlow::grainDEMSystem::particleId()
{
return span<uint32>(particleIdHost_.data(), particleIdHost_.size());
}
pFlow::span<pFlow::real> pFlow::grainDEMSystem::diameter() pFlow::span<pFlow::real> pFlow::grainDEMSystem::diameter()
{ {
return span<real>(diameterHost_.data(), diameterHost_.size()); return span<real>(diameterHost_.data(), diameterHost_.size());
@ -233,6 +239,7 @@ bool pFlow::grainDEMSystem::beforeIteration()
velocityHost_ = std::as_const(particles_()).velocity().hostView(); velocityHost_ = std::as_const(particles_()).velocity().hostView();
positionHost_ = std::as_const(particles_()).pointPosition().hostView(); positionHost_ = std::as_const(particles_()).pointPosition().hostView();
diameterHost_ = particles_->diameter().hostView(); diameterHost_ = particles_->diameter().hostView();
particleIdHost_ = particles_->particleId().hostView();
if(requireRVel_) if(requireRVel_)
rVelocityHost_ = std::as_const(particles_()).rVelocity().hostView(); rVelocityHost_ = std::as_const(particles_()).rVelocity().hostView();

View File

@ -63,6 +63,8 @@ protected:
ViewType1D<real, HostSpace> diameterHost_; ViewType1D<real, HostSpace> diameterHost_;
ViewType1D<uint32, HostSpace> particleIdHost_;
bool requireRVel_ = false; bool requireRVel_ = false;
ViewType1D<realx3, HostSpace> rVelocityHost_; ViewType1D<realx3, HostSpace> rVelocityHost_;
@ -122,6 +124,8 @@ public:
span<const int32> parIndexInDomain(int32 di)const override; span<const int32> parIndexInDomain(int32 di)const override;
span<uint32> particleId() override;
span<real> diameter() override; span<real> diameter() override;
span<real> courseGrainFactor() override; span<real> courseGrainFactor() override;

View File

@ -165,6 +165,11 @@ pFlow::sphereDEMSystem::parIndexInDomain(int32 di)const
return particleDistribution_->particlesInDomain(di); return particleDistribution_->particlesInDomain(di);
} }
pFlow::span<pFlow::uint32> pFlow::sphereDEMSystem::particleId()
{
return span<uint32>();
}
pFlow::span<pFlow::real> pFlow::sphereDEMSystem::diameter() pFlow::span<pFlow::real> pFlow::sphereDEMSystem::diameter()
{ {
return span<real>(diameterHost_.data(), diameterHost_.size()); return span<real>(diameterHost_.data(), diameterHost_.size());
@ -235,6 +240,7 @@ bool pFlow::sphereDEMSystem::beforeIteration()
velocityHost_ = std::as_const(particles_()).velocity().hostView(); velocityHost_ = std::as_const(particles_()).velocity().hostView();
positionHost_ = std::as_const(particles_()).pointPosition().hostView(); positionHost_ = std::as_const(particles_()).pointPosition().hostView();
diameterHost_ = particles_->diameter().hostView(); diameterHost_ = particles_->diameter().hostView();
particleIdHost_ = particles_->particleId().hostView();
if(requireRVel_) if(requireRVel_)
rVelocityHost_ = std::as_const(particles_()).rVelocity().hostView(); rVelocityHost_ = std::as_const(particles_()).rVelocity().hostView();

View File

@ -63,6 +63,8 @@ protected:
ViewType1D<real, HostSpace> diameterHost_; ViewType1D<real, HostSpace> diameterHost_;
ViewType1D<uint32, HostSpace> particleIdHost_;
bool requireRVel_ = false; bool requireRVel_ = false;
ViewType1D<realx3, HostSpace> rVelocityHost_; ViewType1D<realx3, HostSpace> rVelocityHost_;
@ -122,6 +124,8 @@ public:
span<const int32> parIndexInDomain(int32 di)const override; span<const int32> parIndexInDomain(int32 di)const override;
span<uint32> particleId() override;
span<real> diameter() override; span<real> diameter() override;
span<real> courseGrainFactor() override; span<real> courseGrainFactor() override;

View File

@ -185,6 +185,18 @@ public:
return contactTorque_; return contactTorque_;
} }
inline
uint32PointField_D& particleId()
{
return idHandler_();
}
inline
const uint32PointField_D& particleId() const
{
return idHandler_();
}
inline inline
uint32 maxId()const uint32 maxId()const
{ {

View File

@ -5,6 +5,14 @@ The `PostprocessData` module in phasicFlow provides powerful tools for analyzing
- in-simulation: this is postprocessing that is active during simulation. When running a solver, it allows for real-time data analysis and adjustments based on the simulation's current state. See below to see how you can activate in-simulation postprocessing. - in-simulation: this is postprocessing that is active during simulation. When running a solver, it allows for real-time data analysis and adjustments based on the simulation's current state. See below to see how you can activate in-simulation postprocessing.
- post-simulation: this is postprocessing that is done after the simulation is completed. It allows for detailed analysis of the simulation results, including data extraction and visualization based on the results that are stored in time-folders. If you want to use post-simulation, you need to run utility `postprocessPhasicFlow` in terminal (in the simulation case setup folder) to run the postprocessing. This utility reads the `postprocessDataDict` file and performs the specified operations on the simulation data. - post-simulation: this is postprocessing that is done after the simulation is completed. It allows for detailed analysis of the simulation results, including data extraction and visualization based on the results that are stored in time-folders. If you want to use post-simulation, you need to run utility `postprocessPhasicFlow` in terminal (in the simulation case setup folder) to run the postprocessing. This utility reads the `postprocessDataDict` file and performs the specified operations on the simulation data.
<div style="border: 1px solid black; padding: 10px; margin-bottom: 10px; background-color: gray;">
**IMPORTANT NOTE**
in-simulation postprocessing is not implemented for MPI execution. For post-simulation postprocessing, you can use the `postprocessPhasicFlow` utility without MPI, even though the actual simulation has been done using MPI.
</div>
## 1. Overview ## 1. Overview
Postprocessing in phasicFlow allows you to: Postprocessing in phasicFlow allows you to:
@ -118,12 +126,17 @@ Regions define where in the domain the postprocessing operations are applied:
| Region Type | Description | Required Parameters | Compatible with | | Region Type | Description | Required Parameters | Compatible with |
|-------------|-------------|---------------------|-----------------| |-------------|-------------|---------------------|-----------------|
| `sphere` | A spherical region | `radius`, `center` | bulk | | `sphere` | A spherical region | `radius`, `center` defined in `sphereInfo` dict| bulk |
| `multipleSpheres` | Multiple spherical regions | `centers`, `radii` | bulk | | `multipleSpheres` | Multiple spherical regions | `centers`, `radii` defined in `multiplSpheresInfo` dict | bulk |
| `line` | Spheres along a line with specified radius | `p1`, `p2`, `nSpheres`, `radius` | bulk | | `line` | Spheres along a line with specified radius | `p1`, `p2`, `nSpheres`, `radius` defined in `lineInfo` dict| bulk |
| `centerPoints` | Specific particles selected by ID | `ids` | individual | | `box`| A cuboid region | `min`, `max` defined in `boxInfo` dict | bulk |
| `centerPoints`* | Specific particles selected by ID | `ids` | individual |
| `centerPoints`* | Specific particles selected by center points located in a box | `boxInfo` | individual |
| `centerPoints`* | Specific particles selected by center points located in a sphere | `sphereInfo` | individual |
| `centerPoints`* | Specific particles selected by center points located in a cylinder | `cylinderInfo` | individual |
| <td colspan="4">\* Particles selection is done when simulation reaches the time that is specified by `startTime` of the post-process component and this selection remains intact up to the end of simulation. This is very good for particle tracking purposes or when you want to analyze specific particles behavior over time.</td> |
## 6. Processing Operations ## 6. Processing Operations for Bulk Properties
Within each processing region of type `bulk`, you can define multiple operations to be performed: Within each processing region of type `bulk`, you can define multiple operations to be performed:
@ -565,5 +578,4 @@ components
} }
); );
``` ```

View File

@ -19,7 +19,7 @@ boxRegionPoints::boxRegionPoints
(boxRegion_.maxPoint().y() - boxRegion_.minPoint().y()) * (boxRegion_.maxPoint().y() - boxRegion_.minPoint().y()) *
(boxRegion_.maxPoint().z() - boxRegion_.minPoint().z()) (boxRegion_.maxPoint().z() - boxRegion_.minPoint().z())
), ),
diameter_(pow(3 * volume_ / 4.0 / Pi, 1.0 / 3.0)), diameter_(2 * pow(3 * volume_ / 4.0 / Pi, 1.0 / 3.0)),
selectedPoints_("selectedPoints") selectedPoints_("selectedPoints")
{ {
} }

View File

@ -8,6 +8,8 @@ namespace pFlow::postprocessData
bool centerPointsRegionPoints::selectIds() bool centerPointsRegionPoints::selectIds()
{ {
// check if it is already found the ids of particles
// if not, then find the ids of particles
if(!firstTimeUpdate_) return true; if(!firstTimeUpdate_) return true;
firstTimeUpdate_ = false; firstTimeUpdate_ = false;
@ -26,16 +28,20 @@ bool centerPointsRegionPoints::selectIds()
} }
} }
else else
// TODO: this should be corrected to select ids of particles
// that are selected based on the selector (this is visa versa)
{ {
auto selectorPtr = pStructSelector::create( auto selectorPtr = pStructSelector::create(
selector, selector,
database().pStruct(), database().pStruct(),
probDict_.subDict(selector+"Info")); probDict_.subDict(selector+"Info"));
auto selectedPoints = selectorPtr->selectedPoints(); auto selectedPoints = selectorPtr->selectedPoints();
ids_.resize(selectedPoints.size()); const auto& idField = database().updateFieldUint32(idName_);
ids_.assign(selectedPoints.begin(), selectedPoints.end());
ids_.clear();
ids_.reserve(selectedPoints.size());
for( auto& pntIndex: selectedPoints)
{
ids_.push_back(idField[pntIndex]);
}
} }
volume_.resize(ids_.size(),1.0); volume_.resize(ids_.size(),1.0);
@ -62,11 +68,12 @@ bool centerPointsRegionPoints::update()
const auto& idField = database().updateFieldUint32(idName_); const auto& idField = database().updateFieldUint32(idName_);
selectedPoints_.fill(-1); selectedPoints_.fill(-1);
for(uint32 i = 0; i < idField.size(); ++i) for( uint32 j=0; j< ids_.size(); ++j)
{ {
for( uint32 j=0; j< ids_.size(); ++j) auto id = ids_[j];
for( uint32 i=0; i< idField.size(); i++)
{ {
if(idField[i] == ids_[j]) if(idField[i] == id)
{ {
selectedPoints_[j] = i; selectedPoints_[j] = i;
break; break;