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,
const std::vector<box>& domains,
int argc,
char* argv[]
char* argv[],
bool requireRVel
)
{
if( wordvCtorSelector_.search(demSystemName) )
{
return wordvCtorSelector_[demSystemName] (demSystemName, domains, argc, argv);
return wordvCtorSelector_[demSystemName] (demSystemName, domains, argc, argv, requireRVel);
}
else
{

View File

@ -71,13 +71,15 @@ public:
word demSystemName,
const std::vector<box>& domains,
int argc,
char* argv[]
char* argv[],
bool requireRVel
),
(
demSystemName,
domains,
argc,
argv
argv,
requireRVel
));
realx3 g()const
@ -121,6 +123,9 @@ public:
virtual
span<real> diameter() = 0;
virtual
span<uint32> particleId() = 0;
virtual
span<real> courseGrainFactor() = 0;
@ -176,7 +181,8 @@ public:
word demSystemName,
const std::vector<box>& domains,
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);
}
pFlow::span<pFlow::uint32> pFlow::grainDEMSystem::particleId()
{
return span<uint32>(particleIdHost_.data(), particleIdHost_.size());
}
pFlow::span<pFlow::real> pFlow::grainDEMSystem::diameter()
{
return span<real>(diameterHost_.data(), diameterHost_.size());
@ -233,6 +239,7 @@ bool pFlow::grainDEMSystem::beforeIteration()
velocityHost_ = std::as_const(particles_()).velocity().hostView();
positionHost_ = std::as_const(particles_()).pointPosition().hostView();
diameterHost_ = particles_->diameter().hostView();
particleIdHost_ = particles_->particleId().hostView();
if(requireRVel_)
rVelocityHost_ = std::as_const(particles_()).rVelocity().hostView();

View File

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

View File

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

View File

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

View File

@ -185,6 +185,18 @@ public:
return contactTorque_;
}
inline
uint32PointField_D& particleId()
{
return idHandler_();
}
inline
const uint32PointField_D& particleId() const
{
return idHandler_();
}
inline
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.
- 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
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 |
|-------------|-------------|---------------------|-----------------|
| `sphere` | A spherical region | `radius`, `center` | bulk |
| `multipleSpheres` | Multiple spherical regions | `centers`, `radii` | bulk |
| `line` | Spheres along a line with specified radius | `p1`, `p2`, `nSpheres`, `radius` | bulk |
| `centerPoints` | Specific particles selected by ID | `ids` | individual |
| `sphere` | A spherical region | `radius`, `center` defined in `sphereInfo` dict| bulk |
| `multipleSpheres` | Multiple spherical regions | `centers`, `radii` defined in `multiplSpheresInfo` dict | bulk |
| `line` | Spheres along a line with specified radius | `p1`, `p2`, `nSpheres`, `radius` defined in `lineInfo` dict| bulk |
| `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:
@ -565,5 +578,4 @@ components
}
);
```

View File

@ -19,7 +19,7 @@ boxRegionPoints::boxRegionPoints
(boxRegion_.maxPoint().y() - boxRegion_.minPoint().y()) *
(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")
{
}

View File

@ -8,6 +8,8 @@ namespace pFlow::postprocessData
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;
firstTimeUpdate_ = false;
@ -26,16 +28,20 @@ bool centerPointsRegionPoints::selectIds()
}
}
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(
selector,
database().pStruct(),
probDict_.subDict(selector+"Info"));
auto selectedPoints = selectorPtr->selectedPoints();
ids_.resize(selectedPoints.size());
ids_.assign(selectedPoints.begin(), selectedPoints.end());
const auto& idField = database().updateFieldUint32(idName_);
ids_.clear();
ids_.reserve(selectedPoints.size());
for( auto& pntIndex: selectedPoints)
{
ids_.push_back(idField[pntIndex]);
}
}
volume_.resize(ids_.size(),1.0);
@ -62,11 +68,12 @@ bool centerPointsRegionPoints::update()
const auto& idField = database().updateFieldUint32(idName_);
selectedPoints_.fill(-1);
for(uint32 i = 0; i < idField.size(); ++i)
{
for( uint32 j=0; j< ids_.size(); ++j)
{
if(idField[i] == ids_[j])
auto id = ids_[j];
for( uint32 i=0; i< idField.size(); i++)
{
if(idField[i] == id)
{
selectedPoints_[j] = i;
break;