mirror of
https://github.com/PhasicFlow/phasicFlow.git
synced 2025-07-18 03:17:04 +00:00
Merge branch 'PhasicFlow:main' into stlModelImport
This commit is contained in:
110
utilities/pFlowToVTK/README.md
Normal file
110
utilities/pFlowToVTK/README.md
Normal file
@ -0,0 +1,110 @@
|
||||
# pFlowToVTK Utility
|
||||
|
||||
## Overview
|
||||
|
||||
pFlowToVTK is a utility for converting phasicFlow simulation data into VTK (Visualization Toolkit) file format. This enables visualization of simulation results in applications like ParaView. The utility handles two primary types of data:
|
||||
|
||||
1. **Particle Data** (pointField) - Converts particle properties such as position, velocity, forces, etc.
|
||||
2. **Geometry Data** (triSurfaceField) - Converts surface geometries and their properties
|
||||
|
||||
## Basic Usage
|
||||
|
||||
```bash
|
||||
pFlowToVTK [OPTIONS]
|
||||
```
|
||||
|
||||
After simulation is complete, run this command from the case directory to convert all simulation data to VTK format, which will be stored in the `./VTK/` folder.
|
||||
|
||||
## Command Line Options
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--no-geometry` | Skip conversion of geometry data to VTK format |
|
||||
| `--no-particles` | Skip conversion of particle data to VTK format |
|
||||
| `-b, --binary` | Write VTK files in binary format (default is ASCII). Using binary format accelerates conversion (5-10x) and visualization in ParaView |
|
||||
| `-o, --out-folder <path>` | Specify the output directory path (default: `./VTK/`) |
|
||||
| `-s, --separate-surfaces` | Create separate files for each sub-surface in geometry |
|
||||
| `-f, --fields <field1> <field2>...` | Specify which particle fields to convert (space-separated list). If not specified, all fields are converted |
|
||||
| `-t, --time <times>` | Process only specific time folders. Accepts multiple formats: <br> - Space-separated list of times (e.g., `0.1 0.2 0.3`) <br> - Strided range with format `<begin>:<stride>:<end>` (e.g., `0.1:0.1:0.5`) <br> - Interval with format `<begin>:<end>` (e.g., `0.1:0.5`) |
|
||||
| `-h, --help` | Display help message with all available options |
|
||||
|
||||
## Examples
|
||||
|
||||
Convert all data with default settings:
|
||||
|
||||
```bash
|
||||
pFlowToVTK
|
||||
```
|
||||
|
||||
Convert only geometry data:
|
||||
|
||||
```bash
|
||||
pFlowToVTK --no-particles
|
||||
```
|
||||
|
||||
Convert only particle data in binary format:
|
||||
|
||||
```bash
|
||||
pFlowToVTK --no-geometry --binary
|
||||
```
|
||||
|
||||
Convert specific fields for particles:
|
||||
|
||||
```bash
|
||||
pFlowToVTK -f velocity diameter contactForce
|
||||
```
|
||||
|
||||
Convert data for specific time steps:
|
||||
|
||||
```bash
|
||||
pFlowToVTK -t 0.1 0.2 0.3
|
||||
```
|
||||
|
||||
Convert data for a range of time steps:
|
||||
|
||||
```bash
|
||||
pFlowToVTK -t 0.1:0.1:1.0
|
||||
```
|
||||
|
||||
Write output to a custom directory:
|
||||
|
||||
```bash
|
||||
pFlowToVTK -o /path/to/custom/output
|
||||
```
|
||||
|
||||
## Output Structure
|
||||
|
||||
The utility creates the following directory structure:
|
||||
```
|
||||
simulationCase/
|
||||
├── 0/ # Contains the initial time step data
|
||||
├── 0.1/ # time-folder for simulation data at 0.1 s
|
||||
├── 0.2/ # time-folder for simulation data at 0.2 s
|
||||
├── caseSetup/ # Contains the case setup files
|
||||
├── settings/ # Contains the settings files
|
||||
└── VTK/
|
||||
├── geometry/ # Contains VTK files for geometry
|
||||
│ └── surface-*.vtk # Geometry at different time steps
|
||||
└── particles/ # Contains VTK files for particles
|
||||
└── particles-*.vtk # Particle data at different time steps
|
||||
```
|
||||
|
||||
Additionally, the utility generates `.vtk.series` files in the VTK root folder, which can be used by ParaView for loading time series data automatically:
|
||||
```
|
||||
VTK/
|
||||
├── particles.vtk.series
|
||||
└── surface.vtk.series # (and possibly other surface names if --separate-surfaces is used)
|
||||
```
|
||||
|
||||
## Recommendations
|
||||
|
||||
- Use binary format (`-b` flag) for large simulations to significantly improve conversion speed and reduce file size
|
||||
- For complex geometries with multiple sub-surfaces, consider using `-s` flag to keep surfaces in separate files for better visualization
|
||||
- When working with large datasets, use the `-t` option to convert only the time steps you need to visualize
|
||||
|
||||
## See Also
|
||||
## Related Utilities
|
||||
- [`tutorials`](../../tutorials): Contains example cases and step-by-step guides for using phasicFlow
|
||||
- [`particlesPhasicFlow`](../particlesPhasicFlow): Creates the initial fields for particles
|
||||
- [`geometryPhasicFlow`](../geometryPhasicFlow): Creates the geometry
|
||||
- [`postprocessPhasicFlow`](../postprocessPhasicFlow): Tool for performing various cell-based averaging on fields
|
369
utilities/particlesPhasicFlow/README.md
Normal file
369
utilities/particlesPhasicFlow/README.md
Normal file
@ -0,0 +1,369 @@
|
||||
# particlesPhasicFlow Utility
|
||||
|
||||
## 1. Overview
|
||||
|
||||
`particlesPhasicFlow` is a pre-processing utility for Discrete Element Method (DEM) simulations in phasicFlow. It is used to:
|
||||
|
||||
1. Position particles in the simulation domain using different methods
|
||||
2. Set initial field values (such as velocity, acceleration, shape) for particles
|
||||
3. Apply field values to selected subsets of particles
|
||||
|
||||
The utility reads its configuration from `settings/particlesDict` in your simulation case directory.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [1. Overview](#1-overview)
|
||||
- [2. Command Line Options](#2-command-line-options)
|
||||
- [3. The particlesDict File Structure](#3-the-particlesdict-file-structure)
|
||||
- [3.1. positionParticles Sub-dictionary](#31-positionparticles-sub-dictionary)
|
||||
- [3.1.1. Positioning Methods](#311-positioning-methods)
|
||||
- [3.1.2. Region Types](#312-region-types)
|
||||
- [3.2. setFields Dictionary](#32-setfields-dictionary)
|
||||
- [3.2.1. Selector Types](#321-selector-types)
|
||||
- [4. Usage Examples](#4-usage-examples)
|
||||
- [4.1. Example 1: Positioning Particles in an Ordered Pattern](#41-example-1-positioning-particles-in-an-ordered-pattern)
|
||||
- [4.2. Example 2: Setting Field Values for a Binary Mixture of Particles](#42-example-2-setting-field-values-for-a-binary-mixture-of-particles)
|
||||
- [4.3. Example 3: Empty Initial Particle System (for Insertion Later)](#43-example-3-empty-initial-particle-system-for-insertion-later)
|
||||
- [5. Workflow Tips](#5-workflow-tips)
|
||||
- [6. Common Field Types](#6-common-field-types)
|
||||
- [7. Shape Handling](#7-shape-handling)
|
||||
- [8. See Also](#8-see-also)
|
||||
|
||||
## 2. Command Line Options
|
||||
|
||||
The utility can be run with the following command line options:
|
||||
|
||||
```
|
||||
particlesPhasicFlow [OPTIONS]
|
||||
```
|
||||
|
||||
Where `[OPTIONS]` can include:
|
||||
|
||||
- `--positionParticles-only`: Execute only the positioning part and store the created pointStructure.
|
||||
- `--setFields-only`: Execute only the field setting part, reading an existing pointStructure file from the time folder.
|
||||
- `-c, --coupling`: Specify if this is a fluid-particle coupling simulation.
|
||||
|
||||
## 3. The particlesDict File Structure
|
||||
|
||||
The `particlesDict` file consists of two main sections:
|
||||
|
||||
1. `positionParticles`: Defines how particles are positioned in the domain.
|
||||
2. `setFields`: Defines initial field values for particles and selective field assignments.
|
||||
|
||||
### 3.1. positionParticles Sub-dictionary
|
||||
|
||||
This section defines how particles are positioned in the simulation domain:
|
||||
|
||||
```C++
|
||||
positionParticles
|
||||
{
|
||||
method <method>; // Options: ordered, random, file, empty
|
||||
|
||||
regionType <region>; // Options: box, cylinder, sphere, domain
|
||||
|
||||
// Method-specific settings
|
||||
<method>Info
|
||||
{
|
||||
// Parameters for the selected method
|
||||
}
|
||||
|
||||
// Region-specific settings
|
||||
<region>Info
|
||||
{
|
||||
// Parameters for the selected region
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.1.1. Positioning Methods
|
||||
|
||||
1. **ordered**: Positions particles in an ordered pattern along specified axes
|
||||
|
||||
```C++
|
||||
orderedInfo
|
||||
{
|
||||
distance <value>; // Minimum space between centers of particles
|
||||
numPoints <value>; // Number of particles to position
|
||||
axisOrder (<axis1> <axis2> <axis3>); // Order of axes for filling (x, y, z)
|
||||
}
|
||||
```
|
||||
|
||||
2. **random**: Positions particles randomly in the specified region
|
||||
|
||||
```C++
|
||||
randomInfo
|
||||
{
|
||||
distance <value>; // Minimum distance between particle centers
|
||||
numPoints <value>; // Number of particles to position
|
||||
maxIterations <value>; // Maximum iterations for random positioning (default: 10)
|
||||
}
|
||||
```
|
||||
|
||||
3. **file**: Reads particle positions from a file
|
||||
|
||||
```C++
|
||||
fileInfo
|
||||
{
|
||||
fileName <path>; // Path to file containing positions
|
||||
commaSeparated Yes/No; // Whether file is comma-separated
|
||||
}
|
||||
```
|
||||
|
||||
4. **empty**: Creates an empty pointStructure with no particles. No additional sub-dictionary is required.
|
||||
|
||||
#### 3.1.2. Region Types
|
||||
|
||||
1. **box**: Rectangular region
|
||||
|
||||
```C++
|
||||
boxInfo
|
||||
{
|
||||
min (<x> <y> <z>); // Lower corner point coordinates
|
||||
max (<x> <y> <z>); // Upper corner point coordinates
|
||||
}
|
||||
```
|
||||
|
||||
2. **cylinder**: Cylindrical region
|
||||
|
||||
```C++
|
||||
cylinderInfo
|
||||
{
|
||||
p1 (<x> <y> <z>); // Begin point of cylinder axis
|
||||
p2 (<x> <y> <z>); // End point of cylinder axis
|
||||
radius <value>; // Radius of cylinder
|
||||
}
|
||||
```
|
||||
|
||||
3. **sphere**: Spherical region
|
||||
|
||||
```C++
|
||||
sphereInfo
|
||||
{
|
||||
center (<x> <y> <z>); // Center of sphere
|
||||
radius <value>; // Radius of sphere
|
||||
}
|
||||
```
|
||||
|
||||
4. **domain**: Uses the global domain defined in the simulation (in file `settings/domainDict`)
|
||||
|
||||
```C++
|
||||
// No additional information needed when using domain
|
||||
```
|
||||
|
||||
### 3.2. setFields Dictionary
|
||||
|
||||
This section defines the initial field values for particles and allows selective field assignments:
|
||||
|
||||
```C++
|
||||
setFields
|
||||
{
|
||||
defaultValue
|
||||
{
|
||||
// Default field values for all particles
|
||||
velocity realx3 (<x> <y> <z>); // Initial linear velocity (m/s)
|
||||
acceleration realx3 (<x> <y> <z>); // Initial linear acceleration (m/s²)
|
||||
rVelocity realx3 (<x> <y> <z>); // Initial rotational velocity (rad/s)
|
||||
shapeName word <shape>; // Particle shape name
|
||||
// Additional fields as required
|
||||
}
|
||||
|
||||
selectors
|
||||
{
|
||||
<selectorName>
|
||||
{
|
||||
selector <selectorType>; // Type of selector
|
||||
|
||||
<selectorType>Info
|
||||
{
|
||||
// Parameters specific to the selector type
|
||||
}
|
||||
|
||||
fieldValue
|
||||
{
|
||||
// Field values to set for selected particles
|
||||
<fieldName> <fieldType> <value>;
|
||||
// Additional fields as required
|
||||
}
|
||||
}
|
||||
// Additional selectors as required
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.2.1. Selector Types
|
||||
|
||||
1. **stridedRange**: Selects particles based on index ranges
|
||||
|
||||
```C++
|
||||
stridedRangeInfo
|
||||
{
|
||||
begin <value>; // Beginning index
|
||||
end <value>; // Ending index
|
||||
stride <value>; // Step size (default: 1)
|
||||
}
|
||||
```
|
||||
|
||||
2. **box**: Selects particles within a box region
|
||||
|
||||
```C++
|
||||
boxInfo
|
||||
{
|
||||
min (<x> <y> <z>); // Lower corner point coordinates
|
||||
max (<x> <y> <z>); // Upper corner point coordinates
|
||||
}
|
||||
```
|
||||
|
||||
3. **cylinder**: Selects particles within a cylindrical region
|
||||
|
||||
```C++
|
||||
cylinderInfo
|
||||
{
|
||||
p1 (<x> <y> <z>); // Begin point of cylinder axis
|
||||
p2 (<x> <y> <z>); // End point of cylinder axis
|
||||
radius <value>; // Radius of cylinder
|
||||
}
|
||||
```
|
||||
|
||||
4. **sphere**: Selects particles within a spherical region
|
||||
|
||||
```C++
|
||||
sphereInfo
|
||||
{
|
||||
center (<x> <y> <z>); // Center of sphere
|
||||
radius <value>; // Radius of sphere
|
||||
}
|
||||
```
|
||||
|
||||
5. **randomPoints**: Selects a random subset of particles
|
||||
|
||||
```C++
|
||||
randomPointsInfo
|
||||
{
|
||||
begin <value>; // Beginning index
|
||||
end <value>; // Ending index
|
||||
number <value>; // Number of random points to select
|
||||
}
|
||||
```
|
||||
|
||||
## 4. Usage Examples
|
||||
|
||||
### 4.1. Example 1: Positioning Particles in an Ordered Pattern
|
||||
|
||||
```C++
|
||||
positionParticles
|
||||
{
|
||||
method ordered;
|
||||
mortonSorting Yes;
|
||||
|
||||
orderedInfo
|
||||
{
|
||||
distance 0.005;
|
||||
numPoints 30000;
|
||||
axisOrder (z x y);
|
||||
}
|
||||
|
||||
regionType cylinder;
|
||||
|
||||
cylinderInfo
|
||||
{
|
||||
p1 (0.0 0.0 0.003);
|
||||
p2 (0.0 0.0 0.097);
|
||||
radius 0.117;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2. Example 2: Setting Field Values for a Binary Mixture of Particles
|
||||
|
||||
```C++
|
||||
setFields
|
||||
{
|
||||
defaultValue
|
||||
{
|
||||
velocity realx3 (0 0 0);
|
||||
acceleration realx3 (0 0 0);
|
||||
rVelocity realx3 (0 0 0);
|
||||
shapeName word smallSphere;
|
||||
}
|
||||
|
||||
selectors
|
||||
{
|
||||
shapeAssigne
|
||||
{
|
||||
selector stridedRange;
|
||||
|
||||
stridedRangeInfo
|
||||
{
|
||||
begin 0;
|
||||
end 30000;
|
||||
stride 3;
|
||||
}
|
||||
|
||||
fieldValue
|
||||
{
|
||||
shapeName word largeSphere;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3. Example 3: Empty Initial Particle System (for Insertion Later)
|
||||
|
||||
```C++
|
||||
positionParticles
|
||||
{
|
||||
method empty;
|
||||
}
|
||||
```
|
||||
|
||||
## 5. Workflow Tips
|
||||
|
||||
1. To create particles at the beginning of a simulation:
|
||||
|
||||
```
|
||||
particlesPhasicFlow
|
||||
```
|
||||
|
||||
2. To only position particles without setting fields:
|
||||
|
||||
```
|
||||
particlesPhasicFlow --positionParticles-only
|
||||
```
|
||||
|
||||
3. To modify fields on existing particles (e.g., at a later time step):
|
||||
|
||||
```
|
||||
particlesPhasicFlow --setFields-only
|
||||
```
|
||||
|
||||
4. For fluid-particle coupling simulations:
|
||||
|
||||
```
|
||||
particlesPhasicFlow -c
|
||||
```
|
||||
|
||||
5. To change particle properties at a later time step in a simulation:
|
||||
- Change `startTime` in the settings dictionary to the desired time
|
||||
- Run `particlesPhasicFlow --setFields-only`
|
||||
- Restart the simulation from that time step
|
||||
|
||||
## 6. Common Field Types
|
||||
|
||||
- `realx3`: 3D vector of real values, e.g., `(0 0 0)`
|
||||
- `real`: Single real value
|
||||
- `word`: Text string
|
||||
- `uint32`: Unsigned 32-bit integer
|
||||
|
||||
## 7. Shape Handling
|
||||
|
||||
When using the `shapeName` field, ensure that the shapes are defined in the `shape` file in the `caseSetup` directory. The utility will automatically convert shape names to shape indices and hashes for the simulation.
|
||||
|
||||
For any further assistance, please refer to the tutorial examples in the phasicFlow distribution.
|
||||
|
||||
## 8. See Also
|
||||
|
||||
- [Tutorials](../../tutorials) - Example cases demonstrating phasicFlow capabilities and more about particlesPhasicFlow
|
||||
- [geometryPhasicFlow](../geometryPhasicFlow) - Utility for geometry creation and manipulation in phasicFlow
|
||||
- [pFlowToVTK](../pFlowToVTK) - Utility for converting phasicFlow data to VTK format for visualization
|
||||
- [postprocessPhasicFlow](../postprocessPhasicFlow) - Utility for post-processing simulation results
|
@ -64,7 +64,7 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
real maxDiameter() const final
|
||||
real distance() const final
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
@ -74,9 +74,9 @@ public:
|
||||
return static_cast<uint32>(position_.size());
|
||||
}
|
||||
|
||||
real maxDiameter() const final
|
||||
real distance() const final
|
||||
{
|
||||
return 0;
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
// bool commaSeparated()const
|
||||
|
@ -79,7 +79,7 @@ bool pFlow::positionOrdered::positionPointsOrdered()
|
||||
{
|
||||
position_.clear();
|
||||
|
||||
realx3 dl(diameter_);
|
||||
realx3 dl(distance_);
|
||||
const auto& region = pRegion();
|
||||
auto minP = region.minPoint();
|
||||
auto maxP = region.maxPoint();
|
||||
@ -131,9 +131,9 @@ pFlow::positionOrdered::positionOrdered
|
||||
(
|
||||
dict.subDict("orderedInfo")
|
||||
),
|
||||
diameter_
|
||||
distance_
|
||||
(
|
||||
poDict_.getVal<real>("diameter")
|
||||
poDict_.getVal<real>("distance")
|
||||
),
|
||||
numPoints_
|
||||
(
|
||||
|
@ -35,7 +35,8 @@ private:
|
||||
|
||||
dictionary poDict_;
|
||||
|
||||
real diameter_;
|
||||
/// Minimum distance between centers of particles
|
||||
real distance_;
|
||||
|
||||
uint32 numPoints_;
|
||||
|
||||
@ -86,9 +87,10 @@ public:
|
||||
return static_cast<uint32>(position_.size());
|
||||
}
|
||||
|
||||
real maxDiameter() const final
|
||||
/// Minimum distance between centers of particles
|
||||
real distance() const final
|
||||
{
|
||||
return diameter_;
|
||||
return distance_;
|
||||
}
|
||||
|
||||
// - const access to position
|
||||
|
@ -83,7 +83,8 @@ public:
|
||||
|
||||
virtual uint32 size()const = 0;
|
||||
|
||||
virtual real maxDiameter() const = 0;
|
||||
/// Minimum distance between centers of particles
|
||||
virtual real distance() const = 0;
|
||||
|
||||
// - const access to position
|
||||
virtual const realx3Vector& position()const = 0;
|
||||
|
@ -35,10 +35,10 @@ bool pFlow::positionRandom::positionOnePass(collisionCheck& collCheck)
|
||||
{
|
||||
realx3 p = region.peek();
|
||||
|
||||
if( collCheck.checkPoint(p, diameter_) )
|
||||
if( collCheck.checkPoint(p, distance_) )
|
||||
{
|
||||
position_.push_back(p);
|
||||
diameters_.push_back(diameter_);
|
||||
diameters_.push_back(distance_);
|
||||
|
||||
if(!collCheck.mapLastAddedParticle())
|
||||
{
|
||||
@ -64,7 +64,7 @@ bool pFlow::positionRandom::positionPointsRandom()
|
||||
uint32 pass = 0;
|
||||
collisionCheck collCheck(
|
||||
box(pRegion().minPoint(), pRegion().maxPoint()),
|
||||
diameter_,
|
||||
distance_,
|
||||
position_,
|
||||
diameters_);
|
||||
|
||||
@ -107,9 +107,9 @@ pFlow::positionRandom::positionRandom
|
||||
(
|
||||
dict.subDict("randomInfo")
|
||||
),
|
||||
diameter_
|
||||
distance_
|
||||
(
|
||||
prDict_.getVal<real>("diameter")
|
||||
prDict_.getVal<real>("distance")
|
||||
),
|
||||
numPoints_
|
||||
(
|
||||
|
@ -32,23 +32,25 @@ class positionRandom : public positionParticles
|
||||
{
|
||||
private:
|
||||
|
||||
dictionary prDict_;
|
||||
dictionary prDict_;
|
||||
|
||||
real diameter_;
|
||||
real distance_;
|
||||
|
||||
uint32 numPoints_;
|
||||
uint32 numPoints_;
|
||||
|
||||
uint32 maxIterations_;
|
||||
uint32 maxIterations_;
|
||||
|
||||
uint32 reportInterval_ = 100;
|
||||
|
||||
realx3Vector position_;
|
||||
|
||||
// still keeping this variable name as diameters_ since it stores
|
||||
// the collection of distance values
|
||||
realVector diameters_;
|
||||
|
||||
uint32 reportInterval_;
|
||||
bool positionOnePass(collisionCheck& collCheck);
|
||||
|
||||
bool positionOnePass(collisionCheck& collCheck);
|
||||
|
||||
bool positionPointsRandom();
|
||||
bool positionPointsRandom();
|
||||
|
||||
public:
|
||||
|
||||
@ -79,9 +81,9 @@ public:
|
||||
return position_.size();
|
||||
}
|
||||
|
||||
real maxDiameter() const override
|
||||
real distance() const override
|
||||
{
|
||||
return diameter_;
|
||||
return distance_;
|
||||
}
|
||||
|
||||
// - const access to position
|
||||
|
@ -1,26 +1,19 @@
|
||||
#include "postSimulationFieldsDataBase.hpp"
|
||||
#include "vocabs.hpp"
|
||||
|
||||
namespace pFlow
|
||||
namespace pFlow::postprocessData
|
||||
{
|
||||
|
||||
bool pointFieldGetType
|
||||
(
|
||||
const word& objectType,
|
||||
word& fieldType,
|
||||
word& fieldSpace
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
bool pFlow::postSimulationFieldsDataBase::pointFieldNameExists(const word& name) const
|
||||
bool postSimulationFieldsDataBase::pointFieldNameExists(const word& name) const
|
||||
{
|
||||
if(currentFileFields_.contains(name)) return true;
|
||||
if(time().lookupObjectName(name)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool pFlow::postSimulationFieldsDataBase::loadPointFieldToTime(const word &name)
|
||||
bool postSimulationFieldsDataBase::loadPointFieldToTime(const word &name)
|
||||
{
|
||||
if(time().lookupObjectName(name)) return true;
|
||||
if(auto [iter, success]=currentFileFields_.findIf(name); success)
|
||||
@ -116,7 +109,7 @@ bool pFlow::postSimulationFieldsDataBase::loadPointFieldToTime(const word &name)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pFlow::postSimulationFieldsDataBase::loadPointStructureToTime()
|
||||
bool postSimulationFieldsDataBase::loadPointStructureToTime()
|
||||
{
|
||||
if(!pStructPtr_)
|
||||
{
|
||||
@ -126,7 +119,7 @@ bool pFlow::postSimulationFieldsDataBase::loadPointStructureToTime()
|
||||
return true;
|
||||
}
|
||||
|
||||
const pFlow::shape &pFlow::postSimulationFieldsDataBase::getShape() const
|
||||
const shape &postSimulationFieldsDataBase::getShape() const
|
||||
{
|
||||
if(!shapePtr_)
|
||||
{
|
||||
@ -143,7 +136,7 @@ const pFlow::shape &pFlow::postSimulationFieldsDataBase::getShape() const
|
||||
return shapePtr_();
|
||||
}
|
||||
|
||||
pFlow::word pFlow::postSimulationFieldsDataBase::getPointFieldType(const word &name) const
|
||||
word postSimulationFieldsDataBase::getPointFieldType(const word &name) const
|
||||
{
|
||||
if(auto [iter, success]=currentFileFields_.findIf(name); success)
|
||||
{
|
||||
@ -159,7 +152,7 @@ pFlow::word pFlow::postSimulationFieldsDataBase::getPointFieldType(const word &n
|
||||
return "";
|
||||
}
|
||||
|
||||
bool pFlow::postSimulationFieldsDataBase::setToCurrentFolder()
|
||||
bool postSimulationFieldsDataBase::setToCurrentFolder()
|
||||
{
|
||||
allPointFields_.clear();
|
||||
pStructPtr_.reset(nullptr);
|
||||
@ -184,7 +177,7 @@ bool pFlow::postSimulationFieldsDataBase::setToCurrentFolder()
|
||||
word type, space;
|
||||
for(auto& [name, objectType]: files)
|
||||
{
|
||||
if(pointFieldGetType(objectType, type, space))
|
||||
if(fieldsDataBase::pointFieldGetType(objectType, type, space))
|
||||
{
|
||||
if(name == pointStructureFile__) continue;
|
||||
currentFileFields_.insertIf(name, type);
|
||||
@ -194,7 +187,7 @@ bool pFlow::postSimulationFieldsDataBase::setToCurrentFolder()
|
||||
return true;
|
||||
}
|
||||
|
||||
pFlow::postSimulationFieldsDataBase::postSimulationFieldsDataBase
|
||||
postSimulationFieldsDataBase::postSimulationFieldsDataBase
|
||||
(
|
||||
systemControl &control,
|
||||
const dictionary& postDict,
|
||||
@ -233,17 +226,17 @@ pFlow::postSimulationFieldsDataBase::postSimulationFieldsDataBase
|
||||
}
|
||||
}
|
||||
|
||||
const pFlow::pointStructure& pFlow::postSimulationFieldsDataBase::pStruct()const
|
||||
const pointStructure& postSimulationFieldsDataBase::pStruct()const
|
||||
{
|
||||
return pStructPtr_();
|
||||
}
|
||||
|
||||
pFlow::timeValue pFlow::postSimulationFieldsDataBase::getNextTimeFolder() const
|
||||
timeValue postSimulationFieldsDataBase::getNextTimeFolder() const
|
||||
{
|
||||
return allValidFolders_.nextTime();
|
||||
}
|
||||
|
||||
pFlow::timeValue pFlow::postSimulationFieldsDataBase::setToNextTimeFolder()
|
||||
timeValue postSimulationFieldsDataBase::setToNextTimeFolder()
|
||||
{
|
||||
timeValue nextTime = allValidFolders_.nextTime();
|
||||
if(nextTime < 0.0) return nextTime;
|
||||
@ -261,7 +254,7 @@ pFlow::timeValue pFlow::postSimulationFieldsDataBase::setToNextTimeFolder()
|
||||
return nextTime;
|
||||
}
|
||||
|
||||
pFlow::timeValue pFlow::postSimulationFieldsDataBase::skipNextTimeFolder()
|
||||
timeValue postSimulationFieldsDataBase::skipNextTimeFolder()
|
||||
{
|
||||
timeValue nextTime = allValidFolders_.nextTime();
|
||||
if(nextTime < 0.0) return nextTime;
|
||||
@ -269,3 +262,5 @@ pFlow::timeValue pFlow::postSimulationFieldsDataBase::skipNextTimeFolder()
|
||||
allValidFolders_++;
|
||||
return nextTime;
|
||||
}
|
||||
|
||||
} // namespace pFlow::postprocessData
|
@ -27,12 +27,12 @@ Licence:
|
||||
#include "ListPtr.hpp"
|
||||
#include "property.hpp"
|
||||
|
||||
namespace pFlow
|
||||
namespace pFlow::postprocessData
|
||||
{
|
||||
|
||||
class postSimulationFieldsDataBase
|
||||
:
|
||||
public fieldsDataBase
|
||||
public postprocessData::fieldsDataBase
|
||||
{
|
||||
|
||||
systemControl& control_;
|
||||
|
@ -30,7 +30,7 @@ Licence:
|
||||
int main(int argc, char** argv )
|
||||
{
|
||||
|
||||
pFlow::word outFolder = (pFlow::CWD()/pFlow::postProcessGlobals::defaultRelDir__).wordPath();
|
||||
pFlow::word outFolder = (pFlow::CWD()/pFlow::postprocessData::defaultRelDir__).wordPath();
|
||||
|
||||
pFlow::commandLine cmds(
|
||||
"postprocessPhasicFlow",
|
||||
@ -40,7 +40,7 @@ int main(int argc, char** argv )
|
||||
pFlow::wordVector times;
|
||||
|
||||
pFlow::word description = "path to output folder of postprocess data: ./"
|
||||
+ pFlow::postProcessGlobals::defaultRelDir__;
|
||||
+ pFlow::postprocessData::defaultRelDir__;
|
||||
|
||||
cmds.addOption("-o,--out-folder",
|
||||
outFolder,
|
||||
@ -50,7 +50,7 @@ int main(int argc, char** argv )
|
||||
cmds.addOption(
|
||||
"-t,--time",
|
||||
times.vectorField(),
|
||||
"a SPACE separated lits of time folders, "
|
||||
"a SPACE separated list of time folders, "
|
||||
"or a strided range <begin>:<stride>:<end>, or an interval <begin>:<end>",
|
||||
" ");
|
||||
|
||||
@ -99,7 +99,7 @@ int main(int argc, char** argv )
|
||||
fatalExit;
|
||||
}
|
||||
|
||||
pFlow::postprocessData postprocess(Control, nextTime);
|
||||
pFlow::postprocessData::postprocessData postprocess(Control, nextTime);
|
||||
postprocess.setOutputDirectory(pFlow::fileSystem(outFolder+"/").absolute());
|
||||
|
||||
bool folderSkipped = false;
|
||||
|
234
utilities/postprocessPhasicFlow/readme.md
Normal file
234
utilities/postprocessPhasicFlow/readme.md
Normal file
@ -0,0 +1,234 @@
|
||||
# postprocessPhasicFlow Utility
|
||||
|
||||
This is a documentation for the `postprocessPhasicFlow` utility. This utility is designed to perform post-simulation processing on completed simulation data.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [1. Overview](#1-overview)
|
||||
- [2. When to Use postprocessPhasicFlow](#2-when-to-use-postprocessphasicflow)
|
||||
- [3. Basic Usage](#3-basic-usage)
|
||||
- [4. Command Line Options](#4-command-line-options)
|
||||
- [4.1. Available Options](#41-available-options)
|
||||
- [4.2. Examples](#42-examples)
|
||||
- [5. Configuration](#5-configuration)
|
||||
- [5.1. Important Configuration Parameters for Post-Simulation Processing](#51-important-configuration-parameters-for-post-simulation-processing)
|
||||
- [6. Difference Between In-Simulation and Post-Simulation Processing](#6-difference-between-in-simulation-and-post-simulation-processing)
|
||||
- [7. File Structure](#7-file-structure)
|
||||
- [8. Advanced Features](#8-advanced-features)
|
||||
- [9. Example Configuration](#9-example-configuration)
|
||||
- [10. Troubleshooting](#10-troubleshooting)
|
||||
- [11. See Also](#11-see-also)
|
||||
|
||||
## 1. Overview
|
||||
|
||||
`postprocessPhasicFlow` is a utility for performing postprocessing analysis on completed simulation data. It allows you to extract statistical information, track specific particles, and analyze regional particle behavior without needing to re-run your simulations. This utility leverages the functionality provided by phasicFlow's `PostprocessData` module to analyze data stored in time folders.
|
||||
|
||||
## 2. When to Use postprocessPhasicFlow
|
||||
|
||||
You should use this utility when:
|
||||
|
||||
1. Your simulation has completed and you want to analyze the results
|
||||
2. You want to try different postprocessing configurations on the same simulation data
|
||||
3. You need to extract additional information that wasn't included in real-time processing
|
||||
4. You want to focus on specific time periods or regions of your simulation domain
|
||||
|
||||
## 3. Basic Usage
|
||||
|
||||
To use the `postprocessPhasicFlow` utility, navigate to your simulation case directory and run:
|
||||
|
||||
```bash
|
||||
postprocessPhasicFlow
|
||||
```
|
||||
|
||||
This will read the `postprocessDataDict` file from your case's `settings` directory and perform the configured postprocessing operations on all available time folders.
|
||||
|
||||
## 4. Command Line Options
|
||||
|
||||
The `postprocessPhasicFlow` utility supports several command line options that allow you to customize its behavior:
|
||||
|
||||
```bash
|
||||
postprocessPhasicFlow [OPTIONS]
|
||||
```
|
||||
|
||||
### 4.1. Available Options
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `-o, --out-folder <path>` | Specify the output directory path where postprocessing results will be written. Default is `./postprocessData/` |
|
||||
| `-t, --time <times>` | Process only specific time folders. Accepts multiple formats: <br> - Space-separated list of times (e.g., `0.1 0.2 0.3`) <br> - Strided range with format `<begin>:<stride>:<end>` (e.g., `0.1:0.1:0.5`) <br> - Interval with format `<begin>:<end>` (e.g., `0.1:0.5`) |
|
||||
| `-z, --zeroFolder` | Include the zero folder (initial state) in the processing. By default, the zero folder is not processed. |
|
||||
| `-h, --help` | Display help message with all available options |
|
||||
|
||||
### 4.2. Examples
|
||||
|
||||
Process all available time folders (except zero folder):
|
||||
|
||||
```bash
|
||||
postprocessPhasicFlow
|
||||
```
|
||||
|
||||
Process only specific time steps:
|
||||
|
||||
```bash
|
||||
postprocessPhasicFlow -t 0.1 0.2 0.5
|
||||
```
|
||||
|
||||
Process a range of time steps from 0.1 to 1.0 with 0.1 increments:
|
||||
|
||||
```bash
|
||||
postprocessPhasicFlow -t 0.1:0.1:1.0
|
||||
```
|
||||
|
||||
Process all time steps including the initial state (zero folder):
|
||||
|
||||
```bash
|
||||
postprocessPhasicFlow -z
|
||||
```
|
||||
|
||||
Write output to a custom directory:
|
||||
|
||||
```bash
|
||||
postprocessPhasicFlow -o /path/to/custom/output
|
||||
```
|
||||
|
||||
|
||||
## 5. Configuration
|
||||
|
||||
The `postprocessPhasicFlow` utility is configured through the same `postprocessDataDict` file used for in-simulation postprocessing. This file should be placed in the `settings` directory of your case.
|
||||
|
||||
### 5.1. Important Configuration Parameters for Post-Simulation Processing
|
||||
|
||||
When using `postprocessPhasicFlow` for post-simulation processing, pay special attention to these settings:
|
||||
|
||||
```cpp
|
||||
// For post-simulation, runTimeActive should be set to "no"
|
||||
// This indicates that you're doing post-simulation processing
|
||||
runTimeActive no;
|
||||
|
||||
// Specify the correct shape type used in your simulation
|
||||
// This is essential for post-simulation processing
|
||||
shapeType sphere; // Options: sphere, grain, etc.
|
||||
```
|
||||
|
||||
The `shapeType` parameter is particularly crucial for post-simulation processing as it tells the utility what kind of particles were used in the simulation, allowing it to correctly interpret the stored data.
|
||||
|
||||
## 6. Difference Between In-Simulation and Post-Simulation Processing
|
||||
|
||||
| Feature | In-Simulation Processing | Post-Simulation Processing with postprocessPhasicFlow |
|
||||
|---------|--------------------------|--------------------------------------------------------|
|
||||
| When it runs | During simulation execution | After simulation is complete |
|
||||
| How to activate | Set `runTimeActive yes` in postprocessDataDict, set `auxFunctions postprocessData` in settingsDict and add library | Run the `postprocessPhasicFlow` utility |
|
||||
| Data access | Direct access to simulation data in memory | Reads data from time folders |
|
||||
| Performance impact | May slow down simulation | No impact on simulation performance |
|
||||
| Iterations | Can only run once per simulation step | Can be run multiple times with different settings |
|
||||
|
||||
## 7. File Structure
|
||||
|
||||
The results of the postprocessing will be written to files in your case directory (by default, under `postprocessData` folder), with timestamps and naming that matches your configured components and operations. These files can then be used for further analysis or visualization.
|
||||
|
||||
## 8. Advanced Features
|
||||
|
||||
`postprocessPhasicFlow` supports all the features of the PostprocessData module, including:
|
||||
|
||||
- Different processing methods (arithmetic, uniformDistribution, GaussianDistribution)
|
||||
- Various region types (sphere, multipleSpheres, line, centerPoints)
|
||||
- Multiple operation types (average, sum, avMassVelocity)
|
||||
- Special field functions (component, abs, square, magnitude, etc.)
|
||||
- Particle filtering with includeMask
|
||||
|
||||
but it disables/ignores the effect of all `timeControl` settings in postprocess components.
|
||||
|
||||
For detailed information about these features, refer to the [PostprocessData module documentation](../../src/PostprocessData/readme.md).
|
||||
|
||||
## 9. Example Configuration
|
||||
|
||||
Here's a simple example of a `postprocessDataDict` file configured for post-simulation processing:
|
||||
|
||||
```cpp
|
||||
/* -------------------------------*- C++ -*--------------------------------- *\
|
||||
| phasicFlow File |
|
||||
| copyright: www.cemf.ir |
|
||||
\* ------------------------------------------------------------------------- */
|
||||
objectName postprocessDataDict;
|
||||
objectType dictionary;;
|
||||
fileFormat ASCII;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
// Set to "no" for post-simulation processing
|
||||
runTimeActive no;
|
||||
|
||||
// Required for post-simulation processing - specify the shape type used in the simulation
|
||||
shapeType sphere;
|
||||
|
||||
// Default time control settings
|
||||
defaultTimeControl
|
||||
{
|
||||
timeControl timeStep;
|
||||
startTime 0;
|
||||
endTime 1000;
|
||||
executionInterval 20;
|
||||
}
|
||||
|
||||
// List of postprocessing components
|
||||
components
|
||||
(
|
||||
// Track specific particles by ID
|
||||
particleTracker
|
||||
{
|
||||
processMethod particleProbe;
|
||||
processRegion centerPoints;
|
||||
selector id;
|
||||
field velocity;
|
||||
ids (10 42 87);
|
||||
timeControl default;
|
||||
}
|
||||
|
||||
// Analyze particle behavior in a spherical region
|
||||
centerRegionAnalysis
|
||||
{
|
||||
processMethod arithmetic;
|
||||
processRegion sphere;
|
||||
|
||||
sphereInfo
|
||||
{
|
||||
radius 0.05;
|
||||
center (0 0 0.1);
|
||||
}
|
||||
|
||||
timeControl default;
|
||||
|
||||
operations
|
||||
(
|
||||
velocityMagnitude
|
||||
{
|
||||
function average;
|
||||
field mag(velocity);
|
||||
threshold 5;
|
||||
divideByVolume no;
|
||||
fluctuation2 yes;
|
||||
}
|
||||
|
||||
particleDensity
|
||||
{
|
||||
function sum;
|
||||
field mass;
|
||||
divideByVolume yes;
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
## 10. Troubleshooting
|
||||
|
||||
If you encounter issues with the `postprocessPhasicFlow` utility, check the following:
|
||||
|
||||
1. Make sure your `postprocessDataDict` file specifies the correct `shapeType`
|
||||
2. Verify that the time folders contain all the required field data
|
||||
3. Check that field names referenced in your configuration exist in the simulation data
|
||||
4. Ensure that the simulation case structure is intact and not modified
|
||||
|
||||
## 11. See Also
|
||||
|
||||
- [PostprocessData module documentation](../../src/PostprocessData/readme.md)
|
||||
- [phasicFlow simulation tutorials](../../tutorials/)
|
Reference in New Issue
Block a user