special functions for postprocessing: bulkDensity and solidVolFraction

This commit is contained in:
Hamidreza
2025-07-29 20:17:40 +03:30
parent ee8c545bef
commit 53e6d6a02f
10 changed files with 264 additions and 100 deletions

View File

@ -25,6 +25,8 @@ set(SourceFiles
operation/PostprocessOperation/PostprocessOperationSum.cpp operation/PostprocessOperation/PostprocessOperationSum.cpp
operation/PostprocessOperation/PostprocessOperationAverage.cpp operation/PostprocessOperation/PostprocessOperationAverage.cpp
operation/PostprocessOperation/PostprocessOperationAvMassVelocity.cpp operation/PostprocessOperation/PostprocessOperationAvMassVelocity.cpp
operation/PostprocessOperation/PostprocessOperationSolidVolFraction.cpp
operation/PostprocessOperation/PostprocessOperationBulkDensity.cpp
operation/includeMask/includeMask.cpp operation/includeMask/includeMask.cpp
operation/includeMask/IncludeMasks.cpp operation/includeMask/IncludeMasks.cpp

View File

@ -23,106 +23,10 @@ Licence:
/*! /*!
* @class PostprocessOperationAvMassVelocity * @class PostprocessOperationAvMassVelocity
* @brief A class for averaging field values within specified regions during post-processing. * @brief Calculates mass-weighted average velocity of particles in the regions
* *
* @details
* The PostprocessOperationAvMassVelocity class is a specialized post-processing operation that
* calculates the average of field values within specified regions. It inherits from the
* postprocessOperation base class and implements a weighted averaging operation that
* can be applied to scalar (real), vector (realx3), and tensor (realx4) fields.
* *
* The average operation follows the mathematical formula: * @see PostprocessOperationAverage
* \f[
* \text{result} = \frac{\sum_{j \in \text{includeMask}} w_j \cdot \phi_j \cdot \text{field}_j}
* {\sum_{i \in \text{processRegion}} w_i \cdot \phi_i}
* \f]
*
* Where:
* - \f$ i \f$ represents all particles within the specified processing region
* - \f$ j \f$ belongs to a subset of \f$ i \f$ based on an includeMask
* - \f$ w_i \f$ is the weight factor for particle \f$ i \f$
* - \f$ \phi_i \f$ is the value from the phi field for particle \f$ i \f$
* - \f$ \text{field}_j \f$ is the value from the target field for particle \f$ j \f$
*
* The calculation can optionally be divided by the region volume (when divideByVolume is set to yes),
* which allows calculating normalized averages:
* \f[
* \text{result} = \frac{1}{V_{\text{region}}} \frac{\sum_{j \in \text{includeMask}} w_j \cdot \phi_j \cdot \text{field}_j}
* {\sum_{i \in \text{processRegion}} w_i \cdot \phi_i}
* \f]
*
* The averaging can be further filtered using an includeMask to selectively include only
* specific particles that satisfy certain criteria.
*
* This class supports the following field types:
* - real (scalar values)
* - realx3 (vector values)
* - realx4 (tensor values)
*
* @section usage Usage Example
* Below is a sample dictionary showing how to configure and use this class:
*
* ```
* processMethod arithmetic; // method of performing the sum (arithmetic, uniformDistribution, GaussianDistribution)
* processRegion sphere; // type of region on which processing is performed
*
* sphereInfo
* {
* radius 0.01;
* center (-0.08 -0.08 0.015);
* }
*
* timeControl default;
*
* /// all the post process operations to be done
* operations
* (
* // computes the arithmetic mean of particle velocity
* averageVel
* {
* function average;
* field velocity;
* dividedByVolume no; // default is no
* threshold 3; // default is 1
* includeMask all; // include all particles in the calculation
* }
*
* // computes the fraction of par1 in the region
* par1Fraction
* {
* function average;
* field one; // the "one" field is special - all members have value 1.0
* phi one; // default is "one"
* dividedByVolume no;
* includeMask lessThan;
*
* // diameter of par1 is 0.003, so these settings
* // will select only particles of type par1
* lessThanInfo
* {
* field diameter;
* value 0.0031;
* }
* }
* );
* ```
*
* @section defaults Default Behavior
* - By default, `phi` is set to the field named "one" which contains value 1.0 for all entries
* - `dividedByVolume` is set to "no" by default
* - `threshold` is set to 1 by default
* - `includeMask` can be set to various filters, with "all" being the default to include all particles
*
* @section special Special Fields
* The field named "one" is a special field where all members have the value 1.0. This makes it
* particularly useful for calculating:
*
* 1. Volume or number fractions (as shown in the par1Fraction example)
* 2. Simple counts when used with an appropriate mask
* 3. Normalizing values by particle count
*
* @see postprocessOperation
* @see executeAverageOperation
*/ */
#include <variant> #include <variant>

View File

@ -0,0 +1,25 @@
#include "PostprocessOperationBulkDensity.hpp"
namespace pFlow::postprocessData
{
PostprocessOperationBulkDensity::PostprocessOperationBulkDensity
(
const dictionary &opDict,
const regionPoints &regPoints,
fieldsDataBase &fieldsDB
)
:
PostprocessOperationSum
(
opDict,
"mass",
"one",
"all",
regPoints,
fieldsDB
)
{
}
}

View File

@ -0,0 +1,77 @@
/*------------------------------- phasicFlow ---------------------------------
O C enter of
O O E ngineering and
O O M ultiscale modeling of
OOOOOOO F luid flow
------------------------------------------------------------------------------
Copyright (C): www.cemf.ir
email: hamid.r.norouzi AT gmail.com
------------------------------------------------------------------------------
Licence:
This file is part of phasicFlow code. It is a free software for simulating
granular and multiphase flows. You can redistribute it and/or modify it under
the terms of GNU General Public License v3 or any other later versions.
phasicFlow is distributed to help others in their research in the field of
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-----------------------------------------------------------------------------*/
#ifndef __PostprocessOperationBulkDensity_hpp__
#define __PostprocessOperationBulkDensity_hpp__
/*!
* @class PostprocessOperationBulkDensity
* @brief Calculates bulk density in the regions
*
*
* @see PostprocessOperationSum
*/
#include "PostprocessOperationSum.hpp"
namespace pFlow::postprocessData
{
class PostprocessOperationBulkDensity
:
public PostprocessOperationSum
{
public:
TypeInfo("PostprocessOperation<bulkDensity>");
/// @brief Constructs average operation processor
/// @param opDict Operation parameters dictionary
/// @param regPoints Region points data
/// @param fieldsDB Fields database
PostprocessOperationBulkDensity(
const dictionary& opDict,
const regionPoints& regPoints,
fieldsDataBase& fieldsDB);
/// destructor
~PostprocessOperationBulkDensity() override = default;
/// add this virtual constructor to the base class
add_vCtor
(
postprocessOperation,
PostprocessOperationBulkDensity,
dictionary
);
bool divideByVolume()const override
{
return true;
}
};
}
#endif //__PostprocessOperationSolidVolFraction_hpp__

View File

@ -0,0 +1,25 @@
#include "PostprocessOperationSolidVolFraction.hpp"
namespace pFlow::postprocessData
{
PostprocessOperationSolidVolFraction::PostprocessOperationSolidVolFraction
(
const dictionary &opDict,
const regionPoints &regPoints,
fieldsDataBase &fieldsDB
)
:
PostprocessOperationSum
(
opDict,
"volume",
"one",
"all",
regPoints,
fieldsDB
)
{
}
}

View File

@ -0,0 +1,77 @@
/*------------------------------- phasicFlow ---------------------------------
O C enter of
O O E ngineering and
O O M ultiscale modeling of
OOOOOOO F luid flow
------------------------------------------------------------------------------
Copyright (C): www.cemf.ir
email: hamid.r.norouzi AT gmail.com
------------------------------------------------------------------------------
Licence:
This file is part of phasicFlow code. It is a free software for simulating
granular and multiphase flows. You can redistribute it and/or modify it under
the terms of GNU General Public License v3 or any other later versions.
phasicFlow is distributed to help others in their research in the field of
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-----------------------------------------------------------------------------*/
#ifndef __PostprocessOperationSolidVolFraction_hpp__
#define __PostprocessOperationSolidVolFraction_hpp__
/*!
* @class PostprocessOperationSolidVolFraction
* @brief Calculates solid volume fraction in the regions
*
*
* @see PostprocessOperationSum
*/
#include "PostprocessOperationSum.hpp"
namespace pFlow::postprocessData
{
class PostprocessOperationSolidVolFraction
:
public PostprocessOperationSum
{
public:
TypeInfo("PostprocessOperation<solidVolFraction>");
/// @brief Constructs average operation processor
/// @param opDict Operation parameters dictionary
/// @param regPoints Region points data
/// @param fieldsDB Fields database
PostprocessOperationSolidVolFraction(
const dictionary& opDict,
const regionPoints& regPoints,
fieldsDataBase& fieldsDB);
/// destructor
~PostprocessOperationSolidVolFraction() override = default;
/// add this virtual constructor to the base class
add_vCtor
(
postprocessOperation,
PostprocessOperationSolidVolFraction,
dictionary
);
bool divideByVolume()const override
{
return true;
}
};
}
#endif //__PostprocessOperationSolidVolFraction_hpp__

View File

@ -41,6 +41,49 @@ PostprocessOperationSum::PostprocessOperationSum
} }
} }
PostprocessOperationSum::PostprocessOperationSum
(
const dictionary &opDict,
const word &fieldName,
const word &phiName,
const word &includeName,
const regionPoints &regPoints,
fieldsDataBase &fieldsDB
)
:
postprocessOperation(
opDict,
fieldName,
phiName,
includeName,
regPoints,
fieldsDB)
{
if( fieldType() == getTypeName<real>() )
{
processedRegField_ = makeUnique<processedRegFieldType>(
regionField(processedFieldName(), regPoints, real(0)));
}
else if( fieldType() == getTypeName<realx3>() )
{
processedRegField_ = makeUnique<processedRegFieldType>(
regionField(processedFieldName(), regPoints, realx3(0)));
}
else if( fieldType() == getTypeName<realx4>() )
{
processedRegField_ = makeUnique<processedRegFieldType>(
regionField(processedFieldName(), regPoints, realx4(0)));
}
else
{
fatalErrorInFunction<<" in dictionary "<< opDict.globalName()
<< " field type is not supported for sum operation"
<< " field type is "<< fieldType()
<< endl;
fatalExit;
}
}
/// Performs weighted sum of field values within each region /// Performs weighted sum of field values within each region
bool PostprocessOperationSum::execute bool PostprocessOperationSum::execute
( (

View File

@ -154,6 +154,14 @@ public:
const regionPoints& regPoints, const regionPoints& regPoints,
fieldsDataBase& fieldsDB); fieldsDataBase& fieldsDB);
PostprocessOperationSum(
const dictionary& opDict,
const word& fieldName,
const word& phiName,
const word& includeName,
const regionPoints& regPoints,
fieldsDataBase& fieldsDB);
/// destructor /// destructor
~PostprocessOperationSum() override = default; ~PostprocessOperationSum() override = default;

