From ab7f700ead22a04a38b8421895b9b91caf985682 Mon Sep 17 00:00:00 2001 From: Hamidreza Date: Wed, 9 Apr 2025 19:47:57 +0330 Subject: [PATCH 1/2] first commit for post-processing - the whole structure is ready. - next step whould be execute methods and then write methods - post-processing after simulation is not started yet. --- src/PostProcessData/CMakeLists.txt | 35 + .../fieldsDataBase/fieldFunctions.hpp | 165 +++++ .../fieldsDataBase/fieldsDataBase.cpp | 664 ++++++++++++++++++ .../fieldsDataBase/fieldsDataBase.hpp | 389 ++++++++++ .../fieldsDataBaseTemplates.cpp | 80 +++ .../method/GaussianDistribution.hpp | 107 +++ .../method/uniformDistribution.hpp | 86 +++ .../operation/PostprocessOperationSum.cpp | 69 ++ .../operation/PostprocessOperationSum.hpp | 76 ++ .../operation/fieldFunctions.hpp | 117 +++ .../operation/includeMask/IncludeMask.hpp | 192 +++++ .../operation/includeMask/IncludeMasks.cpp | 50 ++ .../operation/includeMask/includeMask.cpp | 91 +++ .../operation/includeMask/includeMask.hpp | 115 +++ .../operation/includeMask/maskOperations.hpp | 162 +++++ .../operation/postprocessOperation.cpp | 101 +++ .../operation/postprocessOperation.hpp | 167 +++++ .../PostprocessComponent.cpp | 109 +++ .../PostprocessComponent.hpp | 117 +++ .../PostprocessComponentGaussian.hpp | 73 ++ .../PostprocessComponents.cpp | 34 + .../particleProbePostprocessComponent.cpp | 26 + .../particleProbePostprocessComponent.hpp | 94 +++ .../postprocessComponent.cpp | 55 ++ .../postprocessComponent.hpp | 114 +++ src/PostProcessData/postprocessData.cpp | 99 +++ src/PostProcessData/postprocessData.hpp | 103 +++ src/PostProcessData/postprocessDataDict | 108 +++ .../postprocessTimeControl.hpp | 65 ++ .../region/regionFields.hpp/regionField.hpp | 95 +++ .../regionFields.hpp/regionFieldTemplate.cpp | 10 + .../regionPoints/centerPointsRegionPoints.cpp | 86 +++ .../regionPoints/centerPointsRegionPoints.hpp | 116 +++ .../region/regionPoints/lineRegionPoints.cpp | 83 +++ .../region/regionPoints/lineRegionPoints.hpp | 100 +++ .../region/regionPoints/regionPoints.cpp | 28 + .../region/regionPoints/regionPoints.hpp | 103 +++ .../regionPoints/sphereRegionPoints.cpp | 31 + .../regionPoints/sphereRegionPoints.hpp | 98 +++ 39 files changed, 4413 insertions(+) create mode 100644 src/PostProcessData/CMakeLists.txt create mode 100644 src/PostProcessData/fieldsDataBase/fieldFunctions.hpp create mode 100644 src/PostProcessData/fieldsDataBase/fieldsDataBase.cpp create mode 100644 src/PostProcessData/fieldsDataBase/fieldsDataBase.hpp create mode 100644 src/PostProcessData/fieldsDataBase/fieldsDataBaseTemplates.cpp create mode 100644 src/PostProcessData/method/GaussianDistribution.hpp create mode 100644 src/PostProcessData/method/uniformDistribution.hpp create mode 100644 src/PostProcessData/operation/PostprocessOperationSum.cpp create mode 100644 src/PostProcessData/operation/PostprocessOperationSum.hpp create mode 100644 src/PostProcessData/operation/fieldFunctions.hpp create mode 100644 src/PostProcessData/operation/includeMask/IncludeMask.hpp create mode 100644 src/PostProcessData/operation/includeMask/IncludeMasks.cpp create mode 100644 src/PostProcessData/operation/includeMask/includeMask.cpp create mode 100644 src/PostProcessData/operation/includeMask/includeMask.hpp create mode 100644 src/PostProcessData/operation/includeMask/maskOperations.hpp create mode 100644 src/PostProcessData/operation/postprocessOperation.cpp create mode 100644 src/PostProcessData/operation/postprocessOperation.hpp create mode 100644 src/PostProcessData/postprocessComponent/PostprocessComponent.cpp create mode 100644 src/PostProcessData/postprocessComponent/PostprocessComponent.hpp create mode 100644 src/PostProcessData/postprocessComponent/PostprocessComponentGaussian.hpp create mode 100644 src/PostProcessData/postprocessComponent/PostprocessComponents.cpp create mode 100644 src/PostProcessData/postprocessComponent/particleProbePostprocessComponent.cpp create mode 100644 src/PostProcessData/postprocessComponent/particleProbePostprocessComponent.hpp create mode 100644 src/PostProcessData/postprocessComponent/postprocessComponent.cpp create mode 100644 src/PostProcessData/postprocessComponent/postprocessComponent.hpp create mode 100644 src/PostProcessData/postprocessData.cpp create mode 100644 src/PostProcessData/postprocessData.hpp create mode 100755 src/PostProcessData/postprocessDataDict create mode 100644 src/PostProcessData/postprocessTimeControl.hpp create mode 100644 src/PostProcessData/region/regionFields.hpp/regionField.hpp create mode 100644 src/PostProcessData/region/regionFields.hpp/regionFieldTemplate.cpp create mode 100644 src/PostProcessData/region/regionPoints/centerPointsRegionPoints.cpp create mode 100644 src/PostProcessData/region/regionPoints/centerPointsRegionPoints.hpp create mode 100644 src/PostProcessData/region/regionPoints/lineRegionPoints.cpp create mode 100644 src/PostProcessData/region/regionPoints/lineRegionPoints.hpp create mode 100644 src/PostProcessData/region/regionPoints/regionPoints.cpp create mode 100644 src/PostProcessData/region/regionPoints/regionPoints.hpp create mode 100644 src/PostProcessData/region/regionPoints/sphereRegionPoints.cpp create mode 100644 src/PostProcessData/region/regionPoints/sphereRegionPoints.hpp diff --git a/src/PostProcessData/CMakeLists.txt b/src/PostProcessData/CMakeLists.txt new file mode 100644 index 00000000..e5a624a8 --- /dev/null +++ b/src/PostProcessData/CMakeLists.txt @@ -0,0 +1,35 @@ + +set(SourceFiles +fieldsDataBase/fieldsDataBase.cpp + +postprocessComponent/postprocessComponent.cpp +postprocessComponent/PostprocessComponents.cpp + +operation/postprocessOperation.cpp +operation/PostprocessOperationSum.cpp + + +postprocessData.cpp + +postprocessComponent/postprocessComponent.cpp +postprocessComponent/PostprocessComponents.cpp +postprocessComponent/particleProbePostprocessComponent.cpp + +operation/includeMask/includeMask.cpp +operation/includeMask/IncludeMasks.cpp +operation/postprocessOperation.cpp +operation/PostprocessOperationSum.cpp + +region/regionPoints/sphereRegionPoints.cpp +region/regionPoints/regionPoints.cpp +region/regionPoints/lineRegionPoints.cpp +region/regionPoints/centerPointsRegionPoints.cpp + +) + +set(link_libs Kokkos::kokkos phasicFlow Particles) + +pFlow_add_library_install(PostProcessData SourceFiles link_libs) + +add_subdirectory(testPostprocess) + diff --git a/src/PostProcessData/fieldsDataBase/fieldFunctions.hpp b/src/PostProcessData/fieldsDataBase/fieldFunctions.hpp new file mode 100644 index 00000000..ea5b7110 --- /dev/null +++ b/src/PostProcessData/fieldsDataBase/fieldFunctions.hpp @@ -0,0 +1,165 @@ +/*------------------------------- 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 __fieldFunctions_hpp__ +#define __fieldFunctions_hpp__ + +#include "types.hpp" +#include "span.hpp" + +namespace pFlow +{ + +template +inline +void funcCast(span src, span dst) +{ + for(uint32 i=0; i(src[i]); + } +} + +template +inline +void funcAbs(span src, span dst) +{ + for(uint32 i=0; i +inline +void funcSquare(span src, span dst) +{ + for( uint32 i=0; i(src[i]),2); + } +} + +template +inline +void funcCube(span src, span dst) +{ + for( uint32 i=0; i(src[i]),3); + } +} + +template +inline +void funcSquareRoot(span src, span dst) +{ + for( uint32 i=0; i(src[i])); + } +} + +template +inline +void funcMagnitude(span src, span dst) +{ + for( uint32 i=0; i +inline +void funcMagnitudeSquare(span src, span dst) +{ + for( uint32 i=0; i +inline +void funcMagnitudeCube(span src, span dst) +{ + for( uint32 i=0; i +inline +void funcMagnitudeSquareRoot(span src, span dst) +{ + for( uint32 i=0; i src, span dst, char component) +{ + for( uint32 i=0; i src, span dst, char component) +{ + for( uint32 i=0; i + +#include "vocabs.hpp" +#include "Time.hpp" +#include "fieldsDataBase.hpp" +#include "fieldFunctions.hpp" +#include "dynamicPointStructure.hpp" + +bool pFlow::fieldsDataBase::checkForUpdate(const word &name, bool forceUpdate) +{ + auto t = currentTime(); + bool shouldUpdate = false; + + if(auto [iter, found]= captureTime_.findIf(name); found) + { + shouldUpdate = iter->second < t; + iter->second = t; + } + else + { + shouldUpdate = true; + captureTime_.insertIf(name, t); + } + + return shouldUpdate; +} + +pFlow::span pFlow::fieldsDataBase::createOrGetRealField(const word &name) +{ + + bool shouldUpdate = checkForUpdate(name); + + if(shouldUpdate) + { + allFields_.emplaceBackOrReplace> + ( + name, + FieldTypeHost + ( + name, + "value", + pointFieldSize() + ) + ); + } + + auto& field = allFields_.getObject>(name); + return span( + field.data(), + field.size()); +} + +bool pFlow::fieldsDataBase::findFunction( + const word &compoundFieldName, + word &fieldName, + fieldsDataBase::Functions &func) +{ + + std::regex pattern(R"((\w+)?\((\w+)(?:,([xyzw]))?\)|(\w+))"); + std::smatch match; + + if (std::regex_match(compoundFieldName, match, pattern)) + { + if (match[1].matched) // Function is present + { + word functionName = match[1].str(); + fieldName = match[2].str(); + + // Map the function name to the enum value + if(functionName=="component") + { + if (!match[3].matched) // Component is not present + { + fatalErrorInFunction << + "Component (x, y, z, or w) is not specified in the function component: " << compoundFieldName << + " the format is component(u,x), where u is the vector field name and x is the compoenent." << endl; + return false; + } + + switch (match[3].str()[0]) + { + case 'x': func = fieldsDataBase::Functions::ComponentX; break; + case 'y': func = fieldsDataBase::Functions::ComponentY; break; + case 'z': func = fieldsDataBase::Functions::ComponentZ; break; + case 'w': func = fieldsDataBase::Functions::ComponentW; break; + default: + fatalErrorInFunction << + "Invalid component specified: " << match[3].str() << endl; + return false; + } + return true; + } + else if (functionName == "abs") + { + func = fieldsDataBase::Functions::Abs; + } + else if (functionName == "square") + { + func = fieldsDataBase::Functions::Square; + } + else if (functionName == "cube") + { + func = fieldsDataBase::Functions::Cube; + } + else if (functionName == "sqrt") + { + func = fieldsDataBase::Functions::SqureRoot; + } + else if (functionName == "mag") + { + func = fieldsDataBase::Functions::Magnitude; + } + else if (functionName == "magSquare") + { + func = fieldsDataBase::Functions::MagnitudeSquare; + } + else if (functionName == "magCube") + { + func = fieldsDataBase::Functions::MagnitudeCube; + } + else if (functionName == "magSqrt") + { + func = fieldsDataBase::Functions::MagnitudeSquareRoot; + } + else + { + fatalErrorInFunction << + "Unknown function specified: " << functionName<< + " in: "<() || + inputType == getTypeName() ) + { + outputType = getTypeName(); + return true; + } + else + { + fatalErrorInFunction<<"Wrong function: component(u,comp), for input field type: "<() ) + { + outputType = getTypeName(); + return true; + } + else + { + fatalErrorInFunction<<"Wrong function: component(u,w), for input field type: "<() || + inputType == getTypeName() || + inputType == getTypeName() || + inputType == getTypeName() ) + { + outputType = getTypeName(); + return true; + } + else + { + fatalErrorInFunction<<"Wrong input field type for functions abs, squqre, cube, and sqrt."<< + " field type is "<< inputType<() || + inputType == getTypeName() ) + { + outputType = getTypeName(); + return true; + } + else + { + fatalErrorInFunction<<"Wroing input field type for functions mag, magSquare, magCube, magSqrt. "<< + " Input field type is "<< inputType<() || + inputType == getTypeName() || + inputType == getTypeName()) + { + outputType = inputType; + return true; + } + else if( inputType == getTypeName() || + inputType == getTypeName() ) + { + outputType = getTypeName(); + return true; + } + else + { + fatalErrorInFunction<< "Wroing input field type "<< inputType<second; + } + else + { + word fieldTypeName = time_.lookupObjectTypeName(fieldName); + word space; + if(!pointFieldGetType(fieldTypeName, originalType, space)) + { + fatalErrorInFunction<<"Cannot extract type name from "<< fieldTypeName< pFlow::fieldsDataBase::updatePoints(bool forceUpdate) +{ + + bool shouldUpdate = checkForUpdate("position", forceUpdate); + + if(shouldUpdate) + { + const auto& pstruct = pStruct(); + allFields_.emplaceBackOrReplace( + "position", + pstruct.activePointsHost()); + } + + auto& points = allFields_.getObject("position"); + + return span( + points.data(), + points.size()); + +} + +pFlow::span pFlow::fieldsDataBase::updateFieldRealx3 +( + const word &compoundName, + bool forceUpdate +) +{ + word originalType, typeAfterFunction, fieldName; + Functions func; + + if( !getPointFieldType(compoundName, fieldName, originalType, typeAfterFunction, func)) + { + fatalErrorInFunction<< "Error in getting the type name of field: "<< + compoundName<<", with type name: "<< originalType <(nullptr, 0); + } + + if( originalType == getTypeName() && func == Functions::None ) + { + return updateField(fieldName, forceUpdate); + } + else + { + fatalErrorInFunction<< "Error in getting the type name of field: "<< + compoundName<<", with type name: "<< originalType <(nullptr, 0); + } + +} + +pFlow::span pFlow::fieldsDataBase::updateFieldRealx4 +( + const word &compoundName, + bool forceUpdate +) +{ + word originalType, typeAfterFunction, fieldName; + Functions func; + + if( !getPointFieldType(compoundName, fieldName, originalType, typeAfterFunction, func)) + { + fatalErrorInFunction<< "Error in getting the type name of field: "<< + compoundName<<", with type name: "<< originalType <(nullptr, 0); + } + + if( originalType == getTypeName() && func == Functions::None ) + { + return updateField(fieldName, forceUpdate); + } + else + { + fatalErrorInFunction<< "Error in getting the type name of field: "<< + compoundName<<", with type name: "<< originalType <(nullptr, 0); + } + +} + +pFlow::span pFlow::fieldsDataBase::updateFieldReal +( + const word &compoundName, + bool forceUpdate +) +{ + word originalType, typeAfterFunction, fieldName; + Functions func; + + if( !getPointFieldType(compoundName, fieldName, originalType, typeAfterFunction, func)) + { + fatalErrorInFunction<< "Error in getting the type name of field: "<< + compoundName<<", with type name: "<< originalType <(nullptr, 0); + } + + // if the output type is not real, then it is not supported yet + if(typeAfterFunction != getTypeName()) + { + fatalErrorInFunction<< "The output type of field "<< compoundName<< + " is not real, it is: "<< typeAfterFunction<(nullptr, 0); + } + + // if the orginal type is real and no function, then it is a normal field + if( originalType == getTypeName() && func == Functions::None ) + { + return updateField(fieldName, forceUpdate); + } + + // if the original type is uint32, and no funciton, cast to real + if( originalType == getTypeName() && func == Functions::None ) + { + auto sp = updateField(fieldName, forceUpdate); + auto spReal = createOrGetRealField(fieldName+".real"); + funcCast(sp, spReal); + return spReal; + } + else + { + fatalErrorInFunction<<"No function can be applied to field of type uint32. "<< + " The field is: "<< compoundName<(nullptr, 0); + fatalExit; + } + + if( originalType == getTypeName() ) + { + switch(func) + { + case Functions::Abs: + { + auto sp = updateField(fieldName, forceUpdate); + auto spReal = createOrGetRealField(compoundName); + funcAbs(sp, spReal); + return spReal; + } + case Functions::Square: + { + auto sp = updateField(fieldName, forceUpdate); + auto spReal = createOrGetRealField(compoundName); + funcSquare(sp, spReal); + return spReal; + } + case Functions::Cube: + { + auto sp = updateField(fieldName, forceUpdate); + auto spReal = createOrGetRealField(compoundName); + funcCube(sp, spReal); + return spReal; + } + case Functions::SqureRoot: + { + auto sp = updateField(fieldName, forceUpdate); + auto spReal = createOrGetRealField(compoundName+".sqrt"); + funcSquareRoot(sp, spReal); + return spReal; + } + default: + { + fatalErrorInFunction<< "Wrong function for field type real in :"<< + compoundName<(nullptr, 0); + } + } + } + + if( originalType == getTypeName()) + { + switch(func) + { + case Functions::Magnitude: + { + auto sp = updateField(fieldName, forceUpdate); + auto spReal = createOrGetRealField(compoundName); + funcMagnitude(sp, spReal); + return spReal; + } + case Functions::MagnitudeSquare: + { + auto sp = updateField(fieldName, forceUpdate); + auto spReal = createOrGetRealField(compoundName); + funcMagnitudeSquare(sp, spReal); + return spReal; + } + case Functions::MagnitudeCube: + { + auto sp = updateField(fieldName, forceUpdate); + auto spReal = createOrGetRealField(compoundName); + funcMagnitudeCube(sp, spReal); + return spReal; + } + case Functions::MagnitudeSquareRoot: + { + auto sp = updateField(fieldName, forceUpdate); + auto spReal = createOrGetRealField(compoundName); + funcMagnitudeSquareRoot(sp, spReal); + return spReal; + } + case Functions::ComponentX: + { + auto sp = updateField(fieldName, forceUpdate); + auto spReal = createOrGetRealField(compoundName); + funcComponent(sp, spReal, 'x'); + return spReal; + } + case Functions::ComponentY: + { + auto sp = updateField(fieldName, forceUpdate); + auto spReal = createOrGetRealField(compoundName); + funcComponent(sp, spReal, 'y'); + return spReal; + } + case Functions::ComponentZ: + { + auto sp = updateField(fieldName, forceUpdate); + auto spReal = createOrGetRealField(compoundName); + funcComponent(sp, spReal, 'z'); + return spReal; + } + default: + { + fatalErrorInFunction<< "Wrong function for field type realx3 in :"<< + compoundName<(nullptr, 0); + } + } + } + + fatalErrorInFunction<<"NOT SUPPORTED "<(nullptr, 0); +} + +pFlow::span pFlow::fieldsDataBase::updateFieldUint32 +( + const word& name, + bool forceUpdate +) +{ + return updateField(name, forceUpdate); +} + +pFlow::allPointFieldTypes pFlow::fieldsDataBase::updateFieldAll +( + const word &compoundName, + bool forceUpdate +) +{ + word originalType, typeAfterFunction; + + if( !getPointFieldType(compoundName, originalType, typeAfterFunction)) + { + fatalErrorInFunction<< "Error in getting the type name of field: "<< + compoundName<<", with type name: "<< originalType <(nullptr,0); + } + + if( typeAfterFunction== getTypeName() ) + { + return updateField(compoundName, forceUpdate); + } + else if( typeAfterFunction == getTypeName() ) + { + return updateField(compoundName, forceUpdate); + } + else if( typeAfterFunction == getTypeName() ) + { + return updateField(compoundName, forceUpdate); + } + else + { + fatalErrorInFunction<< "Invalid feild "<< compoundName<(nullptr, 0); + } +} + +const pFlow::pointStructure &pFlow::fieldsDataBase::pStruct() const +{ + if(inSimulation_) + { + return + static_cast( + time_.lookupObject(pointStructureFile__) + ); + } + else + { + return time_.lookupObject(pointStructureFile__); + } +} + +bool pFlow::pointFieldGetType(const word& TYPENAME, word& fieldType, word& fieldSpace) +{ + std::regex match("pointField\\<([A-Za-z1-9_]*)\\,([A-Za-z1-9_]*)\\>"); + std::smatch search; + if(!std::regex_match(TYPENAME, search, match)) return false; + if(search.size()!= 3) return false; + fieldType = search[1]; + fieldSpace = search[2]; + return true; +} + diff --git a/src/PostProcessData/fieldsDataBase/fieldsDataBase.hpp b/src/PostProcessData/fieldsDataBase/fieldsDataBase.hpp new file mode 100644 index 00000000..13a71f31 --- /dev/null +++ b/src/PostProcessData/fieldsDataBase/fieldsDataBase.hpp @@ -0,0 +1,389 @@ +/*------------------------------- 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 __fieldsDataBase_hpp__ +#define __fieldsDataBase_hpp__ + +#include +#include + + +#include "pointStructure.hpp" +#include "pointFields.hpp" +#include "anyList.hpp" +#include "Map.hpp" +#include "span.hpp" + +namespace pFlow +{ + +class Time; + +bool pointFieldGetType(const word& TYPENAME, word& fieldType, word& fieldSpace); + +template +concept ValidFieldType = + std::same_as || + std::same_as || + std::same_as || + std::same_as; + +template +concept VectorType = + std::same_as || + std::same_as; + +template +concept ScalarType = + std::same_as; + + +template +concept ValidRegionFieldType = + std::same_as || + std::same_as || + std::same_as ; + + +using allPointFieldTypes = std::variant, span, span>; + + +class fieldsDataBase + +{ +private: + + // - Typedefs + + /// Point position data type + using PointsTypeHost = typename pointStructure::PointsTypeHost; + + /// Point field data type + template + using FieldTypeHost = typename internalField::FieldTypeHost; + + /// @brief Enumeration of functions that can be applied to point fields. + enum class Functions + { + None, /// no function + ComponentX, /// component(u,x) + ComponentY, /// component(u,y) + ComponentZ, /// component(u,z) + ComponentW, /// component(u,w) + Abs, /// abs(s) + Square, /// square(s) + Cube, /// cube(s) + SqureRoot, /// sqrt(s) + Magnitude, /// mag(u) + MagnitudeSquare, /// magSquare(u) + MagnitudeCube, /// magCube(u) + MagnitudeSquareRoot /// magSqrt(u) + }; + + + // - Member variables + + /// const reference to the Time object + const Time& time_; + + /// List to store all the point fields + anyList allFields_; + + /// Map to store the last capture time of each field + wordMap captureTime_; + + /// + bool inSimulation_ = false; + + static const inline std::map reservedFieldNames_ + { + {"position", "realx3"}, + {"one", "real"} + }; + + // - Private member functions + + uint32 pointFieldSize() + { + auto s = updatePoints(); + return s.size(); + } + + /// @brief Checks if a field needs to be updated. + /// @param name The name of the field to check. + /// @param forceUpdate Forces an update if true. Defaults to `false`. + /// @return `true` if the field needs updating or `forceUpdate` is true, `false` otherwise. + bool checkForUpdate(const word& name, bool forceUpdate = false); + + /** + * @brief Updates and retrieves a point field of a specified type from the database. + * + * This is a template function that updates and retrieves a point field of type `T` + * from the database. It checks if the field needs to be updated based on the last + * capture time or if a forced update is requested. If an update is necessary, it + * retrieves the latest data for the field. + * + * @tparam T The type of the point field to update and retrieve. Must be a ValidFieldType. + * @param name The name of the field to update. + * @param forceUpdate A boolean flag indicating whether to force an update of the field + * regardless of its current state. Defaults to `false`. + * + * @return A span of `T` representing the updated field data. + * + * @throws message If the field cannot be found in the database or if there is a type mismatch. + */ + template + span updateField(const word& name, bool forceUpdate = false); + + /// @brief Creates a new real field or retrieves an existing one. + /// + /// If a field with the given name already exists, it returns a span to that field. + /// If the field does not exist, it creates a new real field with the given name + /// and returns a span to the newly created field. + /// + /// @param name The name of the field to create or retrieve. + /// @return span of the field + span createOrGetRealField(const word& name); + + /** + * @brief Parses a compound field name to extract the base field name and function. + * + * This function takes a compound field name, which may include a function applied + * to a base field (e.g., "mag(velocity)"), and parses it to extract the base field + * name (e.g., "velocity") and the function to be applied (e.g., `Functions::Magnitude`). + * + * The function supports the following syntax for compound field names: + * - `fieldName` (no function applied) + * - `functionName(fieldName)` + * + * Supported function names are defined in the `Functions` enum. + * + * @param compoundFieldName The compound field name to parse. + * @param fieldName A reference to a `word` where the extracted base field name + * will be stored. + * @param func A reference to a `Functions` enum where the identified function + * will be stored. If no function is applied, this will be set to + * `Functions::None`. + * + * @return `true` if the compound field name was successfully parsed and the base + * field name and function were extracted, `false` otherwise. + * + * @note The function modifies the `fieldName` and `func` parameters to return the + * extracted information. + */ + static + bool findFunction( + const word& compoundFieldName, + word& fieldName, + fieldsDataBase::Functions& func ); + + /** + * @brief Determines the input and output types for a given function. + * + * This function takes a `Functions` enum value and an input type as a string + * and determines the corresponding output type based on the function being applied. + * + * @param func The function for which to determine the input and output types. + * @param inputType The input type as a string. + * @param outputType A reference to a string where the determined output type will be stored. + * + * @return `true` if the input and output types were successfully determined, `false` otherwise. + */ + static + bool inputOutputType( + fieldsDataBase::Functions func, + const word& inputType, + word& outputType); + +public: + + // - constructors + + fieldsDataBase(const Time& time, bool inSimulation); + + /// no copy constructor + fieldsDataBase(const fieldsDataBase&) = delete; + + /// no move constructor + fieldsDataBase(fieldsDataBase&&) = delete; + + /// no copy assignment + fieldsDataBase& operator=(const fieldsDataBase&) = delete; + + /// no move assignment + fieldsDataBase& operator=(fieldsDataBase&&) = delete; + + /// destructor + ~fieldsDataBase() = default; + + // - Public Access Functions + /// returns the current time + timeValue currentTime()const; + + /// const ref to object Time + const Time& time()const + { + return time_; + } + + // - Public Member Functions + + /** + * @brief Retrieves the type of a point field based on its compound name. + * + * This function attempts to extract the type of a point field from its compound name. + * The compound name may include additional information such as a function or operation + * applied to the field, ie. mag(velcoty). If the type is successfully determined, it + * is stored in the provided `typeName` parameter. + * + * @param compoundName The compound name of the field, which may include additional + * information about operations or functions applied to the field. + * @param originalType A reference to a `word` where the original type name is obtained. + * This will be set to the type of the field before any function is applied. + * @param typeAfterFunction A reference to a `word` where the type name after applying + * the function is obtained. + * @param func the applied function to the field. + * + * @return `true` if the type was successfully determined and stored in `typeName`, + * `false` otherwise. + */ + bool getPointFieldType( + const word& compoundName, + word& fieldName, + word& originalType, + word& typeAfterFunction, + Functions& func); + + /// overload for the function getPointFieldType without `func` argument + bool getPointFieldType( + const word& compoundName, + word& originalType, + word& typeAfterFunction); + + /// overload for function getPointFieldType without `originalType` argument + bool getPointFieldType( + const word& compoundName, + word& typeAfterFunction); + + /** + * @brief Updates the points data and returns a span to the updated points. + * + * This function ensures that the points data is up-to-date by checking if an update + * is necessary. If the data is outdated or if a forced update is requested, it retrieves + * the latest points data and stores it in the internal fields database. The function + * then returns a span to the updated points data for further use. + * + * @param forceUpdate A boolean flag indicating whether to force an update of the points + * data regardless of its current state. Defaults to `false`. + * + * @return A span of `realx3` representing the updated points data. + */ + span updatePoints(bool forceUpdate = false); + + /** + * @brief Updates and retrieves a realx3 point field from the database. + * + * This function retrieves or updates a realx3 field based on its compound name. + * The compound name cannot include any function operation. + * If the field needs to be updated or if forceUpdate is true, the method will + * fetch the latest data from the database. + * + * @param compoundName The name of the field, possibly including a function operation + * @param forceUpdate If true, forces an update of the field regardless of its current state. + * Defaults to false. + * + * @return A span containing the updated realx3 field data + * + * @throws message If the field type is not compatible with realx3 or if the field + * cannot be found in the database + */ + span updateFieldRealx3( + const word& compoundName, + bool forceUpdate = false); + + /** + * @brief Updates and retrieves a realx4 point field from the database. + * + * This function retrieves or updates a realx4 field based on its compound name. + * The compound name cannot include any function operation. + * If the field needs to be updated or if forceUpdate is true, the method will + * fetch the latest data from the database. + * + * @param compoundName The name of the field, possibly including a function operation + * @param forceUpdate If true, forces an update of the field regardless of its current state. + * Defaults to false. + * + * @return A span containing the updated realx3 field data + * + * @throws message If the field type is not compatible with realx4 or if the field + * cannot be found in the database + */ + span updateFieldRealx4( + const word& compoundName, + bool forceUpdate = false); + + /** + * @brief Updates and retrieves a real point field from the database. + * + * This function retrieves or updates a real field based on its compound name. + * The compound name may include a function operation (e.g., abs, square, etc.). + * If the field needs to be updated or if forceUpdate is true, the method will + * fetch the latest data from the database and apply the specified function. + * + * Supported functions include: + * - None: Retrieves the field as is. + * - abs: Computes the absolute value of the field. + * - square: Computes the square of the field. + * - cube: Computes the cube of the field. + * - sqrt: Computes the square root of the field. + * - mag, magSquare, magCube, magSqrt: Compute magnitude-related operations for vector fields. + * - component(x, y, z): Extracts a specific component from a vector field. + * + * @param compoundName The name of the field, possibly including a function operation. + * @param forceUpdate If true, forces an update of the field regardless of its current state. + * Defaults to false. + * + * @return A span containing the updated real field data. + * + * @throws message If the field type is not compatible with real or if the field + * cannot be found in the database. + */ + span updateFieldReal( + const word& compoundName, + bool forceUpdate = false); + + span updateFieldUint32( + const word& name, + bool forceUpdate = false); + + /// Updates and retrieves a point field of any type from the database. + /// It returns types real, realx3 and realx4 only. + allPointFieldTypes updateFieldAll( + const word& compoundName, + bool forceUpdate = false); + + const pointStructure& pStruct()const; +}; + +} // nampespace pFlow + +#include "fieldsDataBaseTemplates.cpp" + +#endif //__fieldsDataBased_hpp__ diff --git a/src/PostProcessData/fieldsDataBase/fieldsDataBaseTemplates.cpp b/src/PostProcessData/fieldsDataBase/fieldsDataBaseTemplates.cpp new file mode 100644 index 00000000..888a6136 --- /dev/null +++ b/src/PostProcessData/fieldsDataBase/fieldsDataBaseTemplates.cpp @@ -0,0 +1,80 @@ +/*------------------------------- 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 __fieldsDataBaseTemplates_hpp__ +#define __fieldsDataBaseTemplates_hpp__ + +#include "fieldsDataBase.hpp" + +template +inline +pFlow::span pFlow::fieldsDataBase::updateField(const word& name, bool forceUpdate) +{ + + bool shouldUpdate = checkForUpdate(name, forceUpdate); + + if(shouldUpdate) + { + if(name == "one") + { + allFields_.emplaceBackOrReplace> + ( + "one", + FieldTypeHost + ( + "one", + "value", + pointFieldSize(), + T{1} + ) + ); + } + else if( name == "position") + { + if constexpr( std::same_as) + { + return updatePoints(forceUpdate); + } + else + { + fatalErrorInFunction<< "Error in getting the type name of field: "<< + name<<", with type name: "<< getTypeName() <(nullptr, 0); + } + } + else + { + const auto& pField = time_.lookupObject>(name); + allFields_.emplaceBackOrReplace>( + name, + pField.activeValuesHost()); + } + } + + auto& field = allFields_.getObject>(name); + + return span( + field.data(), + field.size()); + +} + +#endif //__fieldsDataBaseTemplates_hpp__ \ No newline at end of file diff --git a/src/PostProcessData/method/GaussianDistribution.hpp b/src/PostProcessData/method/GaussianDistribution.hpp new file mode 100644 index 00000000..53889b76 --- /dev/null +++ b/src/PostProcessData/method/GaussianDistribution.hpp @@ -0,0 +1,107 @@ +/*------------------------------- 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 __GaussianDistribution_hpp__ +#define __GaussianDistribution_hpp__ + +#include + +#include "typeInfo.hpp" +#include "types.hpp" +#include "span.hpp" + + +namespace pFlow +{ + +class GaussianDistribution +{ +private: + + std::vector weight_; + + real variance_ = 1.0; + + realx3 mean_ = {0,0,0}; + +public: + + TypeInfoNV("GaussianDistribution"); + + + GaussianDistribution() = default; + + GaussianDistribution(realx3 mean, real variance) + : + weight_(), + variance_(variance), + mean_(mean) + {} + + GaussianDistribution(const GaussianDistribution&) = default; + + GaussianDistribution(GaussianDistribution&&) = default; + + GaussianDistribution& operator =(const GaussianDistribution&) = default; + + GaussianDistribution& operator = (GaussianDistribution&&) = default; + + ~GaussianDistribution()=default; + + bool updateWeights(const realx3& center, const span& indices, const span& points) + { + weight_.clear(); + weight_.resize(indices.size()); + + real sum = 0.0; + for(uint32 i=0; i getWeights() + { + return span(weight_.data(), weight_.size()); + } + +}; +} // namespace pFlow + +#endif // __GaussianDistribution_hpp__ \ No newline at end of file diff --git a/src/PostProcessData/method/uniformDistribution.hpp b/src/PostProcessData/method/uniformDistribution.hpp new file mode 100644 index 00000000..736d9d2f --- /dev/null +++ b/src/PostProcessData/method/uniformDistribution.hpp @@ -0,0 +1,86 @@ +/*------------------------------- 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 __uniformDistribution_hpp__ +#define __uniformDistribution_hpp__ + +#include "types.hpp" +#include "typeInfo.hpp" +#include "span.hpp" + +namespace pFlow +{ + +class dictionary; + +class uniformDistribution +{ +private: + + std::vector weight_; + +public: + + // type info + TypeInfoNV("uniformDistribution"); + + uniformDistribution() + {} + + uniformDistribution(const uniformDistribution&) = default; + + uniformDistribution(uniformDistribution&&) = default; + + uniformDistribution& operator=(const uniformDistribution&) = default; + + uniformDistribution& operator=(uniformDistribution&&) = default; + + ~uniformDistribution()=default; + + + bool updateWeights(const realx3& center, const span& points) + { + uint32 n = max(points.size(), 1u); + weight_.assign(n, 1.0/n); + return true; + } + + bool updateWeights(uint32 n) + { + n = max(n, 1u); + weight_.assign(n, 1.0/n); + return true; + } + + real getWeight(uint32 i)const + { + return weight_[i]; + } + + span getWeights() + { + return span(weight_.data(), weight_.size()); + } + +}; + +} + +#endif //__uniformDistribution_hpp__ \ No newline at end of file diff --git a/src/PostProcessData/operation/PostprocessOperationSum.cpp b/src/PostProcessData/operation/PostprocessOperationSum.cpp new file mode 100644 index 00000000..259ff951 --- /dev/null +++ b/src/PostProcessData/operation/PostprocessOperationSum.cpp @@ -0,0 +1,69 @@ +#include "PostprocessOperationSum.hpp" +#include "dictionary.hpp" +#include "fieldsDataBase.hpp" +#include "fieldFunctions.hpp" + +pFlow::PostprocessOperationSum::PostprocessOperationSum +( + const dictionary &opDict, + const regionPoints ®Points, + fieldsDataBase &fieldsDB +) +: + postprocessOperation(opDict, regPoints, fieldsDB) +{ + if( fieldType() == getTypeName() ) + { + processedRegField_ = makeUnique( + regionField(processedFieldName(), regPoints, real(0))); + } + else if( fieldType() == getTypeName() ) + { + processedRegField_ = makeUnique( + regionField(processedFieldName(), regPoints, realx3(0))); + } + else if( fieldType() == getTypeName() ) + { + processedRegField_ = makeUnique( + 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; + } +} + +bool pFlow::PostprocessOperationSum::execute +( + const std::vector>& weights +) +{ + auto allField = database().updateFieldAll(fieldName()); + auto phi = database().updateFieldReal( + phiFieldName()); + + auto mask = getMask(); + word procName = processedFieldName(); + const auto& regP = regPoints(); + bool dbVol = divideByVolume(); + + + std::visit([&](auto&& field)->processedRegFieldType + { + return executeSumOperation( + procName, + field, + regP, + dbVol, + weights, + phi, + mask); + }, + allField); + + return true; +} diff --git a/src/PostProcessData/operation/PostprocessOperationSum.hpp b/src/PostProcessData/operation/PostprocessOperationSum.hpp new file mode 100644 index 00000000..5e9cb314 --- /dev/null +++ b/src/PostProcessData/operation/PostprocessOperationSum.hpp @@ -0,0 +1,76 @@ +/*------------------------------- 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 __PostprocessOperationSum_hpp__ +#define __PostprocessOperationSum_hpp__ + +#include +#include + +#include "postprocessOperation.hpp" +#include "regionField.hpp" +#include "includeMask.hpp" + +namespace pFlow +{ + + +class PostprocessOperationSum +: + public postprocessOperation +{ +private: + + using processedRegFieldType = std::variant + < + regionField, + regionField, + regionField + >; + + /// Pointer to the include mask used for masking operations. + uniquePtr processedRegField_ = nullptr; + +public: + + TypeInfo("PostprocessOperation"); + + PostprocessOperationSum( + const dictionary& opDict, + const regionPoints& regPoints, + fieldsDataBase& fieldsDB); + + ~PostprocessOperationSum() override = default; + + add_vCtor + ( + postprocessOperation, + PostprocessOperationSum, + dictionary + ); + + bool execute(const std::vector>& weights) override; + +}; + + +} + +#endif //__PostprocessOperation_hpp__ \ No newline at end of file diff --git a/src/PostProcessData/operation/fieldFunctions.hpp b/src/PostProcessData/operation/fieldFunctions.hpp new file mode 100644 index 00000000..8e9d6427 --- /dev/null +++ b/src/PostProcessData/operation/fieldFunctions.hpp @@ -0,0 +1,117 @@ +/*------------------------------- 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 __fieldFunctions_hpp__ +#define __fieldFunctions_hpp__ + +#include + +#include "span.hpp" +#include "regionPoints.hpp" +#include "regionField.hpp" +#include "includeMask.hpp" + +namespace pFlow +{ + +template +regionField executeSumOperation +( + const word& regFieldName, + const span& field, + const regionPoints& regPoints, + const bool devideByVol, + const std::vector>& weights, + const span& phi, + const includeMask::Mask& mask +) +{ + regionField processedField(regFieldName, regPoints, T{}); + + for(uint32 reg =0; reg +regionField executeAverageOperation +( + const word& regFieldName, + const span& field, + const regionPoints& regPoints, + const std::vector>& weights, + const span& phi, + const includeMask::Mask& mask +) +{ + regionField processedField(regFieldName, regPoints, T{}); + + for(uint32 reg =0; reg +class IncludeMask +: + public includeMask +{ +public: + + using Mask = typename includeMask::Mask; + +private: + + std::vector mask_; + + Operator operator_; + + word fieldName_; + + timeValue lastUpdated_ = -1; + + bool updateMask() + { + timeValue t = database().currentTime(); + + if( equal( t, lastUpdated_)) return true; + + span s; + if constexpr (std::is_same_v) + { + s = database().updateFieldReal(fieldName_); + } + else if constexpr ( std::is_same_v) + { + s = database().updateFieldRealx3(fieldName_); + } + else if constexpr( std::is_same_v) + { + s = database().updateFieldRealx4(fieldName_); + } + else + { + fatalErrorInFunction<<"Type "<< getTypeName() + <<" is not supported for IncludeMask for field " + << fieldName_ << endl; + return false; + } + + + mask_.resize(s.size()); + + for(uint32 i=0; i("field")) + {} + + add_vCtor( + includeMask, + IncludeMask, + dictionary); + + Mask getMask() override + { + updateMask(); + return Mask(mask_); + } + +}; + + +template +class IncludeMask> +: + public includeMask +{ +public: + + using Mask = typename includeMask::Mask; + +private: + + std::vector mask_; + + timeValue lastUpdated_ = -1; + + bool updateMask() + { + timeValue t = database().currentTime(); + + if( equal( t, lastUpdated_)) return true; + + span s = database().updatePoints(); + mask_.resize(s.size(), true); + + lastUpdated_ = t ; + + return true; + } + +public: + + TypeInfoTemplate12("IncludeMask", T, allOp); + + IncludeMask( + const dictionary& opDict, + fieldsDataBase& feildsDB) + : + includeMask(opDict, feildsDB) + { + span s = database().updatePoints(); + mask_.resize(s.size(), true); + } + + add_vCtor( + includeMask, + IncludeMask, + dictionary); + + Mask getMask()override + { + updateMask(); + return Mask(mask_); + } + +}; + + +} // pFlow + +#endif //__IncludeMask_hpp__ + + diff --git a/src/PostProcessData/operation/includeMask/IncludeMasks.cpp b/src/PostProcessData/operation/includeMask/IncludeMasks.cpp new file mode 100644 index 00000000..8fd6cd3e --- /dev/null +++ b/src/PostProcessData/operation/includeMask/IncludeMasks.cpp @@ -0,0 +1,50 @@ +/*------------------------------- 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. + +-----------------------------------------------------------------------------*/ + +#include "IncludeMask.hpp" + +// real +template class pFlow::IncludeMask >; +template class pFlow::IncludeMask >; + +template class pFlow::IncludeMask >; +template class pFlow::IncludeMask >; + +template class pFlow::IncludeMask >; + +template class pFlow::IncludeMask >; +template class pFlow::IncludeMask >; + +template class pFlow::IncludeMask>; + +// realx3 +template class pFlow::IncludeMask >; +template class pFlow::IncludeMask >; + +template class pFlow::IncludeMask >; +template class pFlow::IncludeMask >; + +template class pFlow::IncludeMask >; + +template class pFlow::IncludeMask >; +template class pFlow::IncludeMask >; + + +// realx4 diff --git a/src/PostProcessData/operation/includeMask/includeMask.cpp b/src/PostProcessData/operation/includeMask/includeMask.cpp new file mode 100644 index 00000000..a2703b1f --- /dev/null +++ b/src/PostProcessData/operation/includeMask/includeMask.cpp @@ -0,0 +1,91 @@ +/*------------------------------- 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. + +-----------------------------------------------------------------------------*/ + + +#include "includeMask.hpp" +#include "dictionary.hpp" +#include "fieldsDataBase.hpp" + + +pFlow::includeMask::includeMask +( + const dictionary& dict, + fieldsDataBase& fieldDB +) +: + database_(fieldDB) +{} + + +pFlow::uniquePtr pFlow::includeMask::create +( + const dictionary& opDict, + fieldsDataBase& feildsDB +) +{ + word mask = opDict.getValOrSet("includeMask", "all"); + word fieldType; + if( mask != "all") + { + auto& maskDict = opDict.subDict(mask+"Info"); + word maskField = maskDict.getVal("field"); + + if( !feildsDB.getPointFieldType(maskField, fieldType) ) + { + fatalErrorInFunction<<"Error in retriving the type of field" + << maskField <<" from dictionary " + << maskDict.globalName() + << endl; + fatalExit; + return nullptr; + } + } + else + { + fieldType = getTypeName(); + } + + word method = angleBracketsNames2("IncludeMask", fieldType, mask); + + if( dictionaryvCtorSelector_.search(method) ) + { + auto objPtr = + dictionaryvCtorSelector_[method] + (opDict, feildsDB); + return objPtr; + } + else + { + printKeys + ( + fatalError << "Ctor Selector "<< + method << " dose not exist. \n" + <<"Avaiable ones are: \n\n" + , + dictionaryvCtorSelector_ + ); + fatalExit; + return nullptr; + } + return nullptr; +} + + + diff --git a/src/PostProcessData/operation/includeMask/includeMask.hpp b/src/PostProcessData/operation/includeMask/includeMask.hpp new file mode 100644 index 00000000..f277ec7b --- /dev/null +++ b/src/PostProcessData/operation/includeMask/includeMask.hpp @@ -0,0 +1,115 @@ +/*------------------------------- 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 __includeMask_hpp__ +#define __includeMask_hpp__ + +#include + +#include "virtualConstructor.hpp" + +namespace pFlow +{ + + +class fieldsDataBase; +class dictionary; + +class includeMask +{ +public: + + class Mask + { + const std::vector& mask_; + + public: + + Mask(const std::vector& msk) + : + mask_(msk) + {} + + Mask(const Mask&) = default; + + Mask(Mask&&) = default; + + ~Mask()=default; + + auto size()const + { + return mask_.size(); + } + + bool operator()(uint32 i)const + { + return mask_[i]; + } + }; + +private: + + fieldsDataBase& database_; + +public: + + TypeInfo("includeMask"); + + includeMask(const dictionary& opDict, fieldsDataBase& feildsDB); + + virtual ~includeMask() = default; + + create_vCtor + ( + includeMask, + dictionary, + ( + const dictionary& opDict, fieldsDataBase& feildsDB + ), + (opDict, feildsDB) + ); + + const fieldsDataBase& database()const + { + return database_; + } + + fieldsDataBase& database() + { + return database_; + } + + virtual + Mask getMask()= 0; + + static + uniquePtr create( + const dictionary& opDict, + fieldsDataBase& feildsDB); + +}; + + + +} // pFlow + +#endif //__IncludeMask_hpp__ + + diff --git a/src/PostProcessData/operation/includeMask/maskOperations.hpp b/src/PostProcessData/operation/includeMask/maskOperations.hpp new file mode 100644 index 00000000..13fec7d3 --- /dev/null +++ b/src/PostProcessData/operation/includeMask/maskOperations.hpp @@ -0,0 +1,162 @@ + +#ifndef __maskOperation_hpp__ +#define __maskOperation_hpp__ + +#include "types.hpp" +#include "dictionary.hpp" + +namespace pFlow +{ + +template +struct greaterThanOp +{ + TypeInfoNV("greaterThan"); + + inline + bool operator()(const T &compVal, const T &val) const { + return val > compVal; } +}; + +template +struct greaterThanEqOp +{ + TypeInfoNV("greaterThanEq"); + + inline + bool operator()(const T &compVal, const T &val) const { + return val >= compVal; } +}; + +template +struct lessThanOp +{ + TypeInfoNV("lessThan"); + + inline + bool operator()(const T &compVal, const T &val) const { + return val < compVal; } +}; + +template +struct lessThanEqOp +{ + TypeInfoNV("lessThanEq"); + + inline + bool operator()(const T &compVal, const T &val) const { + return val <= compVal; } +}; + +template +struct equalOp +{ + TypeInfoNV("equal"); + + inline + bool operator()(const T &compVal, const T &val) const { + return equal(val , compVal); } +}; + + +template +struct betweenOp +{ + TypeInfoNV("between"); + + inline + bool operator()(const T &compVal1, const T &compVal2 ,const T &val) const { + return val>compVal1 && val +struct betweenEqOp +{ + TypeInfoNV("betweenEq"); + + inline + bool operator()(const T &compVal1, const T &compVal2 ,const T &val) const { + return val>=compVal1 && val<=compVal2; } +}; + +template +struct allOp +{ + TypeInfoNV("all"); + + inline + bool operator()() const {return true; } +}; + + + +template class Operator> +class compareOne +{ +public: + + using opertorType = Operator; + +protected: + T compValue_{}; + opertorType operator_{}; +public: + + TypeInfoNV(Operator::TYPENAME()); + + compareOne(const dictionary& dict) + : + compValue_(dict.getVal("value")) + {} + + bool operator()(const T& value)const + { + return operator_(compValue_, value); + } +}; + +template class Operator> +class compareTwo +{ +public: + using opertorType = Operator; +protected: + T compValue1_; + T compValue2_; + opertorType operator_{}; +public: + + TypeInfoNV(opertorType::TYPENAME()); + + compareTwo(const dictionary& dict) + : + compValue1_(dict.getVal("value1")), + compValue2_(dict.getVal("value2")) + {} + + bool operator()(const T& value)const + { + return operator_(compValue1_, compValue2_, value); + } +}; + +template +class compareZero +{ +protected: + Operator operator_{}; +public: + + TypeInfoNV(Operator::TYPENAME()); + compareZero(const dictionary& dict); + + bool operator()(const T& value) const + { + return operator_(); + } +}; + +} + +#endif //__maskOperation_hpp__ \ No newline at end of file diff --git a/src/PostProcessData/operation/postprocessOperation.cpp b/src/PostProcessData/operation/postprocessOperation.cpp new file mode 100644 index 00000000..c37961c1 --- /dev/null +++ b/src/PostProcessData/operation/postprocessOperation.cpp @@ -0,0 +1,101 @@ +/*------------------------------- 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. + +-----------------------------------------------------------------------------*/ + +#include "postprocessOperation.hpp" +#include "regionPoints.hpp" +#include "fieldsDataBase.hpp" + +pFlow::postprocessOperation::postprocessOperation +( + const dictionary &opDict, + const regionPoints& regPoints, + fieldsDataBase &fieldsDB +) +: + operationDict_(opDict), + threshold_ + ( + opDict.getValOrSet("threshold", 1) + ), + divideByVolume_ + ( + opDict.getValOrSet("dividedByVolume", Logical(false)) + ), + regionPoints_ + ( + regPoints + ), + database_ + ( + fieldsDB + ), + fieldName_ + ( + opDict.getValOrSet("field", "one") + ), + phiFieldName_ + ( + opDict.getValOrSet("phi", "one") + ), + includeMask_ + ( + includeMask::create(opDict, fieldsDB) + ) +{ + + if(!fieldsDB.getPointFieldType(fieldName_, fieldType_)) + { + fatalErrorInFunction; + fatalExit; + } +} + +pFlow::uniquePtr + pFlow::postprocessOperation::create + ( + const dictionary &opDict, + const regionPoints& regPoints, + fieldsDataBase &fieldsDB + ) +{ + word func = opDict.getVal("function"); + word method = angleBracketsNames("PostprocessOperation", func); + if( dictionaryvCtorSelector_.search(method) ) + { + REPORT(3)<<"Operation "<< Green_Text(opDict.name())<<" with function "<< Green_Text(func)< includeMask_ = nullptr; + +public: + + + TypeInfo("postprocessOperation"); + + postprocessOperation( + const dictionary& opDict, + const regionPoints& regPoints, + fieldsDataBase& fieldsDB ); + + virtual ~postprocessOperation()=default; + + create_vCtor( + postprocessOperation, + dictionary, + ( + const dictionary& opDict, + const regionPoints& regPoints, + fieldsDataBase& fieldsDB + ), + (opDict, regPoints, fieldsDB)); + + const regionPoints& regPoints()const + { + return regionPoints_; + } + + const fieldsDataBase& database()const + { + return database_; + } + + fieldsDataBase& database() + { + return database_; + } + + word processedFieldName()const + { + return operationDict_.name(); + } + + const word& fieldName()const + { + return fieldName_; + } + + const word& fieldType()const + { + return fieldType_; + } + + const word& phiFieldName()const + { + return phiFieldName_; + } + + const dictionary& operationDict()const + { + return operationDict_; + } + const uint32 threshold()const + { + return threshold_; + } + + bool divideByVolume()const + { + return divideByVolume_(); + } + + Mask getMask() + { + return includeMask_().getMask(); + } + + + virtual + bool execute(const std::vector>& weights) = 0; + + static + uniquePtr create( + const dictionary& opDict, + const regionPoints& regPoints, + fieldsDataBase& fieldsDB); + +}; + +} + +#endif //__postprocessOperation_hpp__ \ No newline at end of file diff --git a/src/PostProcessData/postprocessComponent/PostprocessComponent.cpp b/src/PostProcessData/postprocessComponent/PostprocessComponent.cpp new file mode 100644 index 00000000..5720bdaa --- /dev/null +++ b/src/PostProcessData/postprocessComponent/PostprocessComponent.cpp @@ -0,0 +1,109 @@ +#include "PostprocessComponent.hpp" +/*------------------------------- 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. + +-----------------------------------------------------------------------------*/ + +template +pFlow::PostprocessComponent::PostprocessComponent +( + const dictionary& dict, + fieldsDataBase& fieldsDB, + const baseTimeControl& defaultTimeControl +) +: + postprocessComponent(dict, fieldsDB, defaultTimeControl), + regionPointsPtr_ + ( + makeUnique(dict, fieldsDB) + ), + regionsProcessMethod_ + ( + regionPointsPtr_().size() + ), + operationDicts_(readDictList("operations", dict)) +{ + + for(auto& opDict:operationDicts_) + { + operatios_.push_back + ( + postprocessOperation::create + ( + opDict, + regionPointsPtr_(), + this->database() + ) + ); + } +} + + +template +bool pFlow::PostprocessComponent::execute +( + const timeInfo &ti, + bool forceUpdate +) +{ + + if( !timeControl().eventTime(ti)) + { + executed_ = false; + return true; + } + + // update processing methods + + auto centers = this->regPoints().centers(); + const uint32 n = centers.size(); + auto points = this->database().updatePoints(); + + for(uint32 i=0; iregPoints().indices(i); + regionsProcessMethod_[i].updateWeights( + centers[i], + indices, + points); + } + + std::vector> weights(n); + + for(uint32 i=0; iexecute(weights) ) + { + fatalErrorInFunction + <<"error occured in executing operatoin defined in dict " + << op->operationDict() + < + +#include "ListPtr.hpp" +#include "List.hpp" +#include "postprocessComponent.hpp" +#include "postprocessOperation.hpp" +#include "dictionaryList.hpp" +#include "fieldsDataBase.hpp" +#include "regionPoints.hpp" +#include "regionField.hpp" + +namespace pFlow +{ + +template +class PostprocessComponent +: + public postprocessComponent +{ +private: + + + ListPtr operatios_; + + /// Region type for selecting a subset of particles for processing + uniquePtr regionPointsPtr_; + + /// Method for processing the selected particles data + std::vector regionsProcessMethod_; + + bool executed_{false}; + + dictionaryList operationDicts_; + +protected: + + std::vector& regionProecessMethod() + { + return regionsProcessMethod_; + } + +public: + + // type info + TypeInfoTemplate12( + "PostprocessComponent", + RegionType, + ProcessMethodType); + + PostprocessComponent( + const dictionary& dict, + fieldsDataBase& fieldsDB, + const baseTimeControl& defaultTimeControl); + + ~PostprocessComponent() override = default; + + // add the virtual constructor + add_vCtor( + postprocessComponent, + PostprocessComponent, + dictionary + ); + + word name()const override + { + return operationDicts_.parrent().name(); + } + + regionPoints& regPoints() override + { + return static_cast(regionPointsPtr_()); + } + + const regionPoints& regPoints()const override + { + return static_cast(regionPointsPtr_()); + } + + bool execute(const timeInfo& ti, bool forceUpdate = false) override; + + bool executed()const override + { + return executed_; + } + + + +}; + +} + +#include "PostprocessComponent.cpp" + +#endif \ No newline at end of file diff --git a/src/PostProcessData/postprocessComponent/PostprocessComponentGaussian.hpp b/src/PostProcessData/postprocessComponent/PostprocessComponentGaussian.hpp new file mode 100644 index 00000000..d846ddcc --- /dev/null +++ b/src/PostProcessData/postprocessComponent/PostprocessComponentGaussian.hpp @@ -0,0 +1,73 @@ +/*------------------------------- 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 __PostprocessComponentGaussian_hpp__ +#define __PostprocessComponentGaussian_hpp__ + +#include "PostprocessComponent.hpp" +#include "GaussianDistribution.hpp" + +namespace pFlow +{ + +template +class PostprocessComponentGaussian +: + public PostprocessComponent +{ +public: + + /// type info + TypeInfoTemplate12("PostprocessComponent", RegionType, GaussianDistribution); + + PostprocessComponentGaussian + ( + const dictionary& dict, + fieldsDataBase& fieldsDB, + const baseTimeControl& defaultTimeControl + ) + : + PostprocessComponent(dict, fieldsDB, defaultTimeControl) + { + /// initializes the Gaussian distribution for all elements of region + //const uint32 n = this->regPoints().size(); + auto d = this->regPoints().eqDiameters(); + auto c = this->regPoints().centers(); + auto& regs = this->regionProecessMethod(); + const uint32 n = d.size(); + for(uint32 i=0; i; + + diff --git a/src/PostProcessData/postprocessComponent/particleProbePostprocessComponent.cpp b/src/PostProcessData/postprocessComponent/particleProbePostprocessComponent.cpp new file mode 100644 index 00000000..33105c41 --- /dev/null +++ b/src/PostProcessData/postprocessComponent/particleProbePostprocessComponent.cpp @@ -0,0 +1,26 @@ +#include "particleProbePostprocessComponent.hpp" + +pFlow::particleProbePostprocessComponent::particleProbePostprocessComponent +( + const dictionary &dict, + fieldsDataBase &fieldsDB, + const baseTimeControl &defaultTimeControl +) +: + postprocessComponent(dict, fieldsDB, defaultTimeControl), + regionPointsPtr_ + ( + makeUnique(dict, fieldsDB) + ), + name_(dict.name()) +{} + +bool pFlow::particleProbePostprocessComponent::execute +( + const timeInfo &ti, + bool forceExecute +) +{ + + return false; +} diff --git a/src/PostProcessData/postprocessComponent/particleProbePostprocessComponent.hpp b/src/PostProcessData/postprocessComponent/particleProbePostprocessComponent.hpp new file mode 100644 index 00000000..7ceaf893 --- /dev/null +++ b/src/PostProcessData/postprocessComponent/particleProbePostprocessComponent.hpp @@ -0,0 +1,94 @@ +/*------------------------------- 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 __particleProbePostprocessComponent_hpp__ +#define __particleProbePostprocessComponent_hpp__ + +#include "postprocessComponent.hpp" +#include "fieldsDataBase.hpp" +#include "centerPointsRegionPoints.hpp" +#include "regionField.hpp" + +namespace pFlow +{ + +class particleProbePostprocessComponent +: + public postprocessComponent +{ +private: + + using processedRegFieldType = std::variant + < + regionField, + regionField, + regionField + >; + + bool executed_{false}; + + uniquePtr regionPointsPtr_; + + uniquePtr processedField_ = nullptr; + + word name_; + +public: + + TypeInfo("PostprocessComponent"); + + particleProbePostprocessComponent + ( + const dictionary& dict, + fieldsDataBase& fieldsDB, + const baseTimeControl& defaultTimeControl + ); + + ~particleProbePostprocessComponent()override = default; + + + word name()const override + { + return name_; + } + + regionPoints& regPoints() override + { + return regionPointsPtr_(); + } + + + const regionPoints& regPoints() const override + { + return regionPointsPtr_(); + } + + bool execute(const timeInfo& ti, bool forceExecute = false) override; + + bool executed() const override + { + return executed_; + } + +}; + +} + +#endif //__particleProbePostprocessComponent_hpp__ \ No newline at end of file diff --git a/src/PostProcessData/postprocessComponent/postprocessComponent.cpp b/src/PostProcessData/postprocessComponent/postprocessComponent.cpp new file mode 100644 index 00000000..ed2e3b6c --- /dev/null +++ b/src/PostProcessData/postprocessComponent/postprocessComponent.cpp @@ -0,0 +1,55 @@ +#include "postprocessComponent.hpp" +#include "fieldsDataBase.hpp" +#include "Time.hpp" + + +pFlow::postprocessComponent::postprocessComponent +( + const dictionary &dict, + fieldsDataBase &fieldsDB, + const baseTimeControl &defaultTimeControl +) +: + timeControl_( + dict, + defaultTimeControl, + baseTimeControl( + fieldsDB.time().startTime(), + fieldsDB.time().endTime(), + fieldsDB.time().saveInterval()) + ), + fieldsDataBase_(fieldsDB) +{ +} + + +pFlow::uniquePtr pFlow::postprocessComponent::create +( + const dictionary& dict, + fieldsDataBase& fieldsDB, + const baseTimeControl& defaultTimeControl +) +{ + word method = dict.getVal("processMethod"); + word region = dict.getVal("processRegion"); + + auto compModel = angleBracketsNames2("PostprocessComponent", region, method); + + if( dictionaryvCtorSelector_.search(compModel) ) + { + REPORT(2)<<"Creating postprocess component "<< Green_Text(compModel)<<" ..."< create( + const dictionary& dict, + fieldsDataBase& fieldsDB, + const baseTimeControl& defaultTimeControl); + +}; + +} // namespace pFlow + +#endif // __postprocessComponent_hpp__ \ No newline at end of file diff --git a/src/PostProcessData/postprocessData.cpp b/src/PostProcessData/postprocessData.cpp new file mode 100644 index 00000000..359fa893 --- /dev/null +++ b/src/PostProcessData/postprocessData.cpp @@ -0,0 +1,99 @@ + +/*------------------------------- 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. + +-----------------------------------------------------------------------------*/ + +#include "List.hpp" +#include "systemControl.hpp" +#include "postprocessData.hpp" +#include "fileDictionary.hpp" +#include "postprocessComponent.hpp" + +pFlow::postprocessData::postprocessData(const systemControl &control) +: + auxFunctions(control), + time_(control.time()), + fieldsDataBase_(control.time(), true), + dict_ + ( + objectFile + ( + "postprocessDataDict", + control.settings().path(), + objectFile::READ_IF_PRESENT, + objectFile::WRITE_NEVER + ) + ), + componentsDicts_(readDictList("components", dict_)) +{ + // if dictionary is not provided, no extra action is required. + if( !dict_.fileExist() ) + { + return; + } + + activeInSimulation_ = dict_.getValOrSet( + "activeInSimulation", + Logical{true}); + + if(dict_.containsDictionay("defaultTimeControl")) + { + defaultTimeControlPtr_ = + makeUnique( + dict_.subDict("defaultTimeControl"), + "execution"); + } + else + { + // default time control from settings + defaultTimeControlPtr_ = makeUnique( + control.time().startTime(), + control.time().endTime(), + control.time().saveInterval(), + "execution"); + } + + for(auto& compDict:componentsDicts_) + { + postprocesses_.push_back( postprocessComponent::create( + compDict, + fieldsDataBase_, + defaultTimeControlPtr_() )); + } + +} + +bool pFlow::postprocessData::execute() +{ + + const auto& ti = time_.TimeInfo(); + + for(auto& component:postprocesses_) + { + if(!component->execute(ti)) + { + fatalErrorInFunction + <<"Error occured in executing postprocess component: " + <name()< postprocesses_; + + /// const ref to Time + const Time& time_; + + /// Database for all the points fields on the host + fieldsDataBase fieldsDataBase_; + + /// file dictionary that is constructed from the file (postProcessDataDict) + fileDictionary dict_; + + /// list of dictionaries for postprocess components + dictionaryList componentsDicts_; + + /// @brief default time control that can be used for all post-process components + uniquePtr defaultTimeControlPtr_= nullptr; + +public: + + TypeInfo("postprocessData"); + + /// @brief Construct from systemControl and a boolean flag + /// this constructor is used when postprocesing is active + /// during simulation. + /// @param control const reference to systemControl + postprocessData(const systemControl& control); + + ~postprocessData()override = default; + + add_vCtor + ( + auxFunctions, + postprocessData, + systemControl + ); + + bool execute() override; + + + + bool wirte()const override + { + return false; + } + +}; + +} // namespace pFlow + +#endif // __postprocessData_hpp__ \ No newline at end of file diff --git a/src/PostProcessData/postprocessDataDict b/src/PostProcessData/postprocessDataDict new file mode 100755 index 00000000..8fed2b42 --- /dev/null +++ b/src/PostProcessData/postprocessDataDict @@ -0,0 +1,108 @@ +/* -------------------------------*- C++ -*--------------------------------- *\ +| phasicFlow File | +| copyright: www.cemf.ir | +\* ------------------------------------------------------------------------- */ +objectName processDataDict; +objectType dictionary;; +fileFormat ASCII; +/*---------------------------------------------------------------------------*/ + +runTimeActive yes; + +defaultTimeControl +{ + timeControl; + startTime; + endTime; + actionInterval 0.05; +} + +components +( + velocityProb + { + method particleProbe; + region idSelecttion; + field velocity; + ids (0 10 100); + timeControl timeStep; + startTime 0; + endTime infinity; + probInterval 1; + } + + comp2 + { + method uniformDistribution; + region spehre; + + sphereInfo + { + radius 0.01; + center (); + } + timeControl default; //default; + operations + ( + numParticle + { + function sum; + field compoenent(velocity,x); + phi square(mass); + divideByVol no; //default + threshold 1; //default; + defaultVal NaN; + //includeMask all; //default; + includeMask lessThan; + lessThanInfo + { + field diameter; + value 0.003; + } + } + ); + } + + comp3 + { + + region line; + lineInfo + { + p1 (); + p2 (); + numPoints 10; + radius 0.01; + } + timeControl settingsDict; //default; + type numberBased; + operations(); + } + + comp4 + { + type GaussianDistribution; + region hexMesh; // unstructuredMehs; + hexMeshInfo + { + min (-0.3 -1.4 -0.01); + max ( 0.3 2 0.48 ); + nx 30; // number of divisions in x direction + ny 160; // number of divisions in y direction + nz 24; // number of divisions in z direction + } + timeControl settingsDict; // read from settingsDict + operations + ( + avVelocity + { + type average; + field realx3 velocity; // default to real 1.0 + divideByVol no; // default + threshold 1; //default; + includeMask all; //default; + + } + ); + } +); diff --git a/src/PostProcessData/postprocessTimeControl.hpp b/src/PostProcessData/postprocessTimeControl.hpp new file mode 100644 index 00000000..f70cfd2a --- /dev/null +++ b/src/PostProcessData/postprocessTimeControl.hpp @@ -0,0 +1,65 @@ +/*------------------------------- 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 __postprocessTimeControl_hpp__ +#define __postprocessTimeControl_hpp__ + +#include "baseTimeControl.hpp" + +namespace pFlow +{ +class postprocessTimeControl +: + public baseTimeControl +{ +public: +postprocessTimeControl( + const dictionary& dict, + const baseTimeControl& defaultTimeControl, + const baseTimeControl& settingTimeControl + ) + : + baseTimeControl(0, 1, 1) + { + auto tControl = dict.getValOrSet("timeControl", "default"); + if(tControl == "default") + { + baseTimeControl::operator=( + defaultTimeControl + ); + } + else if(tControl == "settingsDict") + { + baseTimeControl::operator=( + settingTimeControl + ); + } + else + { + baseTimeControl::operator=( baseTimeControl(dict, "execution") ); + } + } + + // Additional methods and members can be added here +}; + +} // namespace pFlow + +#endif // __postprocessTimeControl_hpp__ \ No newline at end of file diff --git a/src/PostProcessData/region/regionFields.hpp/regionField.hpp b/src/PostProcessData/region/regionFields.hpp/regionField.hpp new file mode 100644 index 00000000..559f854f --- /dev/null +++ b/src/PostProcessData/region/regionFields.hpp/regionField.hpp @@ -0,0 +1,95 @@ +/*------------------------------- 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 __regionField_hpp__ +#define __regionField_hpp__ + +#include "types.hpp" +#include "regionPoints.hpp" +#include "Field.hpp" + +namespace pFlow +{ + +template +class regionField +{ +private: + + /// the field value + Field field_; + + /// the region points + const regionPoints& regionPoints_; +public: + + TypeInfoTemplateNV11("regionField", T); + + regionField( + const word& name, + const regionPoints& rPoints, + const T defaultVal); + + regionField(const regionField&) = default; + + regionField(regionField&&) = default; + + regionField& operator=(const regionField&) = default; + + regionField& operator=(regionField&&) = default; + + ~regionField() = default; + + /// get the field value + T& operator[] (const uint32 i) + { + return field_[i]; + } + + /// get the field value + const T& operator[] (const uint32 i)const + { + return field_[i]; + } + + /// get field name + word name()const + { + return field_.name(); + } + + /// @brief write the field to a file + /// @param os output file stream + /// @return true if successful and false if fails + bool writeFieldToFile(iOstream& os)const; + + /// @brief write the field to vtk format (cell based) + /// @param os output file stream + /// @return true if successful and false if fails + bool writeFieldToVtk(iOstream& os)const; + +}; + + +} // namespace pFlow + +#include "regionFieldTemplate.cpp" + +#endif // __regionField_hpp__ \ No newline at end of file diff --git a/src/PostProcessData/region/regionFields.hpp/regionFieldTemplate.cpp b/src/PostProcessData/region/regionFields.hpp/regionFieldTemplate.cpp new file mode 100644 index 00000000..65112474 --- /dev/null +++ b/src/PostProcessData/region/regionFields.hpp/regionFieldTemplate.cpp @@ -0,0 +1,10 @@ + +template +pFlow::regionField::regionField( + const word& name, + const regionPoints& rPoints, + const T defaultVal) +: + field_(name, "regionFieldValue", rPoints.size(), rPoints.size(), defaultVal), + regionPoints_(rPoints) +{} \ No newline at end of file diff --git a/src/PostProcessData/region/regionPoints/centerPointsRegionPoints.cpp b/src/PostProcessData/region/regionPoints/centerPointsRegionPoints.cpp new file mode 100644 index 00000000..2595ca14 --- /dev/null +++ b/src/PostProcessData/region/regionPoints/centerPointsRegionPoints.cpp @@ -0,0 +1,86 @@ +#include "centerPointsRegionPoints.hpp" +#include "fieldsDataBase.hpp" +#include "Set.hpp" +#include "pStructSelector.hpp" + +bool pFlow::centerPointsRegionPoints::selectIds() +{ + if(!firstTimeUpdate_) return true; + firstTimeUpdate_ = false; + + word selector = probDict_.getVal("selector"); + + if(selector == "id") + { + auto idList = probDict_.getVal("ids"); + Set uniqueIds; + + uniqueIds.insert(idList.begin(), idList.end()); + + for(auto& id:uniqueIds) + { + ids_.push_back(id); + } + } + else + { + auto selectorPtr = pStructSelector::create( + selector, + database().pStruct(), + probDict_); + auto selectedPoints = selectorPtr->selectedPoints(); + ids_.resize(selectedPoints.size()); + ids_.assign(selectedPoints.begin(), selectedPoints.end()); + } + + volume_.resize(ids_.size(),1.0); + diameter_.resize(ids_.size(),1.0); + center_.resize(ids_.size(), realx3(0,0,0)); + selectedPoints_.resize(ids_.size(), -1); + return false; +} + +pFlow::centerPointsRegionPoints::centerPointsRegionPoints( + const dictionary &dict, + fieldsDataBase &fieldsDataBase) + : regionPoints(dict, fieldsDataBase), + idName_(dict.getValOrSet("idName", "id")), + probDict_(dict) +{ + auto idList = dict.getVal("ids"); + Set uniqueIds; + + uniqueIds.insert(idList.begin(), idList.end()); + + for(auto& id:uniqueIds) + { + ids_.push_back(id); + } + + selectedPoints_.resize(ids_.size()); +} + +bool pFlow::centerPointsRegionPoints::update() +{ + if(!selectIds()) return false; + + if(ids_.empty()) return true; + + 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]) + { + selectedPoints_[j] = i; + break; + } + } + } + + return false; +} + diff --git a/src/PostProcessData/region/regionPoints/centerPointsRegionPoints.hpp b/src/PostProcessData/region/regionPoints/centerPointsRegionPoints.hpp new file mode 100644 index 00000000..b80a3442 --- /dev/null +++ b/src/PostProcessData/region/regionPoints/centerPointsRegionPoints.hpp @@ -0,0 +1,116 @@ +/*------------------------------- 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 __centerPointsRegionPoints_hpp__ +#define __centerPointsRegionPoints_hpp__ + +#include "regionPoints.hpp" + +namespace pFlow +{ + +class centerPointsRegionPoints +: + public regionPoints +{ +private: + + bool firstTimeUpdate_ = true; + + /// the ids provided in the dictionary + uint32Vector ids_; + + /// the volume of region + realVector volume_ {"volume"}; + + realVector diameter_{"diameter"}; + /// center point of the region + /// this is not used in the idSelection region + realx3Vector center_ {"center"}; + + /// the point indices that are selected by this region + uint32Vector selectedPoints_{"selectedPoints"}; + + /// the name of the id field + word idName_= "id"; + + /// keeps the dictionary for first update use + dictionary probDict_; + + + bool selectIds(); + +public: + + TypeInfo("centerPoints"); + + centerPointsRegionPoints( + const dictionary& dict, + fieldsDataBase& fieldsDataBase); + + ~centerPointsRegionPoints() override = default; + + uint32 size()const override + { + return selectedPoints_.size(); + } + + bool empty()const override + { + return selectedPoints_.empty(); + } + + span volumes()const override + { + return span(volume_.data(), volume_.size()); + } + + span eqDiameters()const override + { + return span(diameter_.data(), diameter_.size()); + } + + span centers()const override + { + return span(center_.data(), center_.size()); + } + + span indices(uint32 elem)const override + { + return span(selectedPoints_.data(), selectedPoints_.size()); + } + + span indices(uint32 elem) override + { + return span(selectedPoints_.data(), selectedPoints_.size()); + } + + /// @brief update the selected points based on the ids + /// @return true if the operation is successful + bool update() override; + + +}; // class centerPointsRegionPoints + +} // namespace pFlow + + + +#endif // __centerPointsRegionPoints_hpp__ \ No newline at end of file diff --git a/src/PostProcessData/region/regionPoints/lineRegionPoints.cpp b/src/PostProcessData/region/regionPoints/lineRegionPoints.cpp new file mode 100644 index 00000000..955e74bf --- /dev/null +++ b/src/PostProcessData/region/regionPoints/lineRegionPoints.cpp @@ -0,0 +1,83 @@ +#include "lineRegionPoints.hpp" +#include "fieldsDataBase.hpp" + +pFlow::lineRegionPoints::lineRegionPoints +( + const dictionary &dict, + fieldsDataBase &fieldsDataBase +) +: + regionPoints(dict, fieldsDataBase), + line_(dict.subDict("lineInfo")), + centerPoints_("centerPoints"), + volumes_("volumes"), + selectedPoints_("selectedPoints") +{ + const auto& lDict = dict.subDict("lineInfo"); + uint32 nPoints = lDict.getValMax("numPoints",2); + realList raddi; + + if( lDict.containsDataEntry("radii")) + { + raddi = lDict.getVal("radii"); + } + else + { + auto r = lDict.getVal("radius"); + raddi = realList(nPoints, r); + } + + if(raddi.size() != nPoints) + { + fatalErrorInFunction + << "The number elements in of radii list should be equal to the number of points"< pFlow::lineRegionPoints::indices(uint32 elem) const +{ + if(elem>=size()) + { + fatalErrorInFunction + << "The element index is out of range. elem: " << elem + << " size: " << size() << endl; + fatalExit; + } + + return span(selectedPoints_[elem].data(), selectedPoints_[elem].size()); +} + +bool pFlow::lineRegionPoints::update() +{ + const auto points = database().updatePoints(); + for(auto& elem:selectedPoints_) + { + elem.clear(); + } + + for(uint32 i = 0; i < points.size(); ++i) + { + for(uint32 j = 0; j < sphereRegions_.size(); ++j) + { + if( sphereRegions_[j].isInside(points[i])) + { + selectedPoints_[j].push_back(i); + } + } + } + return true; +} diff --git a/src/PostProcessData/region/regionPoints/lineRegionPoints.hpp b/src/PostProcessData/region/regionPoints/lineRegionPoints.hpp new file mode 100644 index 00000000..045eab39 --- /dev/null +++ b/src/PostProcessData/region/regionPoints/lineRegionPoints.hpp @@ -0,0 +1,100 @@ +/*------------------------------- 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 __lineRegionPoints_hpp__ +#define __lineRegionPoints_hpp__ + +#include "regionPoints.hpp" +#include "line.hpp" +#include "sphere.hpp" +#include "Vectors.hpp" + +namespace pFlow +{ + +class lineRegionPoints +: + public regionPoints +{ +private: + + /// line region for selecting points + line line_; + + /// all sphere regions + Vector sphereRegions_; + + /// center poitns of regions/elements + realx3Vector centerPoints_; + + /// volumes of all elements/regions + realVector volumes_; + + realVector diameters_; + + /// the point indices that are selected by this region + Vector selectedPoints_; + +public: + + TypeInfo(line::TYPENAME()); + + lineRegionPoints( + const dictionary& dict, + fieldsDataBase& fieldsDataBase); + + ~lineRegionPoints() override = default; + + uint32 size()const override + { + return sphereRegions_.size(); + } + + bool empty()const override + { + return sphereRegions_.empty(); + } + + span volumes()const override + { + return span(volumes_.data(), volumes_.size()); + } + + span eqDiameters()const override + { + return span(diameters_.data(), diameters_.size()); + } + + span centers()const override + { + return span(centerPoints_.data(), centerPoints_.size()); + } + + span indices(uint32 elem)const override; + + + bool update() override; + +}; + +} + + +#endif // __lineRegionPoints_hpp__ \ No newline at end of file diff --git a/src/PostProcessData/region/regionPoints/regionPoints.cpp b/src/PostProcessData/region/regionPoints/regionPoints.cpp new file mode 100644 index 00000000..20599503 --- /dev/null +++ b/src/PostProcessData/region/regionPoints/regionPoints.cpp @@ -0,0 +1,28 @@ +#include "regionPoints.hpp" +#include "fieldsDataBase.hpp" +#include "Time.hpp" + +pFlow::regionPoints::regionPoints +( + const dictionary &dict, + fieldsDataBase &fieldsDataBase +) +: + fieldsDataBase_(fieldsDataBase) +{} + +const pFlow::Time& pFlow::regionPoints::time() const +{ + return fieldsDataBase_.time(); +} + +const pFlow::fieldsDataBase & pFlow::regionPoints::database() const +{ + return fieldsDataBase_; +} + +pFlow::fieldsDataBase& pFlow::regionPoints::database() +{ + return fieldsDataBase_; +} + diff --git a/src/PostProcessData/region/regionPoints/regionPoints.hpp b/src/PostProcessData/region/regionPoints/regionPoints.hpp new file mode 100644 index 00000000..353f73cb --- /dev/null +++ b/src/PostProcessData/region/regionPoints/regionPoints.hpp @@ -0,0 +1,103 @@ +/*------------------------------- 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 __regionPoints_hpp__ +#define __regionPoints_hpp__ + +#include "dictionary.hpp" +#include "pointStructure.hpp" + + +namespace pFlow +{ + +class fieldsDataBase; +class Time; + +class regionPoints +{ + using PointsTypeHost = typename pointStructure::PointsTypeHost; + + fieldsDataBase& fieldsDataBase_; + +public: + + TypeInfo("regionPoints"); + + + regionPoints( + const dictionary& dict, + fieldsDataBase& fieldsDataBase); + + virtual ~regionPoints() = default; + + const Time& time()const; + + const fieldsDataBase& database()const; + + fieldsDataBase& database(); + + /// @brief size of elements + virtual + uint32 size()const = 0; + + /// @brief check if the region is empty + virtual + bool empty()const = 0; + + /*/// @brief return the type of the region + virtual const word& type()const = 0;*/ + + + /// @brief volume of elements + /// @return sapn for accessing the volume of elements + virtual + span volumes()const =0; + + virtual + span eqDiameters()const = 0; + + /// center points of elements + virtual + span centers()const = 0; + + /// indices of particles inside the element @var elem + virtual + span indices(uint32 elem)const = 0; + + virtual + span indices(uint32 elem) = 0; + + virtual + bool update() = 0; + + /*virtual + bool write()const=0;*/ + + /*static + uniquePtr create( + const dictionary& dict, + fieldsDataBase& fieldsDataBase);*/ + +}; + +} + +#endif // __regionPoints_hpp__ \ No newline at end of file diff --git a/src/PostProcessData/region/regionPoints/sphereRegionPoints.cpp b/src/PostProcessData/region/regionPoints/sphereRegionPoints.cpp new file mode 100644 index 00000000..566fd688 --- /dev/null +++ b/src/PostProcessData/region/regionPoints/sphereRegionPoints.cpp @@ -0,0 +1,31 @@ +#include "sphereRegionPoints.hpp" +#include "fieldsDataBase.hpp" + +pFlow::sphereRegionPoints::sphereRegionPoints +( + const dictionary &dict, + fieldsDataBase &fieldsDataBase +) +: + regionPoints(dict, fieldsDataBase), + sphereRegion_(dict.subDict("sphereInfo")), + volume_(sphereRegion_.volume()), + diameter_(2*sphereRegion_.radius()), + selectedPoints_("selectedPoints") +{ +} + +bool pFlow::sphereRegionPoints::update() +{ + const auto points = database().updatePoints(); + selectedPoints_.clear(); + for(uint32 i = 0; i < points.size(); ++i) + { + if( sphereRegion_.isInside(points[i])) + { + selectedPoints_.push_back(i); + } + } + + return false; +} diff --git a/src/PostProcessData/region/regionPoints/sphereRegionPoints.hpp b/src/PostProcessData/region/regionPoints/sphereRegionPoints.hpp new file mode 100644 index 00000000..a8ec481f --- /dev/null +++ b/src/PostProcessData/region/regionPoints/sphereRegionPoints.hpp @@ -0,0 +1,98 @@ +/*------------------------------- 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 __sphereRegionPoints_hpp__ +#define __sphereRegionPoints_hpp__ + +#include "regionPoints.hpp" +#include "sphere.hpp" +#include "Vectors.hpp" + +namespace pFlow +{ +class sphereRegionPoints +: + public regionPoints +{ +private: + + /// spehre region for selecting points + sphere sphereRegion_; + + /// the volume of region + real volume_; + + real diameter_; + + /// the point indices that are selected by this region + uint32Vector selectedPoints_; + +public: + + TypeInfo(sphere::TYPENAME()); + + sphereRegionPoints( + const dictionary& dict, + fieldsDataBase& fieldsDataBase); + + ~sphereRegionPoints() override = default; + + uint32 size()const override + { + return 1; + } + + bool empty()const override + { + return false; + } + + span volumes()const override + { + return span(&volume_, 1); + } + + span eqDiameters()const override + { + return span(&diameter_, 1); + } + + span centers()const override + { + return span(&sphereRegion_.center(), 1); + } + + span indices(uint32 elem)const override + { + return span(selectedPoints_.data(), selectedPoints_.size()); + } + + span indices(uint32 elem) override + { + return span(selectedPoints_.data(), selectedPoints_.size()); + } + + bool update()override; + +}; + +} + +#endif // __sphereRegionPoints_hpp__ \ No newline at end of file From 162cfd3b6ab7093940e729e5a50a400d9c7097bb Mon Sep 17 00:00:00 2001 From: Hamidreza Date: Thu, 10 Apr 2025 21:16:31 +0330 Subject: [PATCH 2/2] The main structure is tested. functons like execute and write are added and tested. other components are left --- src/PostProcessData/CMakeLists.txt | 35 ----- .../particleProbePostprocessComponent.cpp | 26 ---- src/PostprocessData/CMakeLists.txt | 30 ++++ .../fieldsDataBase/fieldFunctions.hpp | 0 .../fieldsDataBase/fieldsDataBase.cpp | 42 ++--- .../fieldsDataBase/fieldsDataBase.hpp | 0 .../fieldsDataBaseTemplates.cpp | 0 .../PostprocessOperationSum.cpp | 28 ++-- .../PostprocessOperationSum.hpp | 14 +- .../PostprocessOperation}/fieldFunctions.hpp | 7 +- .../operation/includeMask/IncludeMask.hpp | 0 .../operation/includeMask/IncludeMasks.cpp | 0 .../operation/includeMask/includeMask.cpp | 0 .../operation/includeMask/includeMask.hpp | 0 .../operation/includeMask/maskOperations.hpp | 0 .../postprocessOperation.cpp | 104 ++++++++++++- .../postprocessOperation.hpp | 28 +++- .../PostprocessComponent.cpp | 57 ++++++- .../PostprocessComponent.hpp | 4 +- .../PostprocessComponentArithmetic.hpp | 73 +++++++++ .../PostprocessComponentGaussian.hpp | 0 .../PostprocessComponentUniform.hpp | 73 +++++++++ .../PostprocessComponents.cpp | 9 +- .../particleProbePostprocessComponent.cpp | 147 ++++++++++++++++++ .../particleProbePostprocessComponent.hpp | 15 +- .../postprocessComponent.cpp | 0 .../postprocessComponent.hpp | 3 + .../postprocessData}/postprocessData.cpp | 25 ++- .../postprocessData}/postprocessData.hpp | 6 +- .../postprocessData/postprocessGlobals.hpp | 35 +++++ .../postprocessTimeControl.hpp | 0 .../processMethod}/GaussianDistribution.hpp | 0 .../processMethod/arithmetic.hpp | 91 +++++++++++ .../processMethod}/uniformDistribution.hpp | 13 +- .../region/regionFields}/regionField.hpp | 15 ++ .../regionFields}/regionFieldTemplate.cpp | 0 .../centerPointsRegionPoints.cpp | 39 +++-- .../centerPointsRegionPoints.hpp | 6 + .../lineRegionPoints}/lineRegionPoints.cpp | 17 ++ .../lineRegionPoints}/lineRegionPoints.hpp | 6 + .../regionPoints/regionPoints.cpp | 0 .../regionPoints/regionPoints.hpp | 8 +- .../sphereRegionPoints.cpp | 12 +- .../sphereRegionPoints.hpp | 7 + .../sampleDictionary}/postprocessDataDict | 0 45 files changed, 821 insertions(+), 154 deletions(-) delete mode 100644 src/PostProcessData/CMakeLists.txt delete mode 100644 src/PostProcessData/postprocessComponent/particleProbePostprocessComponent.cpp create mode 100644 src/PostprocessData/CMakeLists.txt rename src/{PostProcessData => PostprocessData}/fieldsDataBase/fieldFunctions.hpp (100%) rename src/{PostProcessData => PostprocessData}/fieldsDataBase/fieldsDataBase.cpp (95%) rename src/{PostProcessData => PostprocessData}/fieldsDataBase/fieldsDataBase.hpp (100%) rename src/{PostProcessData => PostprocessData}/fieldsDataBase/fieldsDataBaseTemplates.cpp (100%) rename src/{PostProcessData/operation => PostprocessData/operation/PostprocessOperation}/PostprocessOperationSum.cpp (79%) rename src/{PostProcessData/operation => PostprocessData/operation/PostprocessOperation}/PostprocessOperationSum.hpp (90%) rename src/{PostProcessData/operation => PostprocessData/operation/PostprocessOperation}/fieldFunctions.hpp (96%) rename src/{PostProcessData => PostprocessData}/operation/includeMask/IncludeMask.hpp (100%) rename src/{PostProcessData => PostprocessData}/operation/includeMask/IncludeMasks.cpp (100%) rename src/{PostProcessData => PostprocessData}/operation/includeMask/includeMask.cpp (100%) rename src/{PostProcessData => PostprocessData}/operation/includeMask/includeMask.hpp (100%) rename src/{PostProcessData => PostprocessData}/operation/includeMask/maskOperations.hpp (100%) rename src/{PostProcessData/operation => PostprocessData/operation/postprocessOperation}/postprocessOperation.cpp (53%) rename src/{PostProcessData/operation => PostprocessData/operation/postprocessOperation}/postprocessOperation.hpp (87%) rename src/{PostProcessData/postprocessComponent => PostprocessData/postprocessComponent/PostprocessComponent}/PostprocessComponent.cpp (68%) rename src/{PostProcessData/postprocessComponent => PostprocessData/postprocessComponent/PostprocessComponent}/PostprocessComponent.hpp (97%) create mode 100644 src/PostprocessData/postprocessComponent/PostprocessComponent/PostprocessComponentArithmetic.hpp rename src/{PostProcessData/postprocessComponent => PostprocessData/postprocessComponent/PostprocessComponent}/PostprocessComponentGaussian.hpp (100%) create mode 100644 src/PostprocessData/postprocessComponent/PostprocessComponent/PostprocessComponentUniform.hpp rename src/{PostProcessData/postprocessComponent => PostprocessData/postprocessComponent/PostprocessComponent}/PostprocessComponents.cpp (82%) create mode 100644 src/PostprocessData/postprocessComponent/particleProbePostprocessComponent/particleProbePostprocessComponent.cpp rename src/{PostProcessData/postprocessComponent => PostprocessData/postprocessComponent/particleProbePostprocessComponent}/particleProbePostprocessComponent.hpp (86%) rename src/{PostProcessData => PostprocessData/postprocessComponent}/postprocessComponent/postprocessComponent.cpp (100%) rename src/{PostProcessData => PostprocessData/postprocessComponent}/postprocessComponent/postprocessComponent.hpp (96%) rename src/{PostProcessData => PostprocessData/postprocessData}/postprocessData.cpp (83%) rename src/{PostProcessData => PostprocessData/postprocessData}/postprocessData.hpp (96%) create mode 100644 src/PostprocessData/postprocessData/postprocessGlobals.hpp rename src/{PostProcessData => PostprocessData/postprocessData}/postprocessTimeControl.hpp (100%) rename src/{PostProcessData/method => PostprocessData/processMethod}/GaussianDistribution.hpp (100%) create mode 100644 src/PostprocessData/processMethod/arithmetic.hpp rename src/{PostProcessData/method => PostprocessData/processMethod}/uniformDistribution.hpp (89%) rename src/{PostProcessData/region/regionFields.hpp => PostprocessData/region/regionFields}/regionField.hpp (91%) rename src/{PostProcessData/region/regionFields.hpp => PostprocessData/region/regionFields}/regionFieldTemplate.cpp (100%) rename src/{PostProcessData/region/regionPoints => PostprocessData/region/regionPoints/centerPointsRegionPoints}/centerPointsRegionPoints.cpp (79%) rename src/{PostProcessData/region/regionPoints => PostprocessData/region/regionPoints/centerPointsRegionPoints}/centerPointsRegionPoints.hpp (94%) rename src/{PostProcessData/region/regionPoints => PostprocessData/region/regionPoints/lineRegionPoints}/lineRegionPoints.cpp (82%) rename src/{PostProcessData/region/regionPoints => PostprocessData/region/regionPoints/lineRegionPoints}/lineRegionPoints.hpp (94%) rename src/{PostProcessData/region => PostprocessData/region/regionPoints}/regionPoints/regionPoints.cpp (100%) rename src/{PostProcessData/region => PostprocessData/region/regionPoints}/regionPoints/regionPoints.hpp (94%) rename src/{PostProcessData/region/regionPoints => PostprocessData/region/regionPoints/sphereRegionPoints}/sphereRegionPoints.cpp (71%) rename src/{PostProcessData/region/regionPoints => PostprocessData/region/regionPoints/sphereRegionPoints}/sphereRegionPoints.hpp (93%) rename src/{PostProcessData => PostprocessData/sampleDictionary}/postprocessDataDict (100%) diff --git a/src/PostProcessData/CMakeLists.txt b/src/PostProcessData/CMakeLists.txt deleted file mode 100644 index e5a624a8..00000000 --- a/src/PostProcessData/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ - -set(SourceFiles -fieldsDataBase/fieldsDataBase.cpp - -postprocessComponent/postprocessComponent.cpp -postprocessComponent/PostprocessComponents.cpp - -operation/postprocessOperation.cpp -operation/PostprocessOperationSum.cpp - - -postprocessData.cpp - -postprocessComponent/postprocessComponent.cpp -postprocessComponent/PostprocessComponents.cpp -postprocessComponent/particleProbePostprocessComponent.cpp - -operation/includeMask/includeMask.cpp -operation/includeMask/IncludeMasks.cpp -operation/postprocessOperation.cpp -operation/PostprocessOperationSum.cpp - -region/regionPoints/sphereRegionPoints.cpp -region/regionPoints/regionPoints.cpp -region/regionPoints/lineRegionPoints.cpp -region/regionPoints/centerPointsRegionPoints.cpp - -) - -set(link_libs Kokkos::kokkos phasicFlow Particles) - -pFlow_add_library_install(PostProcessData SourceFiles link_libs) - -add_subdirectory(testPostprocess) - diff --git a/src/PostProcessData/postprocessComponent/particleProbePostprocessComponent.cpp b/src/PostProcessData/postprocessComponent/particleProbePostprocessComponent.cpp deleted file mode 100644 index 33105c41..00000000 --- a/src/PostProcessData/postprocessComponent/particleProbePostprocessComponent.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "particleProbePostprocessComponent.hpp" - -pFlow::particleProbePostprocessComponent::particleProbePostprocessComponent -( - const dictionary &dict, - fieldsDataBase &fieldsDB, - const baseTimeControl &defaultTimeControl -) -: - postprocessComponent(dict, fieldsDB, defaultTimeControl), - regionPointsPtr_ - ( - makeUnique(dict, fieldsDB) - ), - name_(dict.name()) -{} - -bool pFlow::particleProbePostprocessComponent::execute -( - const timeInfo &ti, - bool forceExecute -) -{ - - return false; -} diff --git a/src/PostprocessData/CMakeLists.txt b/src/PostprocessData/CMakeLists.txt new file mode 100644 index 00000000..2c15a7c4 --- /dev/null +++ b/src/PostprocessData/CMakeLists.txt @@ -0,0 +1,30 @@ +set(SourceFiles + # Main postprocess data + postprocessData/postprocessData.cpp + + # Fields database + fieldsDataBase/fieldsDataBase.cpp + + # Regions + region/regionPoints/regionPoints/regionPoints.cpp + region/regionPoints/sphereRegionPoints/sphereRegionPoints.cpp + region/regionPoints/lineRegionPoints/lineRegionPoints.cpp + region/regionPoints/centerPointsRegionPoints/centerPointsRegionPoints.cpp + + # Postprocess components + postprocessComponent/postprocessComponent/postprocessComponent.cpp + postprocessComponent/particleProbePostprocessComponent/particleProbePostprocessComponent.cpp + postprocessComponent/PostprocessComponent/PostprocessComponents.cpp + + # Operations + operation/postprocessOperation/postprocessOperation.cpp + operation/PostprocessOperation/PostprocessOperationSum.cpp + operation/includeMask/includeMask.cpp + operation/includeMask/IncludeMasks.cpp + + +) + +set(link_libs Kokkos::kokkos phasicFlow Particles) + +pFlow_add_library_install(PostprocessData SourceFiles link_libs) \ No newline at end of file diff --git a/src/PostProcessData/fieldsDataBase/fieldFunctions.hpp b/src/PostprocessData/fieldsDataBase/fieldFunctions.hpp similarity index 100% rename from src/PostProcessData/fieldsDataBase/fieldFunctions.hpp rename to src/PostprocessData/fieldsDataBase/fieldFunctions.hpp diff --git a/src/PostProcessData/fieldsDataBase/fieldsDataBase.cpp b/src/PostprocessData/fieldsDataBase/fieldsDataBase.cpp similarity index 95% rename from src/PostProcessData/fieldsDataBase/fieldsDataBase.cpp rename to src/PostprocessData/fieldsDataBase/fieldsDataBase.cpp index 46efefa5..cbd47c98 100644 --- a/src/PostProcessData/fieldsDataBase/fieldsDataBase.cpp +++ b/src/PostprocessData/fieldsDataBase/fieldsDataBase.cpp @@ -465,19 +465,22 @@ pFlow::span pFlow::fieldsDataBase::updateFieldReal } // if the original type is uint32, and no funciton, cast to real - if( originalType == getTypeName() && func == Functions::None ) + if( originalType == getTypeName()) { - auto sp = updateField(fieldName, forceUpdate); - auto spReal = createOrGetRealField(fieldName+".real"); - funcCast(sp, spReal); - return spReal; - } - else - { - fatalErrorInFunction<<"No function can be applied to field of type uint32. "<< - " The field is: "<< compoundName<(nullptr, 0); - fatalExit; + if(func == Functions::None) + { + auto sp = updateField(fieldName, forceUpdate); + auto spReal = createOrGetRealField(fieldName+".real"); + funcCast(sp, spReal); + return spReal; + } + else + { + fatalErrorInFunction<<"No function can be applied to field of type uint32. "<< + " The field is: "<< compoundName<(nullptr, 0); + fatalExit; + } } if( originalType == getTypeName() ) @@ -606,27 +609,30 @@ pFlow::allPointFieldTypes pFlow::fieldsDataBase::updateFieldAll bool forceUpdate ) { - word originalType, typeAfterFunction; + + word originalType, typeAfterFunction, fieldName; + Functions func; - if( !getPointFieldType(compoundName, originalType, typeAfterFunction)) + if( !getPointFieldType(compoundName, fieldName, originalType, typeAfterFunction, func)) { fatalErrorInFunction<< "Error in getting the type name of field: "<< compoundName<<", with type name: "<< originalType <(nullptr,0); + return span(nullptr, 0); } + if( typeAfterFunction== getTypeName() ) { - return updateField(compoundName, forceUpdate); + return updateFieldRealx3(compoundName, forceUpdate); } else if( typeAfterFunction == getTypeName() ) { - return updateField(compoundName, forceUpdate); + return updateFieldRealx4(compoundName, forceUpdate); } else if( typeAfterFunction == getTypeName() ) { - return updateField(compoundName, forceUpdate); + return updateFieldReal(compoundName, forceUpdate); } else { diff --git a/src/PostProcessData/fieldsDataBase/fieldsDataBase.hpp b/src/PostprocessData/fieldsDataBase/fieldsDataBase.hpp similarity index 100% rename from src/PostProcessData/fieldsDataBase/fieldsDataBase.hpp rename to src/PostprocessData/fieldsDataBase/fieldsDataBase.hpp diff --git a/src/PostProcessData/fieldsDataBase/fieldsDataBaseTemplates.cpp b/src/PostprocessData/fieldsDataBase/fieldsDataBaseTemplates.cpp similarity index 100% rename from src/PostProcessData/fieldsDataBase/fieldsDataBaseTemplates.cpp rename to src/PostprocessData/fieldsDataBase/fieldsDataBaseTemplates.cpp diff --git a/src/PostProcessData/operation/PostprocessOperationSum.cpp b/src/PostprocessData/operation/PostprocessOperation/PostprocessOperationSum.cpp similarity index 79% rename from src/PostProcessData/operation/PostprocessOperationSum.cpp rename to src/PostprocessData/operation/PostprocessOperation/PostprocessOperationSum.cpp index 259ff951..bae7af3f 100644 --- a/src/PostProcessData/operation/PostprocessOperationSum.cpp +++ b/src/PostprocessData/operation/PostprocessOperation/PostprocessOperationSum.cpp @@ -51,19 +51,21 @@ bool pFlow::PostprocessOperationSum::execute const auto& regP = regPoints(); bool dbVol = divideByVolume(); - - std::visit([&](auto&& field)->processedRegFieldType - { - return executeSumOperation( - procName, - field, - regP, - dbVol, - weights, - phi, - mask); - }, - allField); + processedRegField_ = makeUnique + ( + std::visit([&](auto&& field)->processedRegFieldType + { + return executeSumOperation( + procName, + field, + regP, + dbVol, + weights, + phi, + mask); + }, + allField) + ); return true; } diff --git a/src/PostProcessData/operation/PostprocessOperationSum.hpp b/src/PostprocessData/operation/PostprocessOperation/PostprocessOperationSum.hpp similarity index 90% rename from src/PostProcessData/operation/PostprocessOperationSum.hpp rename to src/PostprocessData/operation/PostprocessOperation/PostprocessOperationSum.hpp index 5e9cb314..94134602 100644 --- a/src/PostProcessData/operation/PostprocessOperationSum.hpp +++ b/src/PostprocessData/operation/PostprocessOperation/PostprocessOperationSum.hpp @@ -37,14 +37,7 @@ class PostprocessOperationSum public postprocessOperation { private: - - using processedRegFieldType = std::variant - < - regionField, - regionField, - regionField - >; - + /// Pointer to the include mask used for masking operations. uniquePtr processedRegField_ = nullptr; @@ -66,6 +59,11 @@ public: dictionary ); + const processedRegFieldType& processedField()const override + { + return processedRegField_(); + } + bool execute(const std::vector>& weights) override; }; diff --git a/src/PostProcessData/operation/fieldFunctions.hpp b/src/PostprocessData/operation/PostprocessOperation/fieldFunctions.hpp similarity index 96% rename from src/PostProcessData/operation/fieldFunctions.hpp rename to src/PostprocessData/operation/PostprocessOperation/fieldFunctions.hpp index 8e9d6427..e1494459 100644 --- a/src/PostProcessData/operation/fieldFunctions.hpp +++ b/src/PostprocessData/operation/PostprocessOperation/fieldFunctions.hpp @@ -31,6 +31,7 @@ Licence: namespace pFlow { + template regionField executeSumOperation ( @@ -54,7 +55,7 @@ regionField executeSumOperation uint n = 0; for(auto index:partIndices) { - if( mask( index )) + if( index!= -1 && mask( index )) { sum += w[n] * field[index]* phi[index]; } @@ -96,7 +97,7 @@ regionField executeAverageOperation uint n = 0; for(auto index:partIndices) { - if( mask( index )) + if( index!= -1 && mask( index )) { sumNum += w[n] * field[index]* phi[index]; } @@ -114,4 +115,4 @@ regionField executeAverageOperation } // namespace pFlow -#endif //__fieldFunctions_hpp__ \ No newline at end of file +#endif //__fieldFunctions_hpp__ diff --git a/src/PostProcessData/operation/includeMask/IncludeMask.hpp b/src/PostprocessData/operation/includeMask/IncludeMask.hpp similarity index 100% rename from src/PostProcessData/operation/includeMask/IncludeMask.hpp rename to src/PostprocessData/operation/includeMask/IncludeMask.hpp diff --git a/src/PostProcessData/operation/includeMask/IncludeMasks.cpp b/src/PostprocessData/operation/includeMask/IncludeMasks.cpp similarity index 100% rename from src/PostProcessData/operation/includeMask/IncludeMasks.cpp rename to src/PostprocessData/operation/includeMask/IncludeMasks.cpp diff --git a/src/PostProcessData/operation/includeMask/includeMask.cpp b/src/PostprocessData/operation/includeMask/includeMask.cpp similarity index 100% rename from src/PostProcessData/operation/includeMask/includeMask.cpp rename to src/PostprocessData/operation/includeMask/includeMask.cpp diff --git a/src/PostProcessData/operation/includeMask/includeMask.hpp b/src/PostprocessData/operation/includeMask/includeMask.hpp similarity index 100% rename from src/PostProcessData/operation/includeMask/includeMask.hpp rename to src/PostprocessData/operation/includeMask/includeMask.hpp diff --git a/src/PostProcessData/operation/includeMask/maskOperations.hpp b/src/PostprocessData/operation/includeMask/maskOperations.hpp similarity index 100% rename from src/PostProcessData/operation/includeMask/maskOperations.hpp rename to src/PostprocessData/operation/includeMask/maskOperations.hpp diff --git a/src/PostProcessData/operation/postprocessOperation.cpp b/src/PostprocessData/operation/postprocessOperation/postprocessOperation.cpp similarity index 53% rename from src/PostProcessData/operation/postprocessOperation.cpp rename to src/PostprocessData/operation/postprocessOperation/postprocessOperation.cpp index c37961c1..8c42daa3 100644 --- a/src/PostProcessData/operation/postprocessOperation.cpp +++ b/src/PostprocessData/operation/postprocessOperation/postprocessOperation.cpp @@ -18,10 +18,72 @@ Licence: -----------------------------------------------------------------------------*/ +#include "Time.hpp" #include "postprocessOperation.hpp" #include "regionPoints.hpp" #include "fieldsDataBase.hpp" +namespace pFlow +{ + +template +inline +bool writeField +( + iOstream& os, + timeValue t, + const regionField field, + uint32 threshold, + const T& defValue=T{} +) +{ + const auto& regPoints = field.regPoints(); + const uint32 n = field.size(); + os<= threshold) + { + if constexpr(std::is_same_v) + { + os<) + { + os << field[i].x() << ' ' << field[i].y() << ' ' << field[i].z() << ' ' << field[i].w() << tab; + } + else + { + os<) + { + os<) + { + os << defValue.x() << ' ' << defValue.y() << ' ' << defValue.z() << ' ' << defValue.w() << tab; + } + else + { + os< - pFlow::postprocessOperation::create +const pFlow::Time& pFlow::postprocessOperation::time() const +{ + return database_.time(); +} + +bool pFlow::postprocessOperation::write(const fileSystem &parDir) const +{ + auto ti = time().TimeInfo(); + + if(!osPtr_) + { + fileSystem path = parDir+( + processedFieldName() + ".Start_" + ti.prevTimeName()); + osPtr_ = makeUnique(path); + + regPoints().write(osPtr_()); + } + + const auto& field = processedField(); + + std::visit ( - const dictionary &opDict, - const regionPoints& regPoints, - fieldsDataBase &fieldsDB - ) + [&](auto&& arg)->bool + { + return writeField(osPtr_(), ti.t(), arg, threshold_); + }, + field + ); + + return true; +} + +pFlow::uniquePtr +pFlow::postprocessOperation::create( + const dictionary &opDict, + const regionPoints ®Points, + fieldsDataBase &fieldsDB) { word func = opDict.getVal("function"); word method = angleBracketsNames("PostprocessOperation", func); diff --git a/src/PostProcessData/operation/postprocessOperation.hpp b/src/PostprocessData/operation/postprocessOperation/postprocessOperation.hpp similarity index 87% rename from src/PostProcessData/operation/postprocessOperation.hpp rename to src/PostprocessData/operation/postprocessOperation/postprocessOperation.hpp index 01cd853b..fa847bdd 100644 --- a/src/PostProcessData/operation/postprocessOperation.hpp +++ b/src/PostprocessData/operation/postprocessOperation/postprocessOperation.hpp @@ -20,18 +20,28 @@ Licence: #ifndef __postprocessOperation_hpp__ #define __postprocessOperation_hpp__ +#include + #include "virtualConstructor.hpp" #include "Logical.hpp" #include "dictionary.hpp" #include "span.hpp" +#include "oFstream.hpp" +#include "regionField.hpp" #include "includeMask.hpp" - namespace pFlow { +using processedRegFieldType = std::variant + < + regionField, + regionField, + regionField + >; + class fieldsDataBase; -class regionPoints; +class Time; /*! * @brief Base class for post-processing operations. @@ -69,10 +79,12 @@ private: word fieldType_; /// Name of the phi field to be processed. - word phiFieldName_; + word phiFieldName_; /// Pointer to the include mask used for masking operations. uniquePtr includeMask_ = nullptr; + + mutable uniquePtr osPtr_ = nullptr; public: @@ -111,6 +123,8 @@ public: return database_; } + const Time& time()const; + word processedFieldName()const { return operationDict_.name(); @@ -150,10 +164,18 @@ public: return includeMask_().getMask(); } + virtual + const processedRegFieldType& processedField()const=0; virtual bool execute(const std::vector>& weights) = 0; + virtual + bool write(const fileSystem &parDir)const; + + virtual + bool write(iOstream& os)const {return true;} + static uniquePtr create( const dictionary& opDict, diff --git a/src/PostProcessData/postprocessComponent/PostprocessComponent.cpp b/src/PostprocessData/postprocessComponent/PostprocessComponent/PostprocessComponent.cpp similarity index 68% rename from src/PostProcessData/postprocessComponent/PostprocessComponent.cpp rename to src/PostprocessData/postprocessComponent/PostprocessComponent/PostprocessComponent.cpp index 5720bdaa..c815d255 100644 --- a/src/PostProcessData/postprocessComponent/PostprocessComponent.cpp +++ b/src/PostprocessData/postprocessComponent/PostprocessComponent/PostprocessComponent.cpp @@ -61,22 +61,31 @@ bool pFlow::PostprocessComponent::execute bool forceUpdate ) { - - if( !timeControl().eventTime(ti)) + if( !forceUpdate && !timeControl().eventTime(ti)) { executed_ = false; return true; } // update processing methods + auto& regPoints = this->regPoints(); - auto centers = this->regPoints().centers(); - const uint32 n = centers.size(); - auto points = this->database().updatePoints(); + if(!regPoints.update()) + { + fatalErrorInFunction + << "regionPoints update failed for " + << operationDicts_.globalName() + << endl; + return false; + } + + auto centers = regPoints.centers(); + const uint32 n = centers.size(); + auto points = this->database().updatePoints(); for(uint32 i=0; iregPoints().indices(i); + auto indices = regPoints.indices(i); regionsProcessMethod_[i].updateWeights( centers[i], indices, @@ -93,7 +102,7 @@ bool pFlow::PostprocessComponent::execute for(auto& op:operatios_) { - if( op->execute(weights) ) + if( !op->execute(weights) ) { fatalErrorInFunction <<"error occured in executing operatoin defined in dict " @@ -105,5 +114,39 @@ bool pFlow::PostprocessComponent::execute executed_ = true; + return true; +} + +template +inline +bool pFlow::PostprocessComponent::write +( + const fileSystem &parDir +) const +{ + if(!executed_) return true; + + if(regionPointsPtr_().writeToSameTimeFile()) + { + for(auto& operation:operatios_) + { + if(!operation->write(parDir)) + { + fatalErrorInFunction + <<"Error occurred in writing operation defined in dict " + << operation->operationDict() + < +class PostprocessComponentArithmetic +: + public PostprocessComponent +{ +public: + + /// type info + TypeInfoTemplate12("PostprocessComponent", RegionType, arithmetic); + + PostprocessComponentArithmetic + ( + const dictionary& dict, + fieldsDataBase& fieldsDB, + const baseTimeControl& defaultTimeControl + ) + : + PostprocessComponent(dict, fieldsDB, defaultTimeControl) + { + /// initializes the arithmetic distribution for all elements of region + //const uint32 n = this->regPoints().size(); + auto d = this->regPoints().eqDiameters(); + auto c = this->regPoints().centers(); + auto& regs = this->regionProecessMethod(); + const uint32 n = d.size(); + for(uint32 i=0; i +class PostprocessComponentUniform +: + public PostprocessComponent +{ +public: + + /// type info + TypeInfoTemplate12("PostprocessComponent", RegionType, uniformDistribution); + + PostprocessComponentUniform + ( + const dictionary& dict, + fieldsDataBase& fieldsDB, + const baseTimeControl& defaultTimeControl + ) + : + PostprocessComponent(dict, fieldsDB, defaultTimeControl) + { + /// initializes the Uniform distribution for all elements of region + //const uint32 n = this->regPoints().size(); + auto d = this->regPoints().eqDiameters(); + auto c = this->regPoints().centers(); + auto& regs = this->regionProecessMethod(); + const uint32 n = d.size(); + for(uint32 i=0; i; - +template class pFlow::PostprocessComponentUniform; +template class pFlow::PostprocessComponentArithmetic; diff --git a/src/PostprocessData/postprocessComponent/particleProbePostprocessComponent/particleProbePostprocessComponent.cpp b/src/PostprocessData/postprocessComponent/particleProbePostprocessComponent/particleProbePostprocessComponent.cpp new file mode 100644 index 00000000..3aad17a4 --- /dev/null +++ b/src/PostprocessData/postprocessComponent/particleProbePostprocessComponent/particleProbePostprocessComponent.cpp @@ -0,0 +1,147 @@ +#include "particleProbePostprocessComponent.hpp" +#include "Time.hpp" + +namespace pFlow +{ + +template +inline +regionField porbeExecute +( + const word& regFieldName, + const span& field, + const regionPoints& regPoints +) +{ + regionField processedField(regFieldName, regPoints, T{}); + auto partIndices = regPoints.indices(0); + + uint n = 0; + for(auto index:partIndices) + { + if(index != -1) + { + processedField[n] = field[index]; + } + n++; + } + return processedField; +} + +template +inline bool writeField +( + iOstream& os, + timeValue t, + const regionField& field, + const regionPoints& regPoints, + const T& invalidVal = T{} +) +{ + auto indices = regPoints.indices(0); + const uint32 s= field.size(); + os<< t <) + { + os< ) + { + os<(dict, fieldsDB) + ), + fieldName_ + ( + dict.getVal("field") + ), + name_(dict.name()) +{} + +bool pFlow::particleProbePostprocessComponent::execute +( + const timeInfo &ti, + bool forceExecute +) +{ + if( !forceExecute && !timeControl().eventTime(ti)) + { + executed_ = false; + return true; + } + + if(!regionPointsPtr_().update()) + { + fatalErrorInFunction + << "regionPoints update for "<< name_ << " failed. \n"; + return false; + } + + auto field = database().updateFieldAll(fieldName_); + auto pFieldName = name_; + + processedField_ = makeUnique + ( + std::visit( + [&](auto&& f) -> processedRegFieldType + { + return porbeExecute( + pFieldName, + f, + regionPointsPtr_()); + }, + field) + ); + + executed_ = true; + return true; +} + + +bool pFlow::particleProbePostprocessComponent::write(const fileSystem& parDir)const +{ + if(! executed_ ) return true; + + const auto ti = database().time().TimeInfo(); + + if( !osPtr_) + { + // file is not open yet + fileSystem path = parDir + (name_+".Start_"+ti.prevTimeName()); + osPtr_ = makeUnique(path); + regionPointsPtr_().write(osPtr_()); + } + + std::visit + ([&](auto&& arg)->bool + { + return writeField(osPtr_(), ti.t(), arg, regionPointsPtr_()); + }, + processedField_() + ); + + return true; +} \ No newline at end of file diff --git a/src/PostProcessData/postprocessComponent/particleProbePostprocessComponent.hpp b/src/PostprocessData/postprocessComponent/particleProbePostprocessComponent/particleProbePostprocessComponent.hpp similarity index 86% rename from src/PostProcessData/postprocessComponent/particleProbePostprocessComponent.hpp rename to src/PostprocessData/postprocessComponent/particleProbePostprocessComponent/particleProbePostprocessComponent.hpp index 7ceaf893..5069e291 100644 --- a/src/PostProcessData/postprocessComponent/particleProbePostprocessComponent.hpp +++ b/src/PostprocessData/postprocessComponent/particleProbePostprocessComponent/particleProbePostprocessComponent.hpp @@ -25,10 +25,12 @@ Licence: #include "fieldsDataBase.hpp" #include "centerPointsRegionPoints.hpp" #include "regionField.hpp" +#include "oFstream.hpp" namespace pFlow { + class particleProbePostprocessComponent : public postprocessComponent @@ -48,8 +50,12 @@ private: uniquePtr processedField_ = nullptr; + word fieldName_; + word name_; + mutable uniquePtr osPtr_ = nullptr; + public: TypeInfo("PostprocessComponent"); @@ -63,6 +69,12 @@ public: ~particleProbePostprocessComponent()override = default; + add_vCtor + ( + postprocessComponent, + particleProbePostprocessComponent, + dictionary + ); word name()const override { @@ -74,7 +86,6 @@ public: return regionPointsPtr_(); } - const regionPoints& regPoints() const override { return regionPointsPtr_(); @@ -87,6 +98,8 @@ public: return executed_; } + bool write(const fileSystem& parDir)const override; + }; } diff --git a/src/PostProcessData/postprocessComponent/postprocessComponent.cpp b/src/PostprocessData/postprocessComponent/postprocessComponent/postprocessComponent.cpp similarity index 100% rename from src/PostProcessData/postprocessComponent/postprocessComponent.cpp rename to src/PostprocessData/postprocessComponent/postprocessComponent/postprocessComponent.cpp diff --git a/src/PostProcessData/postprocessComponent/postprocessComponent.hpp b/src/PostprocessData/postprocessComponent/postprocessComponent/postprocessComponent.hpp similarity index 96% rename from src/PostProcessData/postprocessComponent/postprocessComponent.hpp rename to src/PostprocessData/postprocessComponent/postprocessComponent/postprocessComponent.hpp index e409068b..70db2153 100644 --- a/src/PostProcessData/postprocessComponent/postprocessComponent.hpp +++ b/src/PostprocessData/postprocessComponent/postprocessComponent/postprocessComponent.hpp @@ -101,6 +101,9 @@ public: virtual bool executed()const = 0; + virtual + bool write(const fileSystem& parDir)const = 0; + static uniquePtr create( const dictionary& dict, diff --git a/src/PostProcessData/postprocessData.cpp b/src/PostprocessData/postprocessData/postprocessData.cpp similarity index 83% rename from src/PostProcessData/postprocessData.cpp rename to src/PostprocessData/postprocessData/postprocessData.cpp index 359fa893..064b5ad1 100644 --- a/src/PostProcessData/postprocessData.cpp +++ b/src/PostprocessData/postprocessData/postprocessData.cpp @@ -23,6 +23,7 @@ Licence: #include "systemControl.hpp" #include "postprocessData.hpp" #include "fileDictionary.hpp" +#include "postprocessGlobals.hpp" #include "postprocessComponent.hpp" pFlow::postprocessData::postprocessData(const systemControl &control) @@ -42,6 +43,8 @@ pFlow::postprocessData::postprocessData(const systemControl &control) ), componentsDicts_(readDictList("components", dict_)) { + postProcessGlobals::defaultDir__ = CWD()/pFlow::postProcessGlobals::defaultRelDir__; + // if dictionary is not provided, no extra action is required. if( !dict_.fileExist() ) { @@ -81,7 +84,6 @@ pFlow::postprocessData::postprocessData(const systemControl &control) bool pFlow::postprocessData::execute() { - const auto& ti = time_.TimeInfo(); for(auto& component:postprocesses_) @@ -96,4 +98,23 @@ bool pFlow::postprocessData::execute() } return true; -} \ No newline at end of file +} + +bool pFlow::postprocessData::write() const +{ + for(auto& component:postprocesses_) + { + if(!component->executed()) + { + continue; + } + if(!component->write(postProcessGlobals::defaultDir__/component->name())) + { + fatalErrorInFunction + <<"Error occured in writing postprocess component: " + <name()< + +#include "types.hpp" +#include "typeInfo.hpp" +#include "span.hpp" + +namespace pFlow +{ + +class dictionary; + +class arithmetic +{ +private: + + std::vector weight_; + +public: + + // type info + TypeInfoNV("arithmetic"); + + arithmetic() + {} + + arithmetic(const arithmetic&) = default; + + arithmetic(arithmetic&&) = default; + + arithmetic& operator=(const arithmetic&) = default; + + arithmetic& operator=(arithmetic&&) = default; + + ~arithmetic()=default; + + + bool updateWeights + ( + const realx3& center, + const span& indices, + const span& points + ) + { + return updateWeights(indices.size()); + } + + bool updateWeights(uint32 n) + { + n = max(n, 1u); + weight_.assign(n, 1); + return true; + } + + real getWeight(uint32 i)const + { + return weight_[i]; + } + + span getWeights() + { + return span(weight_.data(), weight_.size()); + } + +}; + +} + +#endif //__arithmetic_hpp__ \ No newline at end of file diff --git a/src/PostProcessData/method/uniformDistribution.hpp b/src/PostprocessData/processMethod/uniformDistribution.hpp similarity index 89% rename from src/PostProcessData/method/uniformDistribution.hpp rename to src/PostprocessData/processMethod/uniformDistribution.hpp index 736d9d2f..d0445615 100644 --- a/src/PostProcessData/method/uniformDistribution.hpp +++ b/src/PostprocessData/processMethod/uniformDistribution.hpp @@ -21,6 +21,8 @@ Licence: #ifndef __uniformDistribution_hpp__ #define __uniformDistribution_hpp__ +#include + #include "types.hpp" #include "typeInfo.hpp" #include "span.hpp" @@ -55,11 +57,14 @@ public: ~uniformDistribution()=default; - bool updateWeights(const realx3& center, const span& points) + bool updateWeights + ( + const realx3& center, + const span& indices, + const span& points + ) { - uint32 n = max(points.size(), 1u); - weight_.assign(n, 1.0/n); - return true; + return updateWeights(indices.size()); } bool updateWeights(uint32 n) diff --git a/src/PostProcessData/region/regionFields.hpp/regionField.hpp b/src/PostprocessData/region/regionFields/regionField.hpp similarity index 91% rename from src/PostProcessData/region/regionFields.hpp/regionField.hpp rename to src/PostprocessData/region/regionFields/regionField.hpp index 559f854f..8d47a281 100644 --- a/src/PostProcessData/region/regionFields.hpp/regionField.hpp +++ b/src/PostprocessData/region/regionFields/regionField.hpp @@ -57,6 +57,11 @@ public: ~regionField() = default; + const regionPoints& regPoints() const + { + return regionPoints_; + } + /// get the field value T& operator[] (const uint32 i) { @@ -75,6 +80,16 @@ public: return field_.name(); } + auto size()const + { + return field_.size(); + } + + bool empty()const + { + return field_.empty(); + } + /// @brief write the field to a file /// @param os output file stream /// @return true if successful and false if fails diff --git a/src/PostProcessData/region/regionFields.hpp/regionFieldTemplate.cpp b/src/PostprocessData/region/regionFields/regionFieldTemplate.cpp similarity index 100% rename from src/PostProcessData/region/regionFields.hpp/regionFieldTemplate.cpp rename to src/PostprocessData/region/regionFields/regionFieldTemplate.cpp diff --git a/src/PostProcessData/region/regionPoints/centerPointsRegionPoints.cpp b/src/PostprocessData/region/regionPoints/centerPointsRegionPoints/centerPointsRegionPoints.cpp similarity index 79% rename from src/PostProcessData/region/regionPoints/centerPointsRegionPoints.cpp rename to src/PostprocessData/region/regionPoints/centerPointsRegionPoints/centerPointsRegionPoints.cpp index 2595ca14..e16ef774 100644 --- a/src/PostProcessData/region/regionPoints/centerPointsRegionPoints.cpp +++ b/src/PostprocessData/region/regionPoints/centerPointsRegionPoints/centerPointsRegionPoints.cpp @@ -37,7 +37,7 @@ bool pFlow::centerPointsRegionPoints::selectIds() diameter_.resize(ids_.size(),1.0); center_.resize(ids_.size(), realx3(0,0,0)); selectedPoints_.resize(ids_.size(), -1); - return false; + return true; } pFlow::centerPointsRegionPoints::centerPointsRegionPoints( @@ -46,19 +46,7 @@ pFlow::centerPointsRegionPoints::centerPointsRegionPoints( : regionPoints(dict, fieldsDataBase), idName_(dict.getValOrSet("idName", "id")), probDict_(dict) -{ - auto idList = dict.getVal("ids"); - Set uniqueIds; - - uniqueIds.insert(idList.begin(), idList.end()); - - for(auto& id:uniqueIds) - { - ids_.push_back(id); - } - - selectedPoints_.resize(ids_.size()); -} +{} bool pFlow::centerPointsRegionPoints::update() { @@ -81,6 +69,27 @@ bool pFlow::centerPointsRegionPoints::update() } } - return false; + return true; } + +bool pFlow::centerPointsRegionPoints::write(iOstream &os) const +{ + if(firstTimeUpdate_) + { + fatalErrorInFunction + <<"Write operation should be done before executing the update. \n"; + return false; + } + os <<"# Probing particles for selected ids\n"; + os << "# SelectedId: "; + + for(auto& id: ids_) + { + os << id << tab; + } + os << endl; + os << "time"< create( diff --git a/src/PostProcessData/region/regionPoints/sphereRegionPoints.cpp b/src/PostprocessData/region/regionPoints/sphereRegionPoints/sphereRegionPoints.cpp similarity index 71% rename from src/PostProcessData/region/regionPoints/sphereRegionPoints.cpp rename to src/PostprocessData/region/regionPoints/sphereRegionPoints/sphereRegionPoints.cpp index 566fd688..4022c00e 100644 --- a/src/PostProcessData/region/regionPoints/sphereRegionPoints.cpp +++ b/src/PostprocessData/region/regionPoints/sphereRegionPoints/sphereRegionPoints.cpp @@ -27,5 +27,15 @@ bool pFlow::sphereRegionPoints::update() } } - return false; + return true; +} + +bool pFlow::sphereRegionPoints::write(iOstream &os) const +{ + os <<"# Single sphere\n"; + os <<"# center point: "<