Skip to content

Commit c681cd2

Browse files
readme.md update for mixing index
1 parent 1c95b15 commit c681cd2

2 files changed

Lines changed: 474 additions & 144 deletions

File tree

src/PostprocessData/readme.md

Lines changed: 253 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,23 @@ In post-simulation mode, all `timeControl` settings are ignored. The postprocess
2727
- [6.3. Derived Functions](#63-derived-functions)
2828
- [6.4. Available Fields](#64-available-fields)
2929
- [6.5. Optional Parameters](#65-optional-parameters)
30-
- [7. Examples](#7-examples)
31-
- [7.1. Example 1: Probing Individual Particles](#71-example-1-probing-individual-particles)
32-
- [7.2. Example 2: Processing in a Spherical Region](#72-example-2-processing-in-a-spherical-region)
33-
- [7.3. Example 3: Processing Along a Line](#73-example-3-processing-along-a-line)
34-
- [7.4. Example 4: Processing in a Rectangular Mesh](#74-example-4-processing-in-a-rectangular-mesh)
35-
- [7.5. Example 5: Tracking particles](#75-example-5-tracking-particles)
36-
- [8. Advanced Features](#8-advanced-features)
37-
- [8.1. Special Functions Applied on Fields](#81-special-functions-applied-on-fields)
38-
- [8.2. Particle Filtering with IncludeMask](#82-particle-filtering-with-includemask)
39-
- [8.3. Implementation Notes](#83-implementation-notes)
40-
- [9. Mathematical Formulations](#9-mathematical-formulations)
41-
- [10. A Complete Dictionary File (postprocessDataDict)](#10-a-complete-dictionary-file-postprocessdatadict)
30+
- [7. Mixing Index Calculations](#7-mixing-index-calculations)
31+
- [7.1. Overview](#71-overview)
32+
- [7.2. Lacey Mixing Index](#72-lacey-mixing-index)
33+
- [7.3. Configuration](#73-configuration)
34+
- [7.4. Example Configuration](#74-example-configuration)
35+
- [8. Examples](#8-examples)
36+
- [8.1. Example 1: Probing Individual Particles](#81-example-1-probing-individual-particles)
37+
- [8.2. Example 2: Processing in a Spherical Region](#82-example-2-processing-in-a-spherical-region)
38+
- [8.3. Example 3: Processing Along a Line](#83-example-3-processing-along-a-line)
39+
- [8.4. Example 4: Processing in a Rectangular Mesh](#84-example-4-processing-in-a-rectangular-mesh)
40+
- [8.5. Example 5: Tracking particles](#85-example-5-tracking-particles)
41+
- [9. Advanced Features](#9-advanced-features)
42+
- [9.1. Special Functions Applied on Fields](#91-special-functions-applied-on-fields)
43+
- [9.2. Particle Filtering with IncludeMask](#92-particle-filtering-with-includemask)
44+
- [9.3. Implementation Notes](#93-implementation-notes)
45+
- [10. Mathematical Formulations](#10-mathematical-formulations)
46+
- [11. A Complete Dictionary File (postprocessDataDict)](#11-a-complete-dictionary-file-postprocessdatadict)
4247

4348
## 1. Overview
4449

@@ -118,6 +123,7 @@ The postprocessing module provides several methods for processing particle data.
118123
| `arithmetic` | bulk | Simple arithmetic mean/sum with equal weights | Each particle contributes equally |
119124
| `uniformDistribution` | bulk | Each particle contributes inversely proportional to the total number of particles | $w_i = 1/n$ where $n$ is the number of particles |
120125
| `GaussianDistribution` | bulk | Weight contribution based on distance from the center with Gaussian falloff | $w_i = \exp(-\|x_i - c\|^2/(2\sigma^2))/\sqrt{2\pi\sigma^2}$ |
126+
| `mixingIndex` | bulk | Calculates mixing quality indices for multi-component granular systems | See [Section 7](#7-mixing-index-calculations) |
121127
| `particleProbe` | individual | Extracts values from specific particles | Direct access to particle properties |
122128
123129
## 5. Region Types
@@ -264,9 +270,187 @@ The above fields may vary from one type of simulation to other. Pleas note that
264270
|`fluctuation2` (in average only)| Calculate fluctuation of field values | `no` | `yes` or `no` |
265271
| `phi` | Field to be used for weighted averaging | `one` | Any valid field name |
266272

267-
## 7. Examples
273+
## 7. Mixing Index Calculations
268274

269-
### 7.1. Example 1: Probing Individual Particles
275+
### 7.1. Overview
276+
277+
The mixing index component provides a specialized postprocessing tool to evaluate the quality of mixing in granular systems containing multiple particle types. This is particularly useful for analyzing mixing and segregation phenomena in industrial processes such as mixing in rotating drums, fluidized beds, and other granular mixers.
278+
279+
The mixing index calculation is a **bulk property** that operates on regions defined by the user. Unlike standard operations that calculate field averages or sums, mixing indices provide a statistical measure of how well different particle types are distributed throughout the domain.
280+
281+
### 7.2. Lacey Mixing Index
282+
283+
Currently, phasicFlow implements the **Lacey Mixing Index**, which is one of the most widely used metrics for assessing mixing quality in particulate systems.
284+
285+
#### Mathematical Definition
286+
287+
The Lacey mixing index is defined as:
288+
289+
$$M = \frac{\sigma_0^2 - \sigma^2}{\sigma_0^2 - \sigma_r^2}$$
290+
291+
where:
292+
293+
- $M$ is the Lacey mixing index (dimensionless, ranging from 0 to 1)
294+
- $\sigma^2$ is the observed variance of the concentration/fraction of one particle type in sample regions
295+
- $\sigma_0^2$ is the maximum variance corresponding to a completely segregated state
296+
- $\sigma_r^2$ is the minimum variance corresponding to a completely mixed (random) state
297+
298+
The variance terms are calculated as:
299+
300+
$$\sigma_0^2 = p(1-p)$$
301+
302+
$$\sigma_r^2 = \frac{p(1-p)}{n}$$
303+
304+
$$\sigma^2 = \frac{1}{N_s}\sum_{i=1}^{N_s}(p_i - p)^2$$
305+
306+
where:
307+
308+
- $p$ is the overall number fraction (concentration) of type 1 particles in the system
309+
- $n$ is the average number of particles per sample region
310+
- $N_s$ is the number of valid sample regions
311+
- $p_i$ is the local fraction of type 1 particles in sample region $i$
312+
313+
#### Interpretation
314+
315+
- **M ≈ 0**: Indicates complete segregation (particles of the same type are clustered together)
316+
- **M ≈ 1**: Indicates complete mixing (particles are randomly distributed)
317+
- **0 < M < 1**: Indicates partial mixing
318+
319+
### 7.3. Configuration
320+
321+
To use mixing index calculations, set `processMethod` to `mixingIndex` in your postprocessing component. The mixing index component requires:
322+
323+
1. **Region Definition**: A `processRegion` that divides the domain into sample volumes (typically `rectMesh`)
324+
2. **Index Type**: Specification of which mixing index to calculate (currently only `Lacey` is available)
325+
3. **Mixing Index Parameters**: Configuration specific to the chosen index type
326+
327+
#### Required Parameters
328+
329+
| Parameter | Description | Example |
330+
|-----------|-------------|---------|
331+
| `processMethod` | Must be set to `mixingIndex` | `mixingIndex` |
332+
| `processRegion` | Type of region for sampling (typically `rectMesh`) | `rectMesh` |
333+
| `indexType` | Type of mixing index to calculate | `Lacey` |
334+
335+
#### Parameters for Lacey Mixing Index
336+
337+
The Lacey-specific parameters are defined in the `LaceyInfo` sub-dictionary:
338+
339+
| Parameter | Description | Type | Required |
340+
|-----------|-------------|------|----------|
341+
| `type1Frac` | Overall number fraction of type 1 particles in the system | `real` | Yes |
342+
| `threshold` | Minimum number of particles in a sample region for it to be included in the calculation | `uint32` | Yes |
343+
| `type1Selection` | Method to identify type 1 particles | `word` | Yes |
344+
345+
#### Type Selection Methods
346+
347+
The `type1Selection` parameter specifies how to identify type 1 particles. It uses the same `includeMask` system as other postprocessing operations. Common options include:
348+
349+
- `equal`: Select particles where a field equals a specific value
350+
- `lessThan`: Select particles where a field is less than a value
351+
- `greaterThan`: Select particles where a field is greater than a value
352+
- `between`: Select particles where a field is between two values
353+
- `lessThanOrEq`, `greaterThanOrEq`, `betweenEq`: Inclusive comparison variants
354+
355+
Each selection method requires its own info sub-dictionary (e.g., `equalInfo`, `lessThanInfo`) with:
356+
- `field`: The particle field to check (e.g., `shapeIndex`, `diameter`)
357+
- `value`: The comparison value(s)
358+
359+
### 7.4. Example Configuration
360+
361+
Here's a complete example for calculating the Lacey mixing index in a rotating drum:
362+
363+
```cpp
364+
mixingIndexCalc
365+
{
366+
processMethod mixingIndex;
367+
368+
processRegion rectMesh;
369+
370+
indexType Lacey;
371+
372+
timeControl default;
373+
374+
precision 4;
375+
376+
scientific no;
377+
378+
rectMeshInfo
379+
{
380+
min (-0.12 -0.12 0.00); // lower corner point of the box
381+
max (0.12 0.12 0.11); // upper corner point of the box
382+
383+
nx 15; // number of divisions in x direction
384+
ny 15; // number of divisions in y direction
385+
nz 8; // number of divisions in z direction
386+
}
387+
388+
LaceyInfo
389+
{
390+
// Overall fraction of type 1 particles (must match actual system composition)
391+
type1Frac 0.5;
392+
393+
// Minimum particles per sample to be included in statistics
394+
threshold 20;
395+
396+
// Method to identify type 1 particles
397+
type1Selection equal;
398+
399+
// Configuration for the equal selection method
400+
equalInfo
401+
{
402+
field shapeIndex; // Use shapeIndex to distinguish particle types
403+
value 0; // Type 1 are particles with shapeIndex = 0
404+
}
405+
}
406+
}
407+
```
408+
409+
#### Alternative Example: Selecting by Diameter
410+
411+
If particle types differ by size, you can use diameter-based selection:
412+
413+
```cpp
414+
LaceyInfo
415+
{
416+
type1Frac 0.3;
417+
threshold 10;
418+
type1Selection lessThan;
419+
420+
lessThanInfo
421+
{
422+
field diameter;
423+
value 0.003; // Type 1 are particles with diameter < 3 mm
424+
}
425+
}
426+
```
427+
428+
#### Output
429+
430+
The mixing index calculation produces a time-series output file in the `postprocessData` folder with the following columns:
431+
432+
1. **time**: Simulation time
433+
2. **numberOfSamples**: Number of valid sample regions (cells with at least `threshold` particles)
434+
3. **avSampleSize**: Average number of particles per valid sample
435+
4. **LaceyMixingIndex**: The calculated Lacey mixing index value
436+
437+
The output file also includes a header with the complete `LaceyInfo` parameters used for the calculation, making it easy to reproduce and verify the analysis.
438+
439+
#### Best Practices
440+
441+
1. **Choose appropriate threshold**: The `threshold` value should be large enough to provide meaningful statistics but not so large that most samples are excluded. A typical range is 10-50 particles per sample.
442+
443+
2. **Select proper mesh resolution**: The `rectMesh` should divide the domain into enough cells to capture spatial variations in mixing, but each cell should contain sufficient particles. Typical mesh sizes range from 10×10×10 to 30×30×30 depending on the system size and particle count.
444+
445+
3. **Ensure accurate type1Frac**: The `type1Frac` parameter must accurately reflect the overall fraction of type 1 particles in your system. An incorrect value will lead to incorrect mixing index values.
446+
447+
4. **Verify particle selection**: Before running long simulations, verify that your `type1Selection` correctly identifies the intended particle type by checking the particle fields in your initial configuration.
448+
449+
For a complete tutorial on using Lacey mixing index calculations, see the example case in [`tutorials/postprocessPhasicFlow/LaceyMixingIndex`](./../../tutorials/postprocessPhasicFlow/LaceyMixingIndex/).
450+
451+
## 8. Examples
452+
453+
### 8.1. Example 1: Probing Individual Particles
270454

271455
```cpp
272456
velocityProb
@@ -282,7 +466,7 @@ velocityProb
282466

283467
This example extracts the y-component of the position for particles with IDs 0, 10, and 100.
284468

285-
### 7.2. Example 2: Processing in a Spherical Region
469+
### 8.2. Example 2: Processing in a Spherical Region
286470

287471
```cpp
288472
on_single_sphere
@@ -342,7 +526,7 @@ This example defines a sphere region and performs three operations:
342526
2. Calculate the fraction of particles with diameter less than 0.0031
343527
3. Calculate the number density by summing and dividing by volume
344528

345-
### 7.3. Example 3: Processing Along a Line
529+
### 8.3. Example 3: Processing Along a Line
346530

347531
In this example, a line region is defined. The `lineInfo` section specifies the start and end points of the line, the number of spheres to create along the line, and the radius of each point. Bulk properties are calculated in each sphere, based on the properties of particles contained in each sphere.
348532

@@ -387,7 +571,7 @@ along_a_line
387571

388572
This example creates 10 spherical regions along a line from (0,0,0) to (0,0.15,0.15) and calculates the bulk density and volume density in each region.
389573

390-
### 7.4 Example 4: Processing in a Rectangular Mesh
574+
### 8.4. Example 4: Processing in a Rectangular Mesh
391575

392576
In this example, a rectangular mesh is defined. The `rectMeshInfo` section specifies the minimum and maximum corner points of the box, the number of divisions in each direction, and an optional cell extension factor which is effective for GaussianDistribution only. In the `operations` section, two operations are defined: one for calculating the average velocity and another for calculating the solid volume fraction.
393577

@@ -436,7 +620,7 @@ on_a_rectMesh
436620
}
437621
```
438622

439-
### 7.5 Example 5: Tracking particles
623+
### 8.5. Example 5: Tracking particles
440624

441625
Suppose we want to mark and track the position of particles that are located inside a box region at t = 1 s. All particles that are inside the box at t = 1 s will be marked/selected and then the position of them are recorded along the simulation time. The following example shows how to do this. Note that marking/selecting of particles is done at the instance that is defined by `startTime`.
442626

@@ -471,9 +655,9 @@ particlesTrack
471655
}
472656
```
473657

474-
## 8. Advanced Features
658+
## 9. Advanced Features
475659

476-
### 8.1. Special functions applied on fields
660+
### 9.1. Special functions applied on fields
477661

478662
You can access specific components of vector fields (`realx3`) using the `component` function:
479663

@@ -495,7 +679,7 @@ Here is a complete list of these special functions:
495679
| `magnitude cube` | `realx3` | `magCube(velocity)` |
496680
| `magnitude square root` | `realx3` | `magSqrt(acceleration)` |
497681
498-
### 8.2. Particle Filtering with includeMask
682+
### 9.2. Particle Filtering with includeMask
499683
500684
The `includeMask` parameter allows you to filter particles based on field values:
501685
@@ -518,15 +702,15 @@ Supported masks:
518702
- `greaterThanOrEq`: Include particles where field ≥ value
519703
- `betweenEq`: Include particles where value1 ≤ field ≤ value2
520704

521-
### 8.3. Implementation Notes
705+
### 9.3. Implementation Notes
522706

523707
- The postprocessing system can work both during simulation (`runTimeActive yes`) or after simulation completion.
524708
- When using post-simulation mode, you must specify the correct `shapeType` to properly initialize the shape objects.
525709
- Results are written to output files in the case directory with timestamps.
526710
- The `threshold` parameter helps eliminate statistical noise in regions with few particles.
527711
- Setting `divideByVolume` to `yes` normalizes results by the volume of the region, useful for calculating densities.
528712

529-
## 9. Mathematical Formulations
713+
## 10. Mathematical Formulations
530714

531715
For weighted `bulk` properties calculation, we have these two general formulations:
532716

@@ -542,7 +726,7 @@ If `divideByVolume` is set to `yes`, the result is divided by the volume of the
542726

543727
$$ \text{volumetric result} = \frac{\text{result}}{V_{\text{region}}} $$
544728

545-
## 10. A complete dictionary file (postprocessDataDict)
729+
## 11. A Complete Dictionary File (postprocessDataDict)
546730

547731
```C++
548732
/* -------------------------------*- C++ -*--------------------------------- *\
@@ -682,6 +866,51 @@ components
682866
);
683867
}
684868

869+
mixingIndexCalc
870+
{
871+
// Calculate mixing index to evaluate mixing quality
872+
processMethod mixingIndex;
873+
874+
processRegion rectMesh;
875+
876+
indexType Lacey;
877+
878+
timeControl default;
879+
880+
precision 4;
881+
882+
scientific no;
883+
884+
rectMeshInfo
885+
{
886+
min (-0.12 -0.12 0.00); // lower corner point of the box
887+
max (0.12 0.12 0.11); // upper corner point of the box
888+
889+
nx 15; // number of divisions in x direction
890+
ny 15; // number of divisions in y direction
891+
nz 8; // number of divisions in z direction
892+
}
893+
894+
LaceyInfo
895+
{
896+
// Overall fraction of type 1 particles (must match actual system composition)
897+
type1Frac 0.5;
898+
899+
// Minimum particles per sample to be included in statistics
900+
threshold 20;
901+
902+
// Method to identify type 1 particles
903+
type1Selection equal;
904+
905+
// Configuration for the equal selection method
906+
equalInfo
907+
{
908+
field shapeIndex; // Use shapeIndex to distinguish particle types
909+
value 0; // Type 1 are particles with shapeIndex = 0
910+
}
911+
}
912+
}
913+
685914
on_single_sphere
686915
{
687916
// method of performing the sum (arithmetic, uniformDistribution, GaussianDistribution)

0 commit comments

Comments
 (0)