View File

@ -225,6 +225,7 @@ public:
} }
/// whether the result is divided by volume of the region /// whether the result is divided by volume of the region
virtual
bool divideByVolume()const bool divideByVolume()const
{ {
return divideByVolume_(); return divideByVolume_();

View File

@ -220,6 +220,8 @@ In addition to the above basic functions, some derived functions are available f
| Function | Property type | Description | Formula | Required Parameters | | Function | Property type | Description | Formula | Required Parameters |
|----------|---------------|-------------|---------|---------------------| |----------|---------------|-------------|---------|---------------------|
|`avMassVelocity` | bulk | Average velocity weighted by mass | $\frac{\sum_{i \in \text{region}} w_i \cdot m_i \cdot v_i}{\sum_{i \in \text{region}} w_i \cdot m_i}$ | - | |`avMassVelocity` | bulk | Average velocity weighted by mass | $\frac{\sum_{i \in \text{region}} w_i \cdot m_i \cdot v_i}{\sum_{i \in \text{region}} w_i \cdot m_i}$ | - |
|`solidVolFraction`| bulk| Volume fraction of solid| $\phi = \frac{\sum_{i \in \text{region}} w_i \cdot V_i}{V_{\text{region}}}$ | - |
|`bulkDensity`| bulk| Bulk density of particles in the region | $\rho_{bulk} = \frac{\sum_{i \in \text{region}} w_i \cdot m_i}{V_{\text{region}}}$ | - |
### 6.4. Available Fields ### 6.4. Available Fields