From f36a4d77822f22c9eaae01890ff1d47c8e4fc943 Mon Sep 17 00:00:00 2001 From: hamidrezanorouzi Date: Mon, 26 Sep 2022 11:08:03 +0330 Subject: [PATCH] postprocessPhasicFlow --- CMakeLists.txt | 6 +- src/Interaction/contactSearch/cells.H | 40 ++- src/Interaction/contactSearch/methods/NBS.H | 195 +++++++------- src/phasicFlow/containers/Map/MapPtr/MapPtr.H | 1 - .../containers/pointField/pointFields.H | 9 + .../dictionary/twoPartEntry/twoPartEntry.C | 19 +- .../dictionary/twoPartEntry/twoPartEntry.H | 9 + src/phasicFlow/globals/vocabs.H | 1 + .../repository/systemControl/timeFolder.H | 11 + src/phasicFlow/typeSelection/typeInfo.H | 4 +- utilities/CMakeLists.txt | 3 + utilities/Utilities/CMakeLists.txt | 13 + utilities/Utilities/readFromTimeFolder.C | 75 ++++++ utilities/Utilities/readFromTimeFolder.H | 201 ++++++++++++++ utilities/Utilities/utilityFunctions.H | 45 ++++ utilities/{pFlowToVTK => Utilities}/vtkFile.C | 0 utilities/{pFlowToVTK => Utilities}/vtkFile.H | 0 utilities/pFlowToVTK/CMakeLists.txt | 3 +- .../postprocessPhasicFlow/CMakeLists.txt | 13 + utilities/postprocessPhasicFlow/IncludeMask.H | 250 ++++++++++++++++++ .../postprocessPhasicFlow/IncludeMasks.C | 80 ++++++ .../postprocessPhasicFlow/ProcessField.H | 164 ++++++++++++ .../postprocessPhasicFlow/ProcessFields.C | 33 +++ .../postprocessPhasicFlow/fieldOperations.H | 107 ++++++++ utilities/postprocessPhasicFlow/includeMask.C | 108 ++++++++ utilities/postprocessPhasicFlow/includeMask.H | 107 ++++++++ .../postprocessPhasicFlow/pointRectCell.H | 158 +++++++++++ utilities/postprocessPhasicFlow/postprocess.C | 145 ++++++++++ utilities/postprocessPhasicFlow/postprocess.H | 94 +++++++ .../postprocessPhasicFlow.C | 113 ++++++++ .../postprocessPhasicFlow/processField.C | 134 ++++++++++ .../postprocessPhasicFlow/processField.H | 169 ++++++++++++ .../postprocessPhasicFlow/rectMeshField.H | 173 ++++++++++++ .../rectMeshFieldToVTK.H | 98 +++++++ .../postprocessPhasicFlow/rectMeshFields.H | 45 ++++ .../postprocessPhasicFlow/rectangleMesh.H | 162 ++++++++++++ 36 files changed, 2678 insertions(+), 110 deletions(-) create mode 100644 utilities/Utilities/CMakeLists.txt create mode 100644 utilities/Utilities/readFromTimeFolder.C create mode 100644 utilities/Utilities/readFromTimeFolder.H create mode 100644 utilities/Utilities/utilityFunctions.H rename utilities/{pFlowToVTK => Utilities}/vtkFile.C (100%) rename utilities/{pFlowToVTK => Utilities}/vtkFile.H (100%) create mode 100644 utilities/postprocessPhasicFlow/CMakeLists.txt create mode 100644 utilities/postprocessPhasicFlow/IncludeMask.H create mode 100644 utilities/postprocessPhasicFlow/IncludeMasks.C create mode 100644 utilities/postprocessPhasicFlow/ProcessField.H create mode 100644 utilities/postprocessPhasicFlow/ProcessFields.C create mode 100644 utilities/postprocessPhasicFlow/fieldOperations.H create mode 100644 utilities/postprocessPhasicFlow/includeMask.C create mode 100644 utilities/postprocessPhasicFlow/includeMask.H create mode 100644 utilities/postprocessPhasicFlow/pointRectCell.H create mode 100644 utilities/postprocessPhasicFlow/postprocess.C create mode 100644 utilities/postprocessPhasicFlow/postprocess.H create mode 100644 utilities/postprocessPhasicFlow/postprocessPhasicFlow.C create mode 100644 utilities/postprocessPhasicFlow/processField.C create mode 100644 utilities/postprocessPhasicFlow/processField.H create mode 100644 utilities/postprocessPhasicFlow/rectMeshField.H create mode 100644 utilities/postprocessPhasicFlow/rectMeshFieldToVTK.H create mode 100644 utilities/postprocessPhasicFlow/rectMeshFields.H create mode 100644 utilities/postprocessPhasicFlow/rectangleMesh.H diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d03d0b7..7815b7a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,9 @@ -cmake_minimum_required(VERSION 3.22 FATAL_ERROR) +cmake_minimum_required(VERSION 3.16 FATAL_ERROR) # set the project name and version project(phasicFlow VERSION 0.1 ) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 17 CACHE STRING "" FORCE) set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_INSTALL_PREFIX ${phasicFlow_SOURCE_DIR} CACHE PATH "Install path of phasicFlow" FORCE) set(CMAKE_BUILD_TYPE Release CACHE STRING "build type" FORCE) @@ -75,7 +75,7 @@ add_subdirectory(solvers) add_subdirectory(utilities) -add_subdirectory(test_newFeatures) +#add_subdirectory(test_newFeatures) install(FILES "${PROJECT_BINARY_DIR}/phasicFlowConfig.H" diff --git a/src/Interaction/contactSearch/cells.H b/src/Interaction/contactSearch/cells.H index f0513d20..230ba2d8 100644 --- a/src/Interaction/contactSearch/cells.H +++ b/src/Interaction/contactSearch/cells.H @@ -38,12 +38,12 @@ public: protected: // - domain - box domain_; + box domain_{realx3(0.0), realx3(1.0)}; // - cell size - real cellSize_; + realx3 cellSize_{1,1,1}; - CellType numCells_; + CellType numCells_{1,1,1}; // - protected methods @@ -69,12 +69,29 @@ public: calculate(); } + + INLINE_FUNCTION_H + cells(const box& domain, int32 nx, int32 ny, int32 nz) + : + domain_(domain), + cellSize_( + (domain_.maxPoint() - domain_.minPoint())/realx3(nx, ny, nz) + ), + numCells_(nx, ny, nz) + {} + INLINE_FUNCTION_HD cells(const cells&) = default; INLINE_FUNCTION_HD cells& operator = (const cells&) = default; + INLINE_FUNCTION_HD + cells(cells &&) = default; + + INLINE_FUNCTION_HD + cells& operator=(cells&&) = default; + cells getCells()const { return *this; @@ -87,8 +104,15 @@ public: calculate(); } + INLINE_FUNCTION_H + void setCellSize(realx3 cellSize) + { + cellSize_ = cellSize; + calculate(); + } + INLINE_FUNCTION_HD - real cellSize()const + realx3 cellSize()const { return cellSize_; } @@ -124,6 +148,11 @@ public: static_cast(numCells_.y())* static_cast(numCells_.z()); } + + const auto& domain()const + { + return domain_; + } INLINE_FUNCTION_HD CellType pointIndex(const realx3& p)const @@ -221,9 +250,6 @@ public: min( domain_.maxPoint().z(), max(domain_.minPoint().z(),p.z())) ); } - - - }; diff --git a/src/Interaction/contactSearch/methods/NBS.H b/src/Interaction/contactSearch/methods/NBS.H index a454819f..573c0c47 100644 --- a/src/Interaction/contactSearch/methods/NBS.H +++ b/src/Interaction/contactSearch/methods/NBS.H @@ -24,6 +24,7 @@ Licence: #include "cells.H" #include "contactSearchFunctions.H" +#include "baseAlgorithms.H" namespace pFlow { @@ -76,7 +77,7 @@ protected: ViewType1D next_; - + INLINE_FUNCTION_H void nullify() { @@ -85,13 +86,13 @@ protected: range(0,this->nx()), range(0,this->ny()), range(0,this->nz()), - -1 + static_cast(-1) ); fill( next_, range(0,capacity_), - -1 + static_cast(-1) ); } @@ -102,13 +103,13 @@ protected: range(0,this->nx()), range(0,this->ny()), range(0,this->nz()), - -1 + static_cast(-1) ); fill( next_, nextRng, - -1 + static_cast(-1) ); } @@ -179,6 +180,24 @@ public: allocateHead(); } + NBS( + const box& domain, + int32 nx, + int32 ny, + int32 nz, + const ViewType1D& position, + const ViewType1D& diam, + int32 initialContainerSize = 1) + : + Cells(domain, nx, ny, nz), + pointPosition_(position), + diameter_(diam), + head_("NBS::head_",nx,ny,nz), //, this->nx(), this->ny(), this->nz()), + next_("NBS::next_",1) //,position.size()), + { + checkAllocateNext(pointPosition_.size()); + } + NBS( dictionary dict, const box& domain, @@ -227,6 +246,16 @@ public: return performedSearch_; } + const auto& Head()const + { + return head_; + } + + const auto& Next()const + { + return next_; + } + // - Perform the broad search to find pairs // with force = true, perform broad search regardless of // updateFrequency_ value @@ -332,6 +361,74 @@ public: } + // - build based on all points in range [0, numPoints_) + INLINE_FUNCTION_H + void buildCheckInDomain(range activeRange) + { + checkAllocateNext(activeRange.second); + nullify(activeRange); + + Cells cellIndex = static_cast(*this); + auto points = pointPosition_; + auto next = next_; + auto head = head_; + + Kokkos::RangePolicy< + Kokkos::IndexType, + Kokkos::Schedule, + ExecutionSpace> rPolicy(activeRange.first, activeRange.second); + + Kokkos::parallel_for( + "NBS::buildCheckInDomain", + rPolicy, + LAMBDA_HD(int32 i){ + + CellType ind; + if( cellIndex.pointIndexInDomain(points[i], ind) ) + { + int32 old = Kokkos::atomic_exchange(&head(ind.x(), ind.y(), ind.z()), i); + next[i] = old; + } + + } + ); + Kokkos::fence(); + + } + + template + INLINE_FUNCTION_H + void buildCheckInDomain(range activeRange, IncludeFunction incld) + { + checkAllocateNext(activeRange.second); + nullify(activeRange); + + Cells cellIndex = static_cast(*this); + auto points = pointPosition_; + auto next = next_; + auto head = head_; + + Kokkos::RangePolicy< + Kokkos::IndexType, + Kokkos::Schedule, + ExecutionSpace> rPolicy(activeRange.first, activeRange.second); + + Kokkos::parallel_for( + "NBS::buildCheckInDomain", + rPolicy, + LAMBDA_HD(int32 i){ + + CellType ind; + if( incld(i) && cellIndex.pointIndexInDomain(points[i], ind) ) + { + auto old = Kokkos::atomic_exchange(&head(ind.x(), ind.y(), ind.z()), i); + next[i] = old; + } + }); + Kokkos::fence(); + } + + template INLINE_FUNCTION_H bool findPairs(PairsContainer& pairs) @@ -383,94 +480,6 @@ public: return true; } - /*INLINE_FUNCTION_HD - void operator()( - TagFindPairs, - int32 i, - int32 j, - int32 k, - int32& getFullUpdate)const - { - - int32 m = head_(i,j,k); - CellType currentCell(i,j,k); - int32 n = -1; - - while( m > -1 ) - { - - auto p_m = pointPosition_[m]; - auto d_m = sizeRatio_* diameter_[m]; - - // the same cell - n = next_(m); - - while(n >-1) - { - - auto p_n = pointPosition_[n]; - auto d_n = sizeRatio_*diameter_[n]; - - if( sphereSphereCheck(p_m, p_n, d_m, d_n) ) - { - auto ln = n; - auto lm = m; - if(lm>ln) Swap(lm,ln); - if( auto res = pairs_.insert(lm,ln); res <0) - { - getFullUpdate++; - } - } - - n = next_(n); - } - - // neighbor cells - CellType neighborCell; - for(int32 ni=0; ni<13; ni++) - { - if(ni==0) neighborCell = currentCell + CellType( 0, 0,-1); - else if(ni==1) neighborCell = currentCell + CellType(-1, 0,-1); - else if(ni==2) neighborCell = currentCell + CellType(-1, 0, 0); - else if(ni==3) neighborCell = currentCell + CellType(-1, 0, 1); - else if(ni==4) neighborCell = currentCell + CellType( 0,-1,-1); - else if(ni==5) neighborCell = currentCell + CellType( 0,-1, 0); - else if(ni==6) neighborCell = currentCell + CellType( 0,-1, 1); - else if(ni==7) neighborCell = currentCell + CellType(-1,-1,-1); - else if(ni==8) neighborCell = currentCell + CellType(-1,-1, 0); - else if(ni==9) neighborCell = currentCell + CellType(-1,-1, 1); - else if(ni==10) neighborCell = currentCell + CellType( 1,-1,-1); - else if(ni==11) neighborCell = currentCell + CellType( 1,-1, 0); - else if(ni==12) neighborCell = currentCell + CellType( 1,-1, 1); - - if( this->isInRange(neighborCell) ) - { - - n = head_(neighborCell.x(), neighborCell.y(), neighborCell.z()); - while( n>-1) - { - - auto p_n = pointPosition_[n]; - auto d_n = sizeRatio_*diameter_[n]; - - if(sphereSphereCheck(p_m, p_n, d_m, d_n)) - { - auto ln = n; - auto lm = m; - if(lm>ln) Swap(lm,ln); - if( auto res = pairs_.insert(lm,ln); res <0) - { - getFullUpdate++; - } - } - n = next_[n]; - } - } - - } - m = next_[m]; - } - }*/ template INLINE_FUNCTION_HD diff --git a/src/phasicFlow/containers/Map/MapPtr/MapPtr.H b/src/phasicFlow/containers/Map/MapPtr/MapPtr.H index 919fa8f3..7ffb1a44 100644 --- a/src/phasicFlow/containers/Map/MapPtr/MapPtr.H +++ b/src/phasicFlow/containers/Map/MapPtr/MapPtr.H @@ -1,4 +1,3 @@ - /*------------------------------- phasicFlow --------------------------------- O C enter of O O E ngineering and diff --git a/src/phasicFlow/containers/pointField/pointFields.H b/src/phasicFlow/containers/pointField/pointFields.H index 8b908825..2b5e095b 100644 --- a/src/phasicFlow/containers/pointField/pointFields.H +++ b/src/phasicFlow/containers/pointField/pointFields.H @@ -29,6 +29,15 @@ Licence: namespace pFlow { +template + using pointField_H = pointField; + +template + using pointField_D = pointField; + +template + using pointField_HD = pointField; + using int8PointField_D = pointField; diff --git a/src/phasicFlow/dictionary/twoPartEntry/twoPartEntry.C b/src/phasicFlow/dictionary/twoPartEntry/twoPartEntry.C index 2b83db0d..04bad294 100644 --- a/src/phasicFlow/dictionary/twoPartEntry/twoPartEntry.C +++ b/src/phasicFlow/dictionary/twoPartEntry/twoPartEntry.C @@ -36,13 +36,26 @@ pFlow::twoPartEntry::twoPartEntry iT >> firstPart_; + + if(iT.eof()) return; + token t; - while(true) { - iT.read(t); + if( !iT.read(t) ) + { + fatalErrorInFunction<<"attemps to read from token stream failed \n"; + fatalExit; + } secondPart_.appendToken(t); if(iT.eof())break; } -} \ No newline at end of file +} + +bool pFlow::isTwoPartEntry(pFlow::dataEntry entry) +{ + twoPartEntry tpEntry(entry); + if(tpEntry.secondPart().size() == 0) return false; + return true; +} diff --git a/src/phasicFlow/dictionary/twoPartEntry/twoPartEntry.H b/src/phasicFlow/dictionary/twoPartEntry/twoPartEntry.H index c3c45870..1f680e43 100644 --- a/src/phasicFlow/dictionary/twoPartEntry/twoPartEntry.H +++ b/src/phasicFlow/dictionary/twoPartEntry/twoPartEntry.H @@ -53,6 +53,11 @@ public: return firstPart_; } + iTstream& secondPart() + { + return secondPart_; + } + template T secondPartVal()const { @@ -65,6 +70,10 @@ public: }; +bool isTwoPartEntry(dataEntry entry); + + + } #endif diff --git a/src/phasicFlow/globals/vocabs.H b/src/phasicFlow/globals/vocabs.H index 68fa1e52..e3a576a2 100755 --- a/src/phasicFlow/globals/vocabs.H +++ b/src/phasicFlow/globals/vocabs.H @@ -46,6 +46,7 @@ const inline char* motionModelFile__ = "motionModel"; const inline char* contactSearchFile__ = "contactSearch"; const inline char* propertyFile__ = "interaction"; const inline char* interactionFile__ = "interaction"; +const inline char* postprocessFile__ = "postprocessDict"; const inline char* uniform__ = "uniform"; diff --git a/src/phasicFlow/repository/systemControl/timeFolder.H b/src/phasicFlow/repository/systemControl/timeFolder.H index 111ada38..b8d5a554 100644 --- a/src/phasicFlow/repository/systemControl/timeFolder.H +++ b/src/phasicFlow/repository/systemControl/timeFolder.H @@ -57,6 +57,17 @@ public: return currentFolder_->second; } + word timeName()const + { + auto tName = tailName(folder().wordPath(), '/'); + return tName; + } + + fileSystem localFolder()const + { + return fileSystem(timeName()); + } + bool operator ++(int) { if(!finished()) currentFolder_++; diff --git a/src/phasicFlow/typeSelection/typeInfo.H b/src/phasicFlow/typeSelection/typeInfo.H index 6f5596cf..b23eaa02 100644 --- a/src/phasicFlow/typeSelection/typeInfo.H +++ b/src/phasicFlow/typeSelection/typeInfo.H @@ -62,6 +62,7 @@ Licence: { return word(tName)+"<"+Type::TYPENAME()+">";} \ else \ return word(tName)+"<"+basicTypeName()+">"; \ + return "noTYPE"; \ } \ virtual word typeName() const { return TYPENAME();} @@ -73,6 +74,7 @@ Licence: { return word(tName)+"<"+Type1::TYPENAME()+","+Type2::TYPENAME()+">";} \ else \ return word(tName)+"<"+basicTypeName()+","+Type2::TYPENAME()+">";\ + return "noTYPE"; \ } \ virtual word typeName() const { return TYPENAME();} @@ -101,7 +103,7 @@ Licence: has_static_member(TYPENAME); \ inline static word TYPENAME() \ { \ - if constexpr( has_static_member_TYPENAME::value) \ + if constexpr ( has_static_member_TYPENAME::value) \ { return word(tName)+"<"+Type::TYPENAME()+","+word(tName2)+">";} \ else \ return word(tName)+"<"+basicTypeName()+","+word(tName2)+">"; \ diff --git a/utilities/CMakeLists.txt b/utilities/CMakeLists.txt index 8b9eaa67..3a7e766f 100644 --- a/utilities/CMakeLists.txt +++ b/utilities/CMakeLists.txt @@ -7,4 +7,7 @@ add_subdirectory(geometryPhasicFlow) add_subdirectory(pFlowToVTK) +add_subdirectory(Utilities) + +add_subdirectory(postprocessPhasicFlow) diff --git a/utilities/Utilities/CMakeLists.txt b/utilities/Utilities/CMakeLists.txt new file mode 100644 index 00000000..3f3df352 --- /dev/null +++ b/utilities/Utilities/CMakeLists.txt @@ -0,0 +1,13 @@ + +set(SourceFiles +vtkFile.C +readFromTimeFolder.C +) + +set(link_libs Kokkos::kokkos phasicFlow Particles Geometry) + +pFlow_add_library_install(Utilities SourceFiles link_libs) + + + + diff --git a/utilities/Utilities/readFromTimeFolder.C b/utilities/Utilities/readFromTimeFolder.C new file mode 100644 index 00000000..8ef1bd04 --- /dev/null +++ b/utilities/Utilities/readFromTimeFolder.C @@ -0,0 +1,75 @@ +/*------------------------------- 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 "readFromTimeFolder.H" + +pFlow::readFromTimeFolder::readFromTimeFolder(repository& rep) +: + repository_(rep) +{} + + +std::pair + pFlow::readFromTimeFolder::fieldExists(word fieldName)const +{ + IOfileHeader fieldHeader( + objectFile( + fieldName, + repository_.path(), + objectFile::READ_ALWAYS, + objectFile::WRITE_NEVER) + ); + + return std::make_pair( fieldHeader.headerOk(true), fieldHeader); +} + +bool pFlow::readFromTimeFolder::pointFieldFileGetType( + word fieldName, + word& typeName) const +{ + + word fileTypeName, space; + if( auto [exist, fieldHeader]= fieldExists(fieldName); !exist ) + { + fatalErrorInFunction<< "Folder "<< repository_.path() << + " does not contain " << fieldName << " field."< + fieldExists(word fieldName)const; + + + + bool pointFieldFileGetType(word fieldName, word& typeName) const; + + template + bool pointFieldGetType(word& typeName)const + { + word fieldTYPENAME = pointField_H::TYPENAME(); + word fldType{}, space{}; + + if( !pFlow::utilities::pointFieldGetType( + fieldTYPENAME, fldType, space) ) + { + fatalErrorInFunction<< + "error in extracting type from "< + bool pointFieldGetCheckType(word fieldName, word& typeName) const + { + + word fieldTYPENAME = pointField_H::TYPENAME(); + word flType{},fldType{}; + + if(!pointFieldFileGetType( fieldName, flType)) + { + fatalExit; + return false; + } + + if( !pointFieldGetType(fldType) ) + { + fatalExit; + return false; + } + + + if( flType == fldType ) + { + typeName = flType; + return true; + }else + { + typeName.clear(); + return false; + } + } + + template + pointField_H& createUniformPointField_H(word name, T value) + { + if( !checkForPointStructure() ) + { + fatalErrorInFunction<< + "cannot find " << pointStructureFile__ << " in repository "<< repository_.name()<(pointStructureFile__); + + word fType; + pointFieldGetType(fType); + word newName = name + fType; + + auto& field = repository_.emplaceReplaceObject>( + objectFile( + name, + "", + objectFile::READ_NEVER, + objectFile::WRITE_NEVER + ), + pStruct, + value + ); + + return field; + + } + + template + pointField_H& readPointField_H(word name) + { + if( !checkForPointStructure() ) + { + fatalErrorInFunction<< + "cannot find " << pointStructureFile__ << " in repository "<< repository_.name()<(pointStructureFile__); + + auto& field = repository_.emplaceObjectOrGet>( + objectFile( + name, + "", + objectFile::READ_IF_PRESENT, + objectFile::WRITE_ALWAYS + ), + pStruct, + T{} + ); + + return field; + + } + + template + pointField_D& readPointField_D(word name) + { + if( !checkForPointStructure() ) + { + fatalErrorInFunction<< + "cannot find " << pointStructureFile__ << " in repository "<< repository_.name()<(pointStructureFile__); + + auto& field = repository_.emplaceObjectOrGet>( + objectFile( + name, + "", + objectFile::READ_IF_PRESENT, + objectFile::WRITE_ALWAYS + ), + pStruct, + T{} + ); + + return field; + } + +}; + +} //pFlow + + + +#endif //__readFromTimeFolder_H__ diff --git a/utilities/Utilities/utilityFunctions.H b/utilities/Utilities/utilityFunctions.H new file mode 100644 index 00000000..e31d16bb --- /dev/null +++ b/utilities/Utilities/utilityFunctions.H @@ -0,0 +1,45 @@ +/*------------------------------- 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 __utilityFunctions_H__ +#define __utilityFunctions_H__ + +#include + + +namespace pFlow::utilities +{ + +bool inline pointFieldGetType(std::string TYPENAME, std::string& fieldType, std::string& 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; +} + + +} + + +#endif //__utilityFunctions_H__ \ No newline at end of file diff --git a/utilities/pFlowToVTK/vtkFile.C b/utilities/Utilities/vtkFile.C similarity index 100% rename from utilities/pFlowToVTK/vtkFile.C rename to utilities/Utilities/vtkFile.C diff --git a/utilities/pFlowToVTK/vtkFile.H b/utilities/Utilities/vtkFile.H similarity index 100% rename from utilities/pFlowToVTK/vtkFile.H rename to utilities/Utilities/vtkFile.H diff --git a/utilities/pFlowToVTK/CMakeLists.txt b/utilities/pFlowToVTK/CMakeLists.txt index 5bf43fce..8946cdfe 100644 --- a/utilities/pFlowToVTK/CMakeLists.txt +++ b/utilities/pFlowToVTK/CMakeLists.txt @@ -1,9 +1,8 @@ set(source_files pFlowToVTK.C -vtkFile.C geometric.C ) -set(link_lib phasicFlow Kokkos::kokkos) +set(link_lib phasicFlow Kokkos::kokkos Utilities) pFlow_make_executable_install(pFlowToVTK source_files link_lib) diff --git a/utilities/postprocessPhasicFlow/CMakeLists.txt b/utilities/postprocessPhasicFlow/CMakeLists.txt new file mode 100644 index 00000000..84bfeee4 --- /dev/null +++ b/utilities/postprocessPhasicFlow/CMakeLists.txt @@ -0,0 +1,13 @@ + +set(source_files +postprocessPhasicFlow.C +postprocess.C +processField.C +ProcessFields.C +includeMask.C +IncludeMasks.C + +) +set(link_lib phasicFlow Interaction Kokkos::kokkos Utilities) + +pFlow_make_executable_install(postprocessPhasicFlow source_files link_lib) diff --git a/utilities/postprocessPhasicFlow/IncludeMask.H b/utilities/postprocessPhasicFlow/IncludeMask.H new file mode 100644 index 00000000..fb537c13 --- /dev/null +++ b/utilities/postprocessPhasicFlow/IncludeMask.H @@ -0,0 +1,250 @@ +/*------------------------------- 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_H__ +#define __IncludeMask_H__ + + +#include "includeMask.H" + +namespace pFlow +{ + + +template +struct greaterThanOp +{ + TypeNameNV("greaterThan"); + + inline + bool operator()(const T &compVal, const T &val) const { + return val > compVal; } +}; + +template +struct greaterThanEqOp +{ + TypeNameNV("greaterThanEq"); + + inline + bool operator()(const T &compVal, const T &val) const { + return val >= compVal; } +}; + +template +struct lessThanOp +{ + TypeNameNV("lessThan"); + + inline + bool operator()(const T &compVal, const T &val) const { + return val < compVal; } +}; + +template +struct lessThanEqOp +{ + TypeNameNV("lessThanEq"); + + inline + bool operator()(const T &compVal, const T &val) const { + return val <= compVal; } +}; + +template +struct equalOp +{ + TypeNameNV("equal"); + + inline + bool operator()(const T &compVal, const T &val) const { + return equal(val , compVal); } +}; + + +template +struct betweenOp +{ + TypeNameNV("between"); + + inline + bool operator()(const T &compVal1, const T &compVal2 ,const T &val) const { + return val>compVal1 && val +struct betweenEqOp +{ + TypeNameNV("betweenEq"); + + inline + bool operator()(const T &compVal1, const T &compVal2 ,const T &val) const { + return val>=compVal1 && val<=compVal2; } +}; + +template +struct allOp +{ + TypeNameNV("all"); + + inline + bool operator()() const {return true; } +}; + + + +template class Operator> +class compareOne +{ +public: + + using opertorType = Operator; + +protected: + T compValue_{}; + opertorType operator_{}; +public: + + TypeNameNV(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: + + TypeNameNV(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: + + TypeNameNV(Operator::TYPENAME()); + compareZero(const dictionary& dict); + + bool operator()(const T& value) const + { + return operator_(); + } +}; + +template +class IncludeMask +: + public includeMask +{ +protected: + + Operator operator_; + + pointField_H field_; + +public: + + TypeNameTemplate2("IncludeMask", T, Operator); + + IncludeMask( + const dictionary& dict, + const word& opType, + readFromTimeFolder& timeFolder) + : + includeMask(dict, opType, timeFolder), + operator_(dict), + field_(timeFolder.readPointField_H(this->fieldName())) + {} + + add_vCtor( + includeMask, + IncludeMask, + dictionary); + + bool isIncluded(int32 n)const override + { + return operator_(field_[n]); + } + +}; + + +template +class IncludeMask> +: + public includeMask +{ +public: + TypeNameTemplate2("IncludeMask", T, allOp); + + IncludeMask( + const dictionary& dict, + const word& opType, + readFromTimeFolder& timeFolder) + : + includeMask(dict, opType, timeFolder) + {} + + add_vCtor( + includeMask, + IncludeMask, + dictionary); + + bool isIncluded(int32 n)const override + { + return true; + } +}; + + +} // pFlow + +#endif //__IncludeMask_H__ + + diff --git a/utilities/postprocessPhasicFlow/IncludeMasks.C b/utilities/postprocessPhasicFlow/IncludeMasks.C new file mode 100644 index 00000000..c6752152 --- /dev/null +++ b/utilities/postprocessPhasicFlow/IncludeMasks.C @@ -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. + +-----------------------------------------------------------------------------*/ + +#include "IncludeMask.H" + +// 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 >; + +template class pFlow::IncludeMask>; + +// int32 +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>; + +// in64 +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>; + + +template class pFlow::IncludeMask>; diff --git a/utilities/postprocessPhasicFlow/ProcessField.H b/utilities/postprocessPhasicFlow/ProcessField.H new file mode 100644 index 00000000..702ef866 --- /dev/null +++ b/utilities/postprocessPhasicFlow/ProcessField.H @@ -0,0 +1,164 @@ +/*------------------------------- 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 __ProcessField_H__ +#define __ProcessField_H__ + + +#include "processField.H" +#include "rectMeshFields.H" +#include "twoPartEntry.H" +#include "fieldOperations.H" +#include "rectMeshFieldToVTK.H" + +namespace pFlow +{ + + +template +class ProcessField +: + public processField +{ + +protected: + + pointField_H& field_; + + + rectMeshField_H& processedField_; + +public: + + TypeNameTemplate("ProcessField", T); + + + ProcessField( + const dictionary& dict, + pointRectCell& pToCell, + repository& rep) + : + processField(dict, pToCell, rep), + field_( + this->isUniform()? + timeFolder().createUniformPointField_H(this->fieldName(), getUniformValue() ): + timeFolder().readPointField_H(this->fieldName()) + ), + processedField_ + ( + processedRepository().emplaceObject> + ( + objectFile + ( + processedFieldName(), + "", + objectFile::READ_NEVER, + objectFile::WRITE_ALWAYS + ), + mesh(), + processedFieldName(), + T{} + ) + ) + { + + } + + add_vCtor( + processField, + ProcessField, + dictionary); + + + T getUniformValue()const + { + const dataEntry& entry = dict().dataEntryRef("field"); + twoPartEntry tpEntry(entry); + return tpEntry.secondPartVal(); + } + + virtual bool process() override + { + + const includeMask& incMask = includeMask_(); + + auto numerator = sumMaksOp( field_ , this->pointToCell(), incMask); + + rectMeshField_H denomerator( this->mesh(), real{} ); + + if(action() == "sum") + { + denomerator = rectMeshField_H(this->mesh(), static_cast(1.0)); + + }else if(action() == "average") + { + + pointField_H oneFld(field_.pStruct(), 1.0, 1.0); + + denomerator = sumOp(oneFld, this->pointToCell()); + + }else if(action() == "averageMask") + { + pointField_H oneFld(field_.pStruct(), 1.0, 1.0); + + denomerator = sumMaksOp(oneFld, this->pointToCell(), incMask); + }else + { + fatalErrorInFunction<<"action is not known: "<< action()<mesh().nx(); i++ ) + { + for(int32 j=0; jmesh().ny(); j++ ) + { + for(int32 k=0; kmesh().nz(); k++ ) + { + if( pointToCell().nPointInCell(i,j,k)>= threshold() ) + { + processedField_(i,j,k) = numerator(i,j,k)/denomerator(i,j,k); + } + else + { + processedField_(i,j,k) = T{}; + } + } + } + } + + + return true; + } + + + bool writeToVTK(iOstream& os)const override + { + return convertRectMeshField(os, processedField_); + } + +}; + + +} // pFlow + + + +#endif //__ProcessField_H__ diff --git a/utilities/postprocessPhasicFlow/ProcessFields.C b/utilities/postprocessPhasicFlow/ProcessFields.C new file mode 100644 index 00000000..e3f4b3a2 --- /dev/null +++ b/utilities/postprocessPhasicFlow/ProcessFields.C @@ -0,0 +1,33 @@ +/*------------------------------- 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 "ProcessField.H" + + +template class pFlow::ProcessField; + +template class pFlow::ProcessField; + +template class pFlow::ProcessField; + +template class pFlow::ProcessField; + +template class pFlow::ProcessField; + diff --git a/utilities/postprocessPhasicFlow/fieldOperations.H b/utilities/postprocessPhasicFlow/fieldOperations.H new file mode 100644 index 00000000..ad4f26e4 --- /dev/null +++ b/utilities/postprocessPhasicFlow/fieldOperations.H @@ -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 __fieldOperations_H__ +#define __fieldOperations_H__ + +#include "rectMeshFields.H" +#include "pointFields.H" +#include "pointRectCell.H" +#include "includeMask.H" + +namespace pFlow +{ + + +template +rectMeshField_H sumOp( const pointField_H field, const pointRectCell& pointToCell) +{ + // create field + const auto& mesh = pointToCell.mesh(); + + rectMeshField_H results(mesh, T(0)); + + for(int32 i=0; i-1) + { + res += field[n]; + n = pointToCell.Next(n); + } + + results(i,j,k) = res; + } + } + } + + return results; +} + +template +rectMeshField_H sumMaksOp( const pointField_H field, const pointRectCell& pointToCell, const incMask& mask) +{ + // create field + const auto& mesh = pointToCell.mesh(); + + rectMeshField_H results(mesh, T(0)); + + for(int32 i=0; i-1) + { + + if(mask(n)) + { + res += field[n]; + } + + n = pointToCell.Next(n); + } + + results(i,j,k) = res; + } + } + } + + return results; +} + + + + +} + + +#endif //__fieldOperations_H__ + diff --git a/utilities/postprocessPhasicFlow/includeMask.C b/utilities/postprocessPhasicFlow/includeMask.C new file mode 100644 index 00000000..9fdd8c14 --- /dev/null +++ b/utilities/postprocessPhasicFlow/includeMask.C @@ -0,0 +1,108 @@ +/*------------------------------- 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.H" + +pFlow::includeMask::includeMask( + const dictionary& dict, + const word& opType, + readFromTimeFolder& timeFolder) +: + operatorType_(opType), + timeFolder_(timeFolder) +{ + if(!getFieldType(dict, timeFolder, fieldName_, fieldType_)) + { + fatalExit; + } + +} + + + +bool pFlow::includeMask::getFieldType( + const dictionary& dict, + readFromTimeFolder& timeFolder, + word& fName, + word& fType) +{ + + fName = dict.getValOrSet("field", "none"); + + if(fName == "none") + { + fType = "int8"; + } + else + { + if( !timeFolder.pointFieldFileGetType(fName, fType) ) + { + fatalErrorInFunction<<"error in reading field type from file "<< fName<< + "in folder "<< timeFolder.path()< pFlow::includeMask::create( + const dictionary& dict, + const word& opType, + readFromTimeFolder& timeFolder) +{ + + word fType, fName; + if(!getFieldType(dict, timeFolder, fName, fType)) + { + fatalExit; + return nullptr; + } + + word method = angleBracketsNames2("IncludeMask", fType, opType); + + if( dictionaryvCtorSelector_.search(method) ) + { + auto objPtr = + dictionaryvCtorSelector_[method] + (dict, opType, timeFolder); + Report(2)<< dict.name()<< " with model "< create( + const dictionary& dict, + const word& opType, + readFromTimeFolder& timeFolder); + +}; + + + +} // pFlow + +#endif //__IncludeMask_H__ + + diff --git a/utilities/postprocessPhasicFlow/pointRectCell.H b/utilities/postprocessPhasicFlow/pointRectCell.H new file mode 100644 index 00000000..d4a9a324 --- /dev/null +++ b/utilities/postprocessPhasicFlow/pointRectCell.H @@ -0,0 +1,158 @@ +/*------------------------------- 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 __pointRectCell_H__ +#define __pointRectCell_H__ + +#include "NBS.H" +#include "rectMeshFields.H" +#include "pointStructure.H" + +namespace pFlow +{ + + +class pointRectCell +{ +public: + + using mapType = NBS; + + using memory_space = typename mapType::memory_space; + +protected: + + repository& processedRepository_; + + rectangleMesh& mesh_; + + + const pointStructure& pStruct_; + + ViewType1D pointPosition_; + + ViewType1D diameter_; + + + mapType map_; + + int32RectMeshField_H nPointInCell_; + +public: + + pointRectCell( + const dictionary& dictMesh, + const pointStructure& pStruct, + repository& rep) + : + processedRepository_(rep), + mesh_ + ( + processedRepository_.emplaceObject + ( + objectFile + ( + "rectMesh", + "", + objectFile::READ_NEVER, + objectFile::WRITE_NEVER + ), + dictMesh + ) + ), + pStruct_(pStruct), + pointPosition_(pStruct_.pointPosition().hostVectorAll()), + diameter_("diameter", pStruct_.capacity()), + map_( + mesh_.domain(), + mesh_.nx(), + mesh_.ny(), + mesh_.nz(), + pointPosition_, + diameter_), + nPointInCell_(mesh_, 0) + { + + mapPOints(); + } + + const auto& mesh()const + { + return mesh_; + } + + auto& processedRepository() + { + return processedRepository_; + } + + void mapPOints() + { + range activeRange = pStruct_.activeRange(); + auto activeMask = pStruct_.activePointsMaskH(); + + + map_.buildCheckInDomain(activeRange, activeMask); + + + const auto& Next = map_.Next(); + const auto& Head = map_.Head(); + for(int32 i=0; i-1) + { + res+=1; + n = Next[n]; + } + nPointInCell_(i,j,k) = res; + + } + } + } + + } + + int32 nPointInCell(int32 i, int32 j, int32 k)const + { + return nPointInCell_(i,j,k); + } + + auto inline Head(int32 i, int32 j, int32 k)const + { + return map_.Head()(i,j,k); + } + + auto inline Next(int32 n)const + { + return map_.Next()(n); + } + //auto +}; + +} + +#endif // __pointRectCell_H__ diff --git a/utilities/postprocessPhasicFlow/postprocess.C b/utilities/postprocessPhasicFlow/postprocess.C new file mode 100644 index 00000000..76e6616e --- /dev/null +++ b/utilities/postprocessPhasicFlow/postprocess.C @@ -0,0 +1,145 @@ +/*------------------------------- 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 "postprocess.H" +#include "timeFolder.H" +#include "pointStructure.H" +#include "vocabs.H" +#include "vtkFile.H" + +pFlow::postprocess::postprocess(systemControl& control) +: + control_(control), + dict_(postprocessFile__, control_.settings().path()+postprocessFile__) +{ + Report(1)<<"Reading numberBased dictionary ..."< + ( + "timeFolder-"+tName, + localFolder, + &control_ + ); + + Report(1)<<"Reading pointStructure"<( + objectFile + ( + pFlow::pointStructureFile__, + "", + objectFile::READ_ALWAYS, + objectFile::WRITE_NEVER + )); + + + Report(1)<<"Creating mesh and point to cell mapper"<( + dict_.subDict("rectMesh"), + timeFolderReposiory().lookupObject(pointStructureFile__), + timeFolderReposiory()); + + // first numberbased dict + processedFields_.clear(); + for(word& dictName:numberBasedDictNames_) + { + + + auto fieldDict = dict_.subDict("numberBased").subDict(dictName); + auto ppFieldPtr = processField::create( + fieldDict, + pointToCell_(), + timeFolderReposiory()); + + if(!ppFieldPtr->process()) + { + fatalExit; + } + + processedFields_.push_back( ppFieldPtr.release() ); + + output<mesh().writeToVtk(vtk()); + + forAll( i, processedFields_) + { + + if( !processedFields_[i].writeToVTK(vtk())) + { + + fatalErrorInFunction<<"error in writing "<< processedFields_[i].processedFieldName()<< + "to vtk file\n"; + return false; + } + } + + return true; +} diff --git a/utilities/postprocessPhasicFlow/postprocess.H b/utilities/postprocessPhasicFlow/postprocess.H new file mode 100644 index 00000000..13d979bc --- /dev/null +++ b/utilities/postprocessPhasicFlow/postprocess.H @@ -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 __postprocess_H__ +#define __postprocess_H__ + + +#include "MapPtr.H" +#include "systemControl.H" +#include "pointRectCell.H" +#include "processField.H" + + +namespace pFlow +{ + +class timeFolder; + + +class postprocess +{ +protected: + + systemControl& control_; + + dictionary dict_; + + wordList numberBasedDictNames_; + + wordList weightBasedDictNames_; + + uniquePtr timeFolderReposiory_ {nullptr}; + + uniquePtr pointToCell_ {nullptr}; + + //uniquePtr processedRepository_ {nullptr}; + + ListPtr processedFields_; + + real time_=0.0; + + //orderedMapPtr timeFolderRepositories_; + + + Logical saveTimes{"No"}; + + Logical saveTimeFolders{"No"}; + + + auto& timeFolderReposiory() + { + return timeFolderReposiory_(); + } + +public: + + postprocess(systemControl& control); + + + + bool processTimeFolder(real time, const word& tName, const fileSystem& localFolder); + + bool processTimeFolder(const timeFolder& tFolder); + + + bool writeToVTK(fileSystem path, word bName)const; + + +}; + + + +} + + + +#endif //__postprocess_H__ diff --git a/utilities/postprocessPhasicFlow/postprocessPhasicFlow.C b/utilities/postprocessPhasicFlow/postprocessPhasicFlow.C new file mode 100644 index 00000000..c57fe609 --- /dev/null +++ b/utilities/postprocessPhasicFlow/postprocessPhasicFlow.C @@ -0,0 +1,113 @@ +/*------------------------------- 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 "systemControl.H" +#include "timeFolder.H" +#include "commandLine.H" +#include "ranges.H" + +#include "postprocess.H" + +using pFlow::word; +using pFlow::wordVector; +using pFlow::wordList; +using pFlow::commandLine; +using pFlow::timeFolder; +using pFlow::output; +using pFlow::endl; + + + + +int main(int argc, char** argv ) +{ + + word outFolder = (pFlow::CWD()/word("VTK/postprocess")).wordPath(); + + commandLine cmds( + "postprocessPhasicFlow", + "post-process fields in time folders based on the input file " + "settings/postprocessDict and convetes the results into vtk file format."); + + wordVector times; + + cmds.addOption("-o,--out-folder", + outFolder, + "path to output folder of VTK/postprocess", + "path"); + + cmds.addOption( + "-t,--time", + times.vectorField(), + "a space separated lits of time folders, or a strided range begin:stride:end, or an interval begin:end", + " "); + + bool withZeroFolder = false; + cmds.addOption( + "-z, --zeroFolder", + withZeroFolder, + "Do NOT exclude zero folder from processing time folders"); + + if(!cmds.parse(argc, argv)) return 0; + + #include "initialize_Control.H" + + + pFlow::postprocess post(Control); + + // time folders in case + timeFolder folders(Control); + + // time in command line + pFlow::realCombinedRange validRange; + if( cmds.count("--time") ) + { + if(!validRange.addRanges(times)){ + fatalExit; } + } + else + { + validRange.addIntervalRange(folders.startTime(), folders.endTime()); + } + + pFlow::fileSystem destFolder = pFlow::fileSystem(outFolder); + + do + { + + + if( !validRange.isMember( folders.time() ) )continue; + + if( !withZeroFolder && pFlow::equal(folders.time() , 0.0))continue; + + post.processTimeFolder(folders); + + if(!post.writeToVTK(destFolder, "processed")) + { + fatalExit; + } + + + }while (folders++); + + #include "finalize.H" + + return true; +} \ No newline at end of file diff --git a/utilities/postprocessPhasicFlow/processField.C b/utilities/postprocessPhasicFlow/processField.C new file mode 100644 index 00000000..ec16addd --- /dev/null +++ b/utilities/postprocessPhasicFlow/processField.C @@ -0,0 +1,134 @@ +/*------------------------------- 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 "processField.H" +#include "pointRectCell.H" +#include "repository.H" +#include "twoPartEntry.H" + + +pFlow::processField::processField( + const dictionary& dict, + pointRectCell& pToCell, + repository& rep) +: + dict_(dict), + pointToCell_(pToCell), + timeFolder_(rep), + processedFieldName_(dict.name()), + action_(dict.getVal("action")), + includeMaskType_(dict.getVal("includeMask")), + threshold_(dict.getValOrSet("threshold", 1)) +{ + + if(!processField::getFieldType( + dict_, + timeFolder_, + fieldName_, + fieldType_) ) + { + fatalExit; + } + + auto& incDict = dict_.subDictOrCreate(includeMaskType_+"Info"); + + includeMask_ = includeMask::create(incDict, includeMaskType_, timeFolder_); + + +} + +bool pFlow::processField::getFieldType( + const dictionary& dict, + readFromTimeFolder& timeFolder, + word& fieldName, + word& fieldType) +{ + if(dict.containsDataEntry("field")) + { + const dataEntry& entry = dict.dataEntryRef("field"); + + if( isTwoPartEntry(entry)) + { + twoPartEntry tpEntry(entry); + fieldName = "uniformField"; + fieldType = tpEntry.firstPart(); + } + else + { + fieldName = dict.getVal("field"); + if( !timeFolder.pointFieldFileGetType(fieldName, fieldType) ) + { + fatalErrorInFunction<<"error in reading field type from file "<< fieldName<< + "in folder "<< timeFolder.path()< +pFlow::processField::create( + const dictionary& dict, + pointRectCell& pToCell, + repository& rep) +{ + + word fName, fType; + readFromTimeFolder timeFolder(rep); + if(!getFieldType(dict, timeFolder, fName, fType)) + { + fatalExit; + return nullptr; + } + + + auto method = angleBracketsNames("ProcessField", fType); + + if( dictionaryvCtorSelector_.search(method) ) + { + auto objPtr = + dictionaryvCtorSelector_[method] + (dict, pToCell, rep); + Report(2)<<"Processing/creating " << yellowText(dict.name())<< " with model "< includeMask_ = nullptr; + + bool static getFieldType( + const dictionary& dict, + readFromTimeFolder& timeFolder, + word& fieldName, + word& fieldType); + +public: + + TypeName("processField"); + + processField(const dictionary& dict, pointRectCell& pToCell, repository& rep); + + + create_vCtor( + processField, + dictionary, + (const dictionary& dict, + pointRectCell& pToCell, + repository& rep), + (dict, pToCell, rep) ); + + + const auto& mesh()const + { + return pointToCell_.mesh(); + } + + const auto& pointToCell()const + { + return pointToCell_; + } + + auto& dict() + { + return dict_; + } + + const auto& dict()const + { + return dict_; + } + + auto& timeFolderRepository() + { + return timeFolder_.db(); + } + + auto& processedRepository() + { + return pointToCell_.processedRepository(); + } + + const word& fieldType()const + { + return fieldType_; + } + + const word& fieldName()const + { + return fieldName_; + } + + bool isUniform()const + { + return fieldName_ == "uniformField"; + } + + const word& action()const + { + return action_; + } + + auto& timeFolder() + { + return timeFolder_; + } + + const word& includeMaskType()const + { + return includeMaskType_; + } + + auto threshold()const + { + return threshold_; + } + + const word& processedFieldName()const + { + return processedFieldName_; + } + + // requires a class to read pointField from timefolder + virtual bool process() = 0; + + virtual bool writeToVTK(iOstream& is) const = 0; + + static + uniquePtr create( + const dictionary& dict, + pointRectCell& pToCell, + repository& rep); +}; + + +} + + +#endif //__processField_H__ \ No newline at end of file diff --git a/utilities/postprocessPhasicFlow/rectMeshField.H b/utilities/postprocessPhasicFlow/rectMeshField.H new file mode 100644 index 00000000..1d384921 --- /dev/null +++ b/utilities/postprocessPhasicFlow/rectMeshField.H @@ -0,0 +1,173 @@ +/*------------------------------- 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 __rectMeshField_H__ +#define __rectMeshField_H__ + +#include "rectangleMesh.H" +#include "baseAlgorithms.H" + +namespace pFlow +{ + +template +class rectMeshField +{ +public: + + using viewType = ViewType3D; + + using memory_space = typename viewType::memory_space; + +protected: + + const rectangleMesh* mesh_; + + word name_="noName"; + + viewType field_; + + T defaultValue_{}; + + constexpr static inline const char* memoerySpaceName() + { + return memory_space::name(); + } + +public: + + + TypeNameTemplateNV2("rectMeshField", T, memoerySpaceName()); + + rectMeshField(const rectangleMesh& mesh, const word& name ,const T& defVal) + : + mesh_(&mesh), + name_(name), + field_("pFlow::reactMeshField", mesh_->nx(), mesh_->ny(), mesh_->nz()), + defaultValue_(defVal) + { + this->fill(defaultValue_); + } + + rectMeshField(const rectangleMesh& mesh, const T& defVal) + : + rectMeshField(mesh, "noName", defVal) + {} + + rectMeshField(const rectMeshField&) = default; + + rectMeshField& operator = (const rectMeshField&) = default; + + rectMeshField(rectMeshField&&) = default; + + rectMeshField& operator =(rectMeshField&&) = default; + + + inline uniquePtr clone() const + { + return makeUnique(*this); + } + + inline rectMeshField* clonePtr()const + { + return new rectMeshField(*this); + } + + INLINE_FUNCTION_H + const word& name()const + { + return name_; + } + + INLINE_FUNCTION_HD + int64 size()const + { + return mesh_->size(); + } + + auto nx()const + { + return mesh_->nx(); + } + + auto ny()const + { + return mesh_->ny(); + } + + auto nz()const + { + return mesh_->nz(); + } + + const auto& mesh() + { + return *mesh_; + } + + INLINE_FUNCTION_HD + real cellVol()const + { + return mesh_->cellVol(); + } + + INLINE_FUNCTION_HD + T& operator()(int32 i, int32 j, int32 k) + { + return field_(i,j,k); + } + + INLINE_FUNCTION_HD + const T& operator()(int32 i, int32 j, int32 k)const + { + return field_(i,j,k); + } + + void fill(T val) + { + pFlow::fill( + field_, + range(0,mesh_->nx()), + range(0,mesh_->ny()), + range(0,mesh_->nz()), + val + ); + } + + bool read(iIstream& is) + { + notImplementedFunction; + return true; + } + + bool write(iOstream& os)const + { + notImplementedFunction; + return true; + } + +}; + + + +} + + +#endif // __rectMeshField_H__ diff --git a/utilities/postprocessPhasicFlow/rectMeshFieldToVTK.H b/utilities/postprocessPhasicFlow/rectMeshFieldToVTK.H new file mode 100644 index 00000000..c0c42f66 --- /dev/null +++ b/utilities/postprocessPhasicFlow/rectMeshFieldToVTK.H @@ -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 __rectMeshFieldToVTK_H__ +#define __rectMeshFieldToVTK_H__ + + +namespace pFlow +{ + +template +bool convertRectMeshField(iOstream& os, rectMeshField_H& field) +{ + fatalErrorInFunction<< "this type is not supported "<< + field.typeName()< +bool convertRectMeshField(iOstream& os, rectMeshField_H& field) +{ + + os<<"FIELD FieldData 1 " << field.name() << " 1 "<< field.size() << " float\n"; + for(int32 k=0; k +bool convertRectMeshField(iOstream& os, rectMeshField_H& field) +{ + + os<<"FIELD FieldData 1 " << field.name() << " 3 "<< field.size() << " float\n"; + for(int32 k=0; k +bool convertRectMeshField(iOstream& os, rectMeshField_H& field) +{ + + os<<"FIELD FieldData 1 " << field.name() << " 1 "<< field.size() << " int\n"; + for(int32 k=0; k +using rectMeshField_H = rectMeshField; + +using int8RectMeshField_H = rectMeshField; + +using int32RectMeshField_H = rectMeshField; + +using int64RectMeshField_H = rectMeshField; + +using realRectMeshField_H = rectMeshField; + +using realx3RectMeshField_H = rectMeshField; + +} + + +#endif // __rectMeshFields_H__ diff --git a/utilities/postprocessPhasicFlow/rectangleMesh.H b/utilities/postprocessPhasicFlow/rectangleMesh.H new file mode 100644 index 00000000..cf766267 --- /dev/null +++ b/utilities/postprocessPhasicFlow/rectangleMesh.H @@ -0,0 +1,162 @@ +/*------------------------------- 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 __rectangleMesh_H__ +#define __rectangleMesh_H__ + +#include "cells.H" + +namespace pFlow +{ + + + +class rectangleMesh +: + public cells +{ + +public: + + TypeNameNV("rectangleMesh"); + + + INLINE_FUNCTION_HD + rectangleMesh(){}; + + INLINE_FUNCTION_HD + rectangleMesh( + const realx3& minP, + const realx3& maxP, + int32 nx, + int32 ny, + int32 nz) + : + cells( + box(minP, maxP), + nx, ny, nz) + {} + + INLINE_FUNCTION_H + rectangleMesh(const dictionary & dict) + : + cells( + box( + dict.getVal("min"), + dict.getVal("max")), + dict.getVal("nx"), + dict.getVal("ny"), + dict.getVal("nz") + ) + {} + + INLINE_FUNCTION_HD + rectangleMesh(const rectangleMesh&) = default; + + INLINE_FUNCTION_HD + rectangleMesh& operator = (const rectangleMesh&) = default; + + INLINE_FUNCTION_HD + rectangleMesh(rectangleMesh&&) = default; + + INLINE_FUNCTION_HD + rectangleMesh& operator = (rectangleMesh&&) = default; + + INLINE_FUNCTION_HD + ~rectangleMesh() = default; + + + INLINE_FUNCTION_HD + int64 size()const + { + return this->totalCells(); + } + + INLINE_FUNCTION_HD + real cellVol()const + { + auto [dx,dy,dz] = this->cellSize(); + return dx*dy*dz; + } + + INLINE_FUNCTION_H + auto minPoint()const + { + return domain().minPoint(); + } + + INLINE_FUNCTION_H + auto maxPoint()const + { + return domain().maxPoint(); + } + + bool read(iIstream& is) + { + return true; + } + + bool write(iOstream& os)const + { + return true; + } + + bool writeToVtk(iOstream& os)const + { + os<<"DATASET RECTILINEAR_GRID"<minPoint(); + auto [dx, dy, dz] = this->cellSize(); + + os<<"X_COORDINATES "<< nx()+1 <<" float\n"; + for(int32 i=0; i