diff --git a/.gitignore b/.gitignore index 54081c4f..fccdff9c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,12 @@ +# files +.clang-format +.vscode +.dependencygraph + # Prerequisites *.d + # Compiled Object files *.slo *.lo @@ -38,7 +44,6 @@ bin/** lib/** test*/** **/**notnow -**/MPIParallel*/** doc/code-documentation/ doc/DTAGS # all possible time folders diff --git a/CMakeLists.txt b/CMakeLists.txt index 233e18aa..fa88bc95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ project(phasicFlow VERSION 1.0 ) 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) +set(CMAKE_BUILD_TYPE Debug CACHE STRING "build type" FORCE) set(BUILD_SHARED_LIBS ON CACHE BOOL "Build using shared libraries" FORCE) mark_as_advanced(FORCE var BUILD_SHARED_LIBS) @@ -71,9 +71,9 @@ include_directories(src/setHelpers src/demComponent "${PROJECT_BINARY_DIR}") add_subdirectory(src) -#add_subdirectory(solvers) +add_subdirectory(solvers) -#add_subdirectory(utilities) +add_subdirectory(utilities) #add_subdirectory(DEMSystems) add_subdirectory(testIO) diff --git a/solvers/CMakeLists.txt b/solvers/CMakeLists.txt index 45bc40aa..7db5fd36 100644 --- a/solvers/CMakeLists.txt +++ b/solvers/CMakeLists.txt @@ -1,6 +1,6 @@ -#add_subdirectory(iterateSphereParticles) +add_subdirectory(iterateSphereParticles) add_subdirectory(iterateGeometry) diff --git a/solvers/iterateGeometry/iterateGeometry.cpp b/solvers/iterateGeometry/iterateGeometry.cpp index a43212c1..d541a5bf 100755 --- a/solvers/iterateGeometry/iterateGeometry.cpp +++ b/solvers/iterateGeometry/iterateGeometry.cpp @@ -28,13 +28,14 @@ Licence: * (https://github.com/PhasicFlow/phasicFlow/tree/main/tutorials/iterateGeometry) * folder. */ - -#include "systemControl.hpp" -#include "geometryMotion.hpp" -#include "commandLine.hpp" -#include "readControlDict.hpp" -using pFlow::commandLine; +#include "vocabs.hpp" +#include "systemControl.hpp" +#include "geometry.hpp" +#include "commandLine.hpp" +//#include "readControlDict.hpp" + +using namespace pFlow; int main( int argc, char* argv[] ) { @@ -54,6 +55,8 @@ commandLine cmds( // this should be palced in each main +processors::initProcessors(argc, argv); +initialize_pFlowProcessors(); #include "initialize_Control.hpp" #include "setProperty.hpp" @@ -68,6 +71,7 @@ commandLine cmds( // this should be palced in each main #include "finalize.hpp" +processors::finalizeProcessors(); } diff --git a/solvers/iterateSphereParticles/CMakeLists.txt b/solvers/iterateSphereParticles/CMakeLists.txt new file mode 100644 index 00000000..59700110 --- /dev/null +++ b/solvers/iterateSphereParticles/CMakeLists.txt @@ -0,0 +1,7 @@ + +set(source_files +iterateSphereParticles.cpp +) +set(link_lib Particles) + +pFlow_make_executable_install(iterateSphereParticles source_files link_lib) diff --git a/src/phasicFlow/structuredData/peakableRegion/peakableRegions.cpp b/solvers/iterateSphereParticles/createDEMComponents.hpp old mode 100644 new mode 100755 similarity index 84% rename from src/phasicFlow/structuredData/peakableRegion/peakableRegions.cpp rename to solvers/iterateSphereParticles/createDEMComponents.hpp index 32476038..85cb798a --- a/src/phasicFlow/structuredData/peakableRegion/peakableRegions.cpp +++ b/solvers/iterateSphereParticles/createDEMComponents.hpp @@ -18,10 +18,8 @@ Licence: -----------------------------------------------------------------------------*/ +// +REPORT(0)<<"\nReading sphere particles . . ."<( objectFile( @@ -37,11 +37,10 @@ REPORT(0)<<"\nCreating particle insertion object . . ."<( - objectFile( - "triSurface", - "", - objectFile::READ_ALWAYS, - objectFile::WRITE_ALWAYS - ) - ) + propertyId_ + ( + objectFile + ( + "propertyId", + "", + objectFile::READ_NEVER, + objectFile::WRITE_NEVER ), - motionComponentName_( - control.geometry().emplaceObject( - objectFile( - "motionComponentName", - "", - objectFile::READ_ALWAYS, - objectFile::WRITE_ALWAYS - ), - "motionNamesList" - ) + *this, + 0u + ), + contactForceWall_ + ( + objectFile + ( + "contactForcWall", + "", + objectFile::READ_IF_PRESENT, + objectFile::WRITE_NEVER ), - materialName_( - control.geometry().emplaceObject( - objectFile( - "materialName", - "", - objectFile::READ_ALWAYS, - objectFile::WRITE_ALWAYS - ), - "materialNamesList" - ) + *this, + zero3 + ), + normalStressWall_ + ( + objectFile + ( + "normalStressWall", + "", + objectFile::READ_IF_PRESENT, + objectFile::WRITE_NEVER ), - propertyId_( - control.geometry().emplaceObject( - objectFile( - "propertyId", - "", - objectFile::READ_NEVER, - objectFile::WRITE_NEVER), - surface(), - 0 ) ), - contactForceWall_( - control.geometry().emplaceObject( - objectFile( - "contactForceWall", - "", - objectFile::READ_IF_PRESENT, - objectFile::WRITE_ALWAYS), - surface(), - zero3) ), - stressWall_( - control.geometry().emplaceObject( - objectFile( - "stressWall", - "", - objectFile::READ_IF_PRESENT, - objectFile::WRITE_ALWAYS), - surface(), - zero3) ) + *this, + zero3 + ), + shearStressWall_ + ( + objectFile + ( + "shearStressWall", + "", + objectFile::READ_IF_PRESENT, + objectFile::WRITE_NEVER + ), + *this, + zero3 + ) { - if(!findPropertyId()) + readWholeObject_ = false; + if( !IOobject::readObject() ) + { + fatalErrorInFunction<< + "Error in reading from file "<numSurfaces() != motionComponentName_.size() ) + { + fatalErrorInFunction<< + "Number of surfaces is not equal to number of motion component names"<numSurfaces() != motionComponentName_.size() ) + { + fatalErrorInFunction<< + "Number of surfaces is not equal to number of motion component names"< + pFlow::geometry::create +( + systemControl& control, + const property& prop +) +{ + + // + fileDictionary dict( motionModelFile__, control.time().geometry().path()); + + word model = dict.getVal("motionModel"); + + auto geomModel = angleBracketsNames("geometry", model); + + REPORT(1)<< "Selecting geometry model . . ."< + pFlow::geometry::create + ( + systemControl& control, + const property& prop, + multiTriSurface& surf, + const wordVector& motionCompName, + const wordVector& materialName, + const dictionary& motionDic + ) +{ + + word model = motionDic.getVal("motionModel"); + + auto geomModel = angleBracketsNames("geometry", model); + + REPORT(1)<< "Selecting geometry model . . ."< - pFlow::geometry::create -( - systemControl& control, - const property& prop -) -{ - //motionModelFile__ - auto motionDictPtr = IOobject::make - ( - objectFile - ( - motionModelFile__, - control.geometry().path(), - objectFile::READ_ALWAYS, - objectFile::WRITE_NEVER - ), - motionModelFile__, - true - ); - word model = motionDictPtr().getObject().getVal("motionModel"); - - auto geomModel = angleBracketsNames("geometry", model); - - REPORT(1)<< "Selecting geometry model . . ."< - pFlow::geometry::create( - systemControl& control, - const property& prop, - const dictionary& dict, - const multiTriSurface& triSurface, - const wordVector& motionCompName, - const wordVector& propName) -{ - - word model = dict.getVal("motionModel"); - - auto geomModel = angleBracketsNames("geometry", model); - - REPORT(1)<< "Selecting geometry model . . ."< create(systemControl& control, const property& prop); + uniquePtr create( + systemControl& control, + const property& prop); static uniquePtr create( - systemControl& control, - const property& prop, - const dictionary& dict, - const multiTriSurface& triSurface, - const wordVector& motionCompName, - const wordVector& propName); + systemControl& control, + const property& prop, + multiTriSurface& surf, + const wordVector& motionCompName, + const wordVector& materialName, + const dictionary& motionDic); }; diff --git a/src/Geometry/geometryMotion/geometryMotion.cpp b/src/Geometry/geometryMotion/geometryMotion.cpp index ece859df..6420dadb 100644 --- a/src/Geometry/geometryMotion/geometryMotion.cpp +++ b/src/Geometry/geometryMotion/geometryMotion.cpp @@ -1,3 +1,4 @@ +#include "geometryMotion.hpp" /*------------------------------- phasicFlow --------------------------------- O C enter of O O E ngineering and @@ -21,42 +22,88 @@ Licence: template bool pFlow::geometryMotion::findMotionIndex() { - motionIndex_.clear(); - triMotionIndex_.reserve( this->surface().capacity() ); - triMotionIndex_.clear(); - - ForAll( surfI, motionComponentName_) + + if(motionComponentName().size() != numSurfaces() ) { - auto mName = motionComponentName_[surfI]; - auto mInd = motionModel_.nameToIndex(mName); - motionIndex_.push_back(mInd); - // fill motionIndex for triangles of the surface - int32 surfSize = this->surface().surfNumTriangles(surfI); - for(int32 i=0; i "<< + motionModel_.componentNames(); + return false; + } + surfMotionIndex.push_back(mInd); + + auto surfRange = subSurfaceRange(surfI); + + for(uint32 i=0; i + bool pFlow::geometryMotion::moveGeometry() + { + + uint32 iter = this->currentIter(); + real t = this->currentTime(); + real dt = this->dt(); + + auto mModel = motionModel_.getModelInterface(iter, t, dt); + + auto& pointMIndexD= pointMotionIndex_.deviceViewAll(); + auto& pointsD = points().deviceViewAll(); + + + Kokkos::parallel_for( + "geometryMotion::movePoints", + deviceRPolicyStatic(0, numPoints()), + LAMBDA_HD(uint32 i){ + auto newPos = mModel.transferPoint(pointMIndexD[i], pointsD[i], dt); + pointsD[i] = newPos; + }); + + Kokkos::fence(); + + // move the motion components + motionModel_.move(iter, t,dt); + + // end of calculations + + + return true; + } + template pFlow::geometryMotion::geometryMotion ( @@ -65,144 +112,75 @@ pFlow::geometryMotion::geometryMotion ) : geometry(control, prop), - motionModel_( - this->owner().template emplaceObject( - objectFile( - motionModelFile__, - "", - objectFile::READ_ALWAYS, - objectFile::WRITE_ALWAYS - ) - ) + motionModel_ + ( + objectFile + ( + motionModelFile__, + "", + objectFile::READ_ALWAYS, + objectFile::WRITE_ALWAYS ), + owner() + ), moveGeomTimer_("move geometry", &this->timers()) { - findMotionIndex(); -} - -template -pFlow::geometryMotion::geometryMotion -( - systemControl& control, - const property& prop, - const multiTriSurface& triSurface, - const wordVector& motionCompName, - const wordVector& propName, - const MotionModel& motionModel -) -: - geometry( - control, - prop, - triSurface, - motionCompName, - propName - ), - motionModel_( - this->owner().template emplaceObject( - objectFile( - motionModelFile__, - "", - objectFile::READ_NEVER, - objectFile::WRITE_ALWAYS - ), - motionModel - ) - ), - moveGeomTimer_("move geometry", &this->timers()) -{ - findMotionIndex(); -} - -template -pFlow::geometryMotion::geometryMotion -( - systemControl& control, - const property& prop, - const dictionary& dict, - const multiTriSurface& triSurface, - const wordVector& motionCompName, - const wordVector& propName -) -: - geometry( - control, - prop, - dict, - triSurface, - motionCompName, - propName - ), - motionModel_( - this->owner().template emplaceObject( - objectFile( - motionModelFile__, - "", - objectFile::READ_NEVER, - objectFile::WRITE_ALWAYS - ), - dict - ) - ), - moveGeomTimer_("move geometry", &this->timers()) -{ - findMotionIndex(); -} - -template -bool pFlow::geometryMotion::beforeIteration() -{ - geometry::beforeIteration(); - return true; -} - -template -bool pFlow::geometryMotion::iterate() -{ - if( motionModel_.isMoving() ) + if(!findMotionIndex()) { - moveGeomTimer_.start(); - moveGeometry(); - moveGeomTimer_.end(); + fatalExit; } - return true; } -template -bool pFlow::geometryMotion::afterIteration() +template +pFlow::geometryMotion::geometryMotion +( + systemControl &control, + const property &prop, + multiTriSurface &surf, + const wordVector &motionCompName, + const wordVector &materialName, + const dictionary &motionDict +) +: + geometry + ( + control, + prop, + surf, + motionCompName, + materialName, + motionDict + ), + motionModel_ + ( + objectFile + ( + motionModelFile__, + "", + objectFile::READ_NEVER, + objectFile::WRITE_ALWAYS + ), + motionDict, + owner() + ), + moveGeomTimer_("move geometry", &this->timers()) { - geometry::afterIteration(); - return true; -} - -template -bool pFlow::geometryMotion::moveGeometry() -{ - - real dt = this->dt(); - real t = this->currentTime(); - - auto pointMIndex= pointMotionIndex_.deviceVector(); - auto mModel = motionModel_.getModel(t); - realx3* points = triSurface_.pointsData_D(); - auto numPoints = triSurface_.numPoints(); + if(!findMotionIndex()) + { + fatalExit; + } +} - Kokkos::parallel_for( - "geometryMotion::movePoints", - numPoints, - LAMBDA_HD(int32 i){ - auto newPos = mModel.transferPoint(pointMIndex[i], points[i], dt); - points[i] = newPos; - }); - - Kokkos::fence(); - - // move the motion components - motionModel_.move(t,dt); - - // end of calculations - moveGeomTimer_.end(); - - return true; -} \ No newline at end of file + template + bool pFlow::geometryMotion::iterate() + { + if( motionModel_.isMoving() ) + { + moveGeomTimer_.start(); + moveGeometry(); + this->calculateNormals(); + moveGeomTimer_.end(); + } + return true; + } diff --git a/src/Geometry/geometryMotion/geometryMotion.hpp b/src/Geometry/geometryMotion/geometryMotion.hpp index cf47c613..157c05e0 100644 --- a/src/Geometry/geometryMotion/geometryMotion.hpp +++ b/src/Geometry/geometryMotion/geometryMotion.hpp @@ -20,9 +20,8 @@ Licence: #ifndef __geometryMotion_hpp__ #define __geometryMotion_hpp__ - +#include "vocabs.hpp" #include "geometry.hpp" -#include "VectorDuals.hpp" namespace pFlow { @@ -39,21 +38,23 @@ class geometryMotion { public: - using MotionModel = MotionModelType; + using MotionModel = MotionModelType; -protected: + using ModelComponent = typename MotionModelType::ModelComponent; + +private: /// Ref to motion model - MotionModel& motionModel_; + MotionModelType motionModel_; /// motion indext mapped on each surface - int32Vector_HD motionIndex_; + uint32Field_D surfMotionIndex_{"triMotionIndex"}; /// motion index mapped on each triangle - int8Vector_HD triMotionIndex_; + uint32Field_D triMotionIndex_ {"surfMotionIndex"}; /// motion index mapped on each point - int8Vector_HD pointMotionIndex_; + uint32Field_D pointMotionIndex_{"pointMotionIndex"}; /// timer for moveGeometry Timer moveGeomTimer_; @@ -61,32 +62,25 @@ protected: /// determine the motion index of each triangle bool findMotionIndex(); + /// Move geometry + bool moveGeometry(); + public: /// Type info - TypeInfoTemplate("geometry", MotionModel); + TypeInfoTemplate11("geometry", ModelComponent); // - Constructors geometryMotion(systemControl& control, const property& prop); - geometryMotion( - systemControl& control, + systemControl& control, const property& prop, - const multiTriSurface& triSurface, + multiTriSurface& surf, const wordVector& motionCompName, - const wordVector& propName, - const MotionModel& motionModel); - - /// Construct from components and dictionary that contains - /// motionModel - geometryMotion(systemControl& control, - const property& prop, - const dictionary& dict, - const multiTriSurface& triSurface, - const wordVector& motionCompName, - const wordVector& propName); + const wordVector& materialName, + const dictionary& motionDict); /// Add virtual constructor add_vCtor @@ -107,9 +101,9 @@ public: // - Methods /// Obtain motion model at time t - auto getModel(real t)const + auto getModel(uint32 iter, real t, real dt)const { - return motionModel_.getModel(t); + return motionModel_.getModelInterface(iter, t, dt); } /// TypeName / TypeInfo of motion model @@ -119,28 +113,21 @@ public: } /// Access to motion model index of triangles - const int8Vector_HD& triMotionIndex()const override + const uint32Field_D& triMotionIndex()const override { return triMotionIndex_; } /// Access to motion model index of points - const int8Vector_HD& pointMotionIndex()const override + const uint32Field_D& pointMotionIndex()const override { return pointMotionIndex_; } - /// Operations before each iteration - bool beforeIteration() override; - /// Iterate geometry one time step bool iterate() override ; - /// Operations after each iteration - bool afterIteration() override; - - /// Move geometry - bool moveGeometry(); + }; @@ -148,9 +135,6 @@ public: #include "geometryMotion.cpp" -#ifndef BUILD_SHARED_LIBS - #include "geometryMotionsInstantiate.cpp" -#endif #endif //__geometryMotion_hpp__ diff --git a/src/Geometry/geometryMotion/geometryMotions.cpp b/src/Geometry/geometryMotion/geometryMotions.cpp index 4eaa179a..8b1d1d55 100644 --- a/src/Geometry/geometryMotion/geometryMotions.cpp +++ b/src/Geometry/geometryMotion/geometryMotions.cpp @@ -17,9 +17,13 @@ Licence: implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -----------------------------------------------------------------------------*/ - #include "geometryMotions.hpp" -#ifdef BUILD_SHARED_LIBS -#include "geometryMotionsInstantiate.cpp" -#endif + +template class pFlow::geometryMotion; + +template class pFlow::geometryMotion; + +template class pFlow::geometryMotion; + +//template class pFlow::geometryMotion; diff --git a/src/Geometry/geometryMotion/geometryMotions.hpp b/src/Geometry/geometryMotion/geometryMotions.hpp index cd636ae6..1bb078d8 100644 --- a/src/Geometry/geometryMotion/geometryMotions.hpp +++ b/src/Geometry/geometryMotion/geometryMotions.hpp @@ -22,22 +22,23 @@ Licence: #define __geometryMotions_hpp__ #include "geometryMotion.hpp" -#include "fixedWall.hpp" +#include "stationaryWall.hpp" #include "rotatingAxisMotion.hpp" -#include "multiRotatingAxisMotion.hpp" +//#include "multiRotatingAxisMotion.hpp" #include "vibratingMotion.hpp" namespace pFlow { -typedef geometryMotion vibratingMotionGeometry; +using vibratingMotionGeometry = geometryMotion; -typedef geometryMotion rotationAxisMotionGeometry; +using rotationAxisMotionGeometry = geometryMotion; -typedef geometryMotion multiRotationAxisMotionGeometry; +using stationaryGeometry = geometryMotion; + +//typedef geometryMotion multiRotationAxisMotionGeometry; -typedef geometryMotion fixedGeometry; diff --git a/src/Geometry/geometryMotion/geometryMotionsInstantiate.cpp b/src/Geometry/geometryMotion/geometryMotionsInstantiate.cpp deleted file mode 100644 index a8ec4fd9..00000000 --- a/src/Geometry/geometryMotion/geometryMotionsInstantiate.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/*------------------------------- 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 "fixedWall.hpp" -#include "rotatingAxisMotion.hpp" -#include "multiRotatingAxisMotion.hpp" -#include "vibratingMotion.hpp" - -template class pFlow::geometryMotion; - -template class pFlow::geometryMotion; - -template class pFlow::geometryMotion; - -template class pFlow::geometryMotion; diff --git a/src/Integration/AdamsBashforth2/AdamsBashforth2.cpp b/src/Integration/AdamsBashforth2/AdamsBashforth2.cpp index 09a4eaa0..c6bb54a6 100644 --- a/src/Integration/AdamsBashforth2/AdamsBashforth2.cpp +++ b/src/Integration/AdamsBashforth2/AdamsBashforth2.cpp @@ -19,59 +19,146 @@ Licence: -----------------------------------------------------------------------------*/ #include "AdamsBashforth2.hpp" +#include "pointStructure.hpp" +#include "Time.hpp" +#include "vocabs.hpp" + +namespace pFlow +{ + +/// Range policy for integration kernel (alias) +using rpIntegration = Kokkos::RangePolicy< + DefaultExecutionSpace, + Kokkos::Schedule, + Kokkos::IndexType + >; + +bool intAllActive( + real dt, + realx3Field_D& y, + realx3PointField_D& dy, + realx3PointField_D& dy1) +{ + + auto d_dy = dy.deviceView(); + auto d_y = y.deviceView(); + auto d_dy1= dy1.deviceView(); + auto activeRng = dy1.activeRange(); + + Kokkos::parallel_for( + "AdamsBashforth2::correct", + rpIntegration (activeRng.start(), activeRng.end()), + LAMBDA_HD(uint32 i){ + d_y[i] += dt*(static_cast(1.5) * d_dy[i] - static_cast(0.5) * d_dy1[i]); + d_dy1[i] = d_dy[i]; + }); + Kokkos::fence(); + + return true; +} + +bool intScattered +( + real dt, + realx3Field_D& y, + realx3PointField_D& dy, + realx3PointField_D& dy1 +) +{ + + auto d_dy = dy.deviceView(); + auto d_y = y.deviceView(); + auto d_dy1 = dy1.deviceView(); + auto activeRng = dy1.activeRange(); + const auto& activeP = dy1.activePointsMaskDevice(); + + Kokkos::parallel_for( + "AdamsBashforth2::correct", + rpIntegration (activeRng.start(), activeRng.end()), + LAMBDA_HD(uint32 i){ + if( activeP(i)) + { + d_y[i] += dt*(static_cast(1.5) * d_dy[i] - static_cast(0.5) * d_dy1[i]); + d_dy1[i] = d_dy[i]; + } + }); + Kokkos::fence(); + + + return true; +} + +} + -//const real AB2_coef[] = { 3.0 / 2.0, 1.0 / 2.0}; pFlow::AdamsBashforth2::AdamsBashforth2 ( const word& baseName, - repository& owner, - const pointStructure& pStruct, - const word& method + pointStructure& pStruct, + const word& method, + const realx3Field_D& initialValField ) : - integration(baseName, owner, pStruct, method), - dy1_( - owner.emplaceObject( - objectFile( - groupNames(baseName,"dy1"), - "", - objectFile::READ_IF_PRESENT, - objectFile::WRITE_ALWAYS), - pStruct, - zero3)) -{ - -} + integration(baseName, pStruct, method, initialValField), + realx3PointField_D + ( + objectFile + ( + groupNames(baseName,"dy1"), + pStruct.time().integrationFolder(), + objectFile::READ_IF_PRESENT, + objectFile::WRITE_ALWAYS + ), + pStruct, + zero3, + zero3 + ) +{} bool pFlow::AdamsBashforth2::predict ( real UNUSED(dt), - realx3Vector_D& UNUSED(y), - realx3Vector_D& UNUSED(dy) + realx3PointField_D& UNUSED(y), + realx3PointField_D& UNUSED(dy) ) { - return true; } +bool pFlow::AdamsBashforth2::predict +( + real dt, + realx3Field_D &y, + realx3PointField_D &dy +) +{ + return true; +} + bool pFlow::AdamsBashforth2::correct ( real dt, - realx3Vector_D& y, - realx3Vector_D& dy + realx3PointField_D& y, + realx3PointField_D& dy ) { - if(this->pStruct().allActive()) + return correct(dt, y.field(), dy); +} + +bool pFlow::AdamsBashforth2::correct(real dt, realx3Field_D &y, realx3PointField_D &dy) +{ + auto& dy1l = dy1(); + + if(dy1l.isAllActive()) { - return intAll(dt, y, dy, this->pStruct().activeRange()); + return intAllActive(dt, y, dy, dy1l); } else { - return intRange(dt, y, dy, this->pStruct().activePointsMaskD()); + return intScattered(dt, y, dy, dy1l); } - - return true; + return false; } bool pFlow::AdamsBashforth2::setInitialVals( @@ -81,25 +168,3 @@ bool pFlow::AdamsBashforth2::setInitialVals( return true; } -bool pFlow::AdamsBashforth2::intAll( - real dt, - realx3Vector_D& y, - realx3Vector_D& dy, - range activeRng) -{ - - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); - auto d_dy1= dy1_.deviceVectorAll(); - - Kokkos::parallel_for( - "AdamsBashforth2::correct", - rpIntegration (activeRng.first, activeRng.second), - LAMBDA_HD(int32 i){ - d_y[i] += dt*(static_cast(3.0 / 2.0) * d_dy[i] - static_cast(1.0 / 2.0) * d_dy1[i]); - d_dy1[i] = d_dy[i]; - }); - Kokkos::fence(); - - return true; -} \ No newline at end of file diff --git a/src/Integration/AdamsBashforth2/AdamsBashforth2.hpp b/src/Integration/AdamsBashforth2/AdamsBashforth2.hpp index 6e2a8892..13685bab 100644 --- a/src/Integration/AdamsBashforth2/AdamsBashforth2.hpp +++ b/src/Integration/AdamsBashforth2/AdamsBashforth2.hpp @@ -36,41 +36,32 @@ namespace pFlow */ class AdamsBashforth2 : - public integration + public integration, + public realx3PointField_D { -protected: - - /// dy at t-dt - realx3PointField_D& dy1_; - - /// Range policy for integration kernel (alias) - using rpIntegration = Kokkos::RangePolicy< - DefaultExecutionSpace, - Kokkos::Schedule, - Kokkos::IndexType - >; +private: + auto& dy1() + { + return static_cast(*this); + } + public: - /// Type info - TypeInfo("AdamsBashforth2"); + /// Class info + ClassInfo("AdamsBashforth2"); // - Constructors /// Construct from components AdamsBashforth2( const word& baseName, - repository& owner, - const pointStructure& pStruct, - const word& method); - - uniquePtr clone()const override - { - return makeUnique(*this); - } + pointStructure& pStruct, + const word& method, + const realx3Field_D& initialValField); /// Destructor - virtual ~AdamsBashforth2()=default; + ~AdamsBashforth2()final = default; /// Add this to the virtual constructor table add_vCtor( @@ -80,71 +71,52 @@ public: // - Methods + /// return integration method + word method()const override + { + return "AdamsBashforth2"; + } bool predict( real UNUSED(dt), - realx3Vector_D& UNUSED(y), - realx3Vector_D& UNUSED(dy)) override; + realx3PointField_D& UNUSED(y), + realx3PointField_D& UNUSED(dy)) final; + + bool predict( + real dt, + realx3Field_D& y, + realx3PointField_D& dy) final; bool correct( real dt, - realx3Vector_D& y, - realx3Vector_D& dy) override; + realx3PointField_D& y, + realx3PointField_D& dy) final; + + bool correct( + real dt, + realx3Field_D& y, + realx3PointField_D& dy) final; + + /*bool hearChanges + ( + real t, + real dt, + uint32 iter, + const message& msg, + const anyList& varList + ) override;*/ bool setInitialVals( const int32IndexContainer& newIndices, - const realx3Vector& y) override; + const realx3Vector& y) final; - bool needSetInitialVals()const override + bool needSetInitialVals()const final { return false; } - - /// Integrate on all points in the active range - bool intAll( - real dt, - realx3Vector_D& y, - realx3Vector_D& dy, - range activeRng); - - /// Integrate on active points in the active range - template - bool intRange( - real dt, - realx3Vector_D& y, - realx3Vector_D& dy, - activeFunctor activeP ); }; -template -bool pFlow::AdamsBashforth2::intRange( - real dt, - realx3Vector_D& y, - realx3Vector_D& dy, - activeFunctor activeP ) -{ - - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); - auto d_dy1= dy1_.deviceVectorAll(); - auto activeRng = activeP.activeRange(); - - Kokkos::parallel_for( - "AdamsBashforth2::correct", - rpIntegration (activeRng.first, activeRng.second), - LAMBDA_HD(int32 i){ - if( activeP(i)) - { - d_y[i] += dt*(static_cast(3.0 / 2.0) * d_dy[i] - static_cast(1.0 / 2.0) * d_dy1[i]); - d_dy1[i] = d_dy[i]; - } - }); - Kokkos::fence(); - - - return true; -} } // pFlow diff --git a/src/Integration/AdamsBashforth3/AdamsBashforth3.cpp b/src/Integration/AdamsBashforth3/AdamsBashforth3.cpp index 040a9e40..f8ec6b5a 100644 --- a/src/Integration/AdamsBashforth3/AdamsBashforth3.cpp +++ b/src/Integration/AdamsBashforth3/AdamsBashforth3.cpp @@ -89,9 +89,9 @@ bool pFlow::AdamsBashforth3::intAll( realx3Vector_D& dy, range activeRng) { - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); - auto d_history = history_.deviceVectorAll(); + auto d_dy = dy.deviceViewAll(); + auto d_y = y.deviceViewAll(); + auto d_history = history_.deviceViewAll(); Kokkos::parallel_for( "AdamsBashforth3::correct", diff --git a/src/Integration/AdamsBashforth3/AdamsBashforth3.hpp b/src/Integration/AdamsBashforth3/AdamsBashforth3.hpp index 6bd47b11..279fdcda 100644 --- a/src/Integration/AdamsBashforth3/AdamsBashforth3.hpp +++ b/src/Integration/AdamsBashforth3/AdamsBashforth3.hpp @@ -160,9 +160,9 @@ bool pFlow::AdamsBashforth3::intRange( realx3Vector_D& dy, activeFunctor activeP ) { - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); - auto d_history = history_.deviceVectorAll(); + auto d_dy = dy.deviceViewAll(); + auto d_y = y.deviceViewAll(); + auto d_history = history_.deviceViewAll(); auto activeRng = activeP.activeRange(); Kokkos::parallel_for( diff --git a/src/Integration/AdamsBashforth4/AdamsBashforth4.cpp b/src/Integration/AdamsBashforth4/AdamsBashforth4.cpp index 547de93f..23bad29b 100644 --- a/src/Integration/AdamsBashforth4/AdamsBashforth4.cpp +++ b/src/Integration/AdamsBashforth4/AdamsBashforth4.cpp @@ -89,9 +89,9 @@ bool pFlow::AdamsBashforth4::intAll( realx3Vector_D& dy, range activeRng) { - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); - auto d_history = history_.deviceVectorAll(); + auto d_dy = dy.deviceViewAll(); + auto d_y = y.deviceViewAll(); + auto d_history = history_.deviceViewAll(); Kokkos::parallel_for( "AdamsBashforth4::correct", diff --git a/src/Integration/AdamsBashforth4/AdamsBashforth4.hpp b/src/Integration/AdamsBashforth4/AdamsBashforth4.hpp index 4f4a2914..cf1f50d8 100644 --- a/src/Integration/AdamsBashforth4/AdamsBashforth4.hpp +++ b/src/Integration/AdamsBashforth4/AdamsBashforth4.hpp @@ -165,9 +165,9 @@ bool pFlow::AdamsBashforth4::intRange( realx3Vector_D& dy, activeFunctor activeP ) { - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); - auto d_history = history_.deviceVectorAll(); + auto d_dy = dy.deviceViewAll(); + auto d_y = y.deviceViewAll(); + auto d_history = history_.deviceViewAll(); auto activeRng = activeP.activeRange(); Kokkos::parallel_for( diff --git a/src/Integration/AdamsBashforth5/AdamsBashforth5.cpp b/src/Integration/AdamsBashforth5/AdamsBashforth5.cpp index 580f0c06..7b87a4a3 100644 --- a/src/Integration/AdamsBashforth5/AdamsBashforth5.cpp +++ b/src/Integration/AdamsBashforth5/AdamsBashforth5.cpp @@ -89,9 +89,9 @@ bool pFlow::AdamsBashforth5::intAll( realx3Vector_D& dy, range activeRng) { - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); - auto d_history = history_.deviceVectorAll(); + auto d_dy = dy.deviceViewAll(); + auto d_y = y.deviceViewAll(); + auto d_history = history_.deviceViewAll(); Kokkos::parallel_for( "AdamsBashforth5::correct", diff --git a/src/Integration/AdamsBashforth5/AdamsBashforth5.hpp b/src/Integration/AdamsBashforth5/AdamsBashforth5.hpp index 99261588..16b55927 100644 --- a/src/Integration/AdamsBashforth5/AdamsBashforth5.hpp +++ b/src/Integration/AdamsBashforth5/AdamsBashforth5.hpp @@ -165,9 +165,9 @@ bool pFlow::AdamsBashforth5::intRange( realx3Vector_D& dy, activeFunctor activeP ) { - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); - auto d_history = history_.deviceVectorAll(); + auto d_dy = dy.deviceViewAll(); + auto d_y = y.deviceViewAll(); + auto d_history = history_.deviceViewAll(); auto activeRng = activeP.activeRange(); Kokkos::parallel_for( diff --git a/src/Integration/AdamsMoulton3/AdamsMoulton3.cpp b/src/Integration/AdamsMoulton3/AdamsMoulton3.cpp index cb819c7c..4fb030bf 100644 --- a/src/Integration/AdamsMoulton3/AdamsMoulton3.cpp +++ b/src/Integration/AdamsMoulton3/AdamsMoulton3.cpp @@ -124,11 +124,11 @@ bool pFlow::AdamsMoulton3::predictAll( range activeRng) { - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); - auto d_y0 = y0_.deviceVectorAll(); - auto d_dy0 = dy0_.deviceVectorAll(); - auto d_dy1= dy1_.deviceVectorAll(); + auto d_dy = dy.deviceViewAll(); + auto d_y = y.deviceViewAll(); + auto d_y0 = y0_.deviceViewAll(); + auto d_dy0 = dy0_.deviceViewAll(); + auto d_dy1= dy1_.deviceViewAll(); Kokkos::parallel_for( "AdamsMoulton3::predict", @@ -150,12 +150,12 @@ bool pFlow::AdamsMoulton3::intAll( range activeRng) { - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); + auto d_dy = dy.deviceViewAll(); + auto d_y = y.deviceViewAll(); - auto d_dy0 = dy0_.deviceVectorAll(); - auto d_y0 = y0_.deviceVectorAll(); - auto d_dy1 = dy1_.deviceVectorAll(); + auto d_dy0 = dy0_.deviceViewAll(); + auto d_y0 = y0_.deviceViewAll(); + auto d_dy1 = dy1_.deviceViewAll(); Kokkos::parallel_for( "AdamsMoulton3::correct", diff --git a/src/Integration/AdamsMoulton3/AdamsMoulton3.hpp b/src/Integration/AdamsMoulton3/AdamsMoulton3.hpp index 349d62b2..3193a819 100644 --- a/src/Integration/AdamsMoulton3/AdamsMoulton3.hpp +++ b/src/Integration/AdamsMoulton3/AdamsMoulton3.hpp @@ -144,11 +144,11 @@ bool AdamsMoulton3::predictRange( realx3Vector_D& dy, activeFunctor activeP) { - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); - auto d_y0 = y0_.deviceVectorAll(); - auto d_dy0 = dy0_.deviceVectorAll(); - auto d_dy1= dy1_.deviceVectorAll(); + auto d_dy = dy.deviceViewAll(); + auto d_y = y.deviceViewAll(); + auto d_y0 = y0_.deviceViewAll(); + auto d_dy0 = dy0_.deviceViewAll(); + auto d_dy1= dy1_.deviceViewAll(); auto activeRng = activeP.activeRange(); @@ -182,12 +182,12 @@ bool pFlow::AdamsMoulton3::intRange( activeFunctor activeP) { - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); + auto d_dy = dy.deviceViewAll(); + auto d_y = y.deviceViewAll(); - auto d_dy0 = dy0_.deviceVectorAll(); - auto d_y0 = y0_.deviceVectorAll(); - auto d_dy1 = dy1_.deviceVectorAll(); + auto d_dy0 = dy0_.deviceViewAll(); + auto d_y0 = y0_.deviceViewAll(); + auto d_dy1 = dy1_.deviceViewAll(); auto activeRng = activeP.activeRange(); diff --git a/src/Integration/AdamsMoulton4/AdamsMoulton4.cpp b/src/Integration/AdamsMoulton4/AdamsMoulton4.cpp index ec735ac8..3cdbbc8f 100644 --- a/src/Integration/AdamsMoulton4/AdamsMoulton4.cpp +++ b/src/Integration/AdamsMoulton4/AdamsMoulton4.cpp @@ -135,13 +135,13 @@ bool pFlow::AdamsMoulton4::predictAll( range activeRng) { - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); + auto d_dy = dy.deviceViewAll(); + auto d_y = y.deviceViewAll(); - auto d_y0 = y0_.deviceVectorAll(); - auto d_dy0 = dy0_.deviceVectorAll(); - auto d_dy1 = dy1_.deviceVectorAll(); - auto d_dy2 = dy2_.deviceVectorAll(); + auto d_y0 = y0_.deviceViewAll(); + auto d_dy0 = dy0_.deviceViewAll(); + auto d_dy1 = dy1_.deviceViewAll(); + auto d_dy2 = dy2_.deviceViewAll(); Kokkos::parallel_for( "AdamsMoulton4::predict", @@ -165,13 +165,13 @@ bool pFlow::AdamsMoulton4::intAll( range activeRng) { - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); + auto d_dy = dy.deviceViewAll(); + auto d_y = y.deviceViewAll(); - auto d_dy0 = dy0_.deviceVectorAll(); - auto d_y0 = y0_.deviceVectorAll(); - auto d_dy1 = dy1_.deviceVectorAll(); - auto d_dy2 = dy2_.deviceVectorAll(); + auto d_dy0 = dy0_.deviceViewAll(); + auto d_y0 = y0_.deviceViewAll(); + auto d_dy1 = dy1_.deviceViewAll(); + auto d_dy2 = dy2_.deviceViewAll(); Kokkos::parallel_for( "AdamsMoulton4::correct", diff --git a/src/Integration/AdamsMoulton4/AdamsMoulton4.hpp b/src/Integration/AdamsMoulton4/AdamsMoulton4.hpp index c0da0f62..3950798a 100644 --- a/src/Integration/AdamsMoulton4/AdamsMoulton4.hpp +++ b/src/Integration/AdamsMoulton4/AdamsMoulton4.hpp @@ -147,13 +147,13 @@ bool AdamsMoulton4::predictRange( realx3Vector_D& dy, activeFunctor activeP ) { - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); + auto d_dy = dy.deviceViewAll(); + auto d_y = y.deviceViewAll(); - auto d_y0 = y0_.deviceVectorAll(); - auto d_dy0 = dy0_.deviceVectorAll(); - auto d_dy1 = dy1_.deviceVectorAll(); - auto d_dy2 = dy2_.deviceVectorAll(); + auto d_y0 = y0_.deviceViewAll(); + auto d_dy0 = dy0_.deviceViewAll(); + auto d_dy1 = dy1_.deviceViewAll(); + auto d_dy2 = dy2_.deviceViewAll(); auto activeRng = activeP.activeRange(); @@ -185,13 +185,13 @@ bool pFlow::AdamsMoulton4::intRange( activeFunctor activeP ) { - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); + auto d_dy = dy.deviceViewAll(); + auto d_y = y.deviceViewAll(); - auto d_dy0 = dy0_.deviceVectorAll(); - auto d_y0 = y0_.deviceVectorAll(); - auto d_dy1 = dy1_.deviceVectorAll(); - auto d_dy2 = dy2_.deviceVectorAll(); + auto d_dy0 = dy0_.deviceViewAll(); + auto d_y0 = y0_.deviceViewAll(); + auto d_dy1 = dy1_.deviceViewAll(); + auto d_dy2 = dy2_.deviceViewAll(); auto activeRng = activeP.activeRange(); diff --git a/src/Integration/AdamsMoulton5/AdamsMoulton5.cpp b/src/Integration/AdamsMoulton5/AdamsMoulton5.cpp index c3f62f18..37629649 100644 --- a/src/Integration/AdamsMoulton5/AdamsMoulton5.cpp +++ b/src/Integration/AdamsMoulton5/AdamsMoulton5.cpp @@ -145,14 +145,14 @@ bool pFlow::AdamsMoulton5::predictAll( range activeRng) { - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); + auto d_dy = dy.deviceViewAll(); + auto d_y = y.deviceViewAll(); - auto d_y0 = y0_.deviceVectorAll(); - auto d_dy0 = dy0_.deviceVectorAll(); - auto d_dy1 = dy1_.deviceVectorAll(); - auto d_dy2 = dy2_.deviceVectorAll(); - auto d_dy3 = dy3_.deviceVectorAll(); + auto d_y0 = y0_.deviceViewAll(); + auto d_dy0 = dy0_.deviceViewAll(); + auto d_dy1 = dy1_.deviceViewAll(); + auto d_dy2 = dy2_.deviceViewAll(); + auto d_dy3 = dy3_.deviceViewAll(); Kokkos::parallel_for( "AdamsMoulton5::predict", @@ -178,14 +178,14 @@ bool pFlow::AdamsMoulton5::intAll( range activeRng) { - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); + auto d_dy = dy.deviceViewAll(); + auto d_y = y.deviceViewAll(); - auto d_dy0 = dy0_.deviceVectorAll(); - auto d_y0 = y0_.deviceVectorAll(); - auto d_dy1 = dy1_.deviceVectorAll(); - auto d_dy2 = dy2_.deviceVectorAll(); - auto d_dy3 = dy3_.deviceVectorAll(); + auto d_dy0 = dy0_.deviceViewAll(); + auto d_y0 = y0_.deviceViewAll(); + auto d_dy1 = dy1_.deviceViewAll(); + auto d_dy2 = dy2_.deviceViewAll(); + auto d_dy3 = dy3_.deviceViewAll(); Kokkos::parallel_for( "AdamsMoulton5::correct", diff --git a/src/Integration/AdamsMoulton5/AdamsMoulton5.hpp b/src/Integration/AdamsMoulton5/AdamsMoulton5.hpp index 2e381d4a..451ff81f 100644 --- a/src/Integration/AdamsMoulton5/AdamsMoulton5.hpp +++ b/src/Integration/AdamsMoulton5/AdamsMoulton5.hpp @@ -150,14 +150,14 @@ bool AdamsMoulton5::predictRange( realx3Vector_D& dy, activeFunctor activeP ) { - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); + auto d_dy = dy.deviceViewAll(); + auto d_y = y.deviceViewAll(); - auto d_y0 = y0_.deviceVectorAll(); - auto d_dy0 = dy0_.deviceVectorAll(); - auto d_dy1 = dy1_.deviceVectorAll(); - auto d_dy2 = dy2_.deviceVectorAll(); - auto d_dy3 = dy3_.deviceVectorAll(); + auto d_y0 = y0_.deviceViewAll(); + auto d_dy0 = dy0_.deviceViewAll(); + auto d_dy1 = dy1_.deviceViewAll(); + auto d_dy2 = dy2_.deviceViewAll(); + auto d_dy3 = dy3_.deviceViewAll(); auto activeRng = activeP.activeRange(); @@ -189,14 +189,14 @@ bool pFlow::AdamsMoulton5::intRange( activeFunctor activeP ) { - auto d_dy = dy.deviceVectorAll(); - auto d_y = y.deviceVectorAll(); + auto d_dy = dy.deviceViewAll(); + auto d_y = y.deviceViewAll(); - auto d_dy0 = dy0_.deviceVectorAll(); - auto d_y0 = y0_.deviceVectorAll(); - auto d_dy1 = dy1_.deviceVectorAll(); - auto d_dy2 = dy2_.deviceVectorAll(); - auto d_dy3 = dy3_.deviceVectorAll(); + auto d_dy0 = dy0_.deviceViewAll(); + auto d_y0 = y0_.deviceViewAll(); + auto d_dy1 = dy1_.deviceViewAll(); + auto d_dy2 = dy2_.deviceViewAll(); + auto d_dy3 = dy3_.deviceViewAll(); auto activeRng = activeP.activeRange(); diff --git a/src/Integration/CMakeLists.txt b/src/Integration/CMakeLists.txt index f3a03112..fca650cd 100644 --- a/src/Integration/CMakeLists.txt +++ b/src/Integration/CMakeLists.txt @@ -1,13 +1,13 @@ list(APPEND SourceFiles integration/integration.cpp -AdamsBashforth5/AdamsBashforth5.cpp -AdamsBashforth4/AdamsBashforth4.cpp -AdamsBashforth3/AdamsBashforth3.cpp AdamsBashforth2/AdamsBashforth2.cpp -AdamsMoulton3/AdamsMoulton3.cpp -AdamsMoulton4/AdamsMoulton4.cpp -AdamsMoulton5/AdamsMoulton5.cpp +#AdamsBashforth5/AdamsBashforth5.cpp +#AdamsBashforth4/AdamsBashforth4.cpp +#AdamsBashforth3/AdamsBashforth3.cpp +#AdamsMoulton3/AdamsMoulton3.cpp +#AdamsMoulton4/AdamsMoulton4.cpp +#AdamsMoulton5/AdamsMoulton5.cpp ) set(link_libs Kokkos::kokkos phasicFlow) diff --git a/src/Integration/integration/integration.cpp b/src/Integration/integration/integration.cpp index 6e48ddaf..f3126e1e 100644 --- a/src/Integration/integration/integration.cpp +++ b/src/Integration/integration/integration.cpp @@ -19,33 +19,35 @@ Licence: -----------------------------------------------------------------------------*/ #include "integration.hpp" +#include "pointStructure.hpp" +#include "repository.hpp" pFlow::integration::integration ( const word& baseName, - repository& owner, - const pointStructure& pStruct, - const word& method + pointStructure& pStruct, + const word&, + const realx3Field_D& ) : - owner_(owner), - baseName_(baseName), - pStruct_(pStruct) -{ - CONSUME_PARAM(method); -} + owner_(*pStruct.owner()), + pStruct_(pStruct), + baseName_(baseName) +{} pFlow::uniquePtr - pFlow::integration::create( + pFlow::integration::create +( const word& baseName, - repository& owner, - const pointStructure& pStruct, - const word& method) + pointStructure& pStruct, + const word& method, + const realx3Field_D& initialValField +) { if( wordvCtorSelector_.search(method) ) { - return wordvCtorSelector_[method] (baseName, owner, pStruct, method); + return wordvCtorSelector_[method] (baseName, pStruct, method, initialValField); } else { diff --git a/src/Integration/integration/integration.hpp b/src/Integration/integration/integration.hpp index 3cca58c2..4769c3ec 100644 --- a/src/Integration/integration/integration.hpp +++ b/src/Integration/integration/integration.hpp @@ -23,14 +23,16 @@ Licence: #include "virtualConstructor.hpp" -#include "Vectors.hpp" -#include "pointStructure.hpp" -#include "repository.hpp" +#include "pointFields.hpp" namespace pFlow { +// - Forward +class repository; +class pointStructure; + /** * Base class for integrating the first order ODE (IVP) * @@ -48,19 +50,19 @@ namespace pFlow */ class integration { -protected: +private: // - Protected data members /// The owner repository that all fields are storred in repository& owner_; - /// The base name for integration - const word baseName_; - /// A reference to pointStructure const pointStructure& pStruct_; + /// The base name for integration + const word baseName_; + public: /// Type info @@ -72,9 +74,9 @@ public: /// Construct from components integration( const word& baseName, - repository& owner, - const pointStructure& pStruct, - const word& method); + pointStructure& pStruct, + const word& method, + const realx3Field_D& initialValField); /// Copy constructor integration(const integration&) = default; @@ -88,22 +90,22 @@ public: /// Move assignment integration& operator = (integration&&) = default; - /// Polymorphic copy/cloning - virtual - uniquePtr clone()const=0; - /// Destructor virtual ~integration()=default; /// Add a virtual constructor - create_vCtor( + create_vCtor + ( integration, word, - (const word& baseName, - repository& owner, - const pointStructure& pStruct, - const word& method), - (baseName, owner, pStruct, method) ); + ( + const word& baseName, + pointStructure& pStruct, + const word& method, + const realx3Field_D& initialValField + ), + (baseName, pStruct, method, initialValField) + ); // - Methods @@ -129,13 +131,23 @@ public: return owner_; } + /// return integration method + virtual + word method()const = 0 ; + /// Prediction step in integration virtual - bool predict(real dt, realx3Vector_D& y, realx3Vector_D& dy) = 0; + bool predict(real dt, realx3PointField_D& y, realx3PointField_D& dy) = 0; + + virtual + bool predict(real dt, realx3Field_D& y, realx3PointField_D& dy) = 0; /// Correction/main integration step virtual - bool correct(real dt, realx3Vector_D& y, realx3Vector_D& dy) = 0; + bool correct(real dt, realx3PointField_D& y, realx3PointField_D& dy) = 0; + + virtual + bool correct(real dt, realx3Field_D& y, realx3PointField_D& dy) = 0; /// Set the initial values for new indices virtual @@ -152,9 +164,9 @@ public: static uniquePtr create( const word& baseName, - repository& owner, - const pointStructure& pStruct, - const word& method); + pointStructure& pStruct, + const word& method, + const realx3Field_D& initialValField); }; // integration diff --git a/src/Interaction/CMakeLists.txt b/src/Interaction/CMakeLists.txt index 25d43014..1427433f 100644 --- a/src/Interaction/CMakeLists.txt +++ b/src/Interaction/CMakeLists.txt @@ -1,9 +1,25 @@ set(SourceFiles +contactSearch/methods/cellBased/NBS/mapperNBS.cpp +contactSearch/methods/cellBased/NBS/mapperNBSKernels.cpp +contactSearch/methods/cellBased/NBS/NBSLevel0.cpp +contactSearch/methods/cellBased/NBS/NBS.cpp +contactSearch/methods/cellBased/NBS/cellsWallLevel0.cpp + +contactSearch/boundaries/boundaryContactSearch/boundaryContactSearch.cpp +contactSearch/boundaries/periodicBoundaryContactSearch/ppwBndryContactSearchKernels.cpp +contactSearch/boundaries/periodicBoundaryContactSearch/ppwBndryContactSearch.cpp +contactSearch/boundaries/periodicBoundaryContactSearch/wallBoundaryContactSearch.cpp +contactSearch/boundaries/periodicBoundaryContactSearch/periodicBoundaryContactSearch.cpp +contactSearch/boundaries/boundaryContactSearchList.cpp + contactSearch/contactSearch/contactSearch.cpp contactSearch/ContactSearch/ContactSearchs.cpp + interaction/interaction.cpp -sphereInteraction/sphereInteractions.cpp +sphereInteraction/sphereInteractionsLinearModels.cpp +sphereInteraction/sphereInteractionsNonLinearModels.cpp +sphereInteraction/sphereInteractionsNonLinearModModels.cpp ) set(link_libs Kokkos::kokkos phasicFlow Property Particles Geometry) diff --git a/src/Interaction/Models/contactForce/linearCF.hpp b/src/Interaction/Models/contactForce/linearCF.hpp index 5ef6da3e..88bf2108 100644 --- a/src/Interaction/Models/contactForce/linearCF.hpp +++ b/src/Interaction/Models/contactForce/linearCF.hpp @@ -133,8 +133,9 @@ protected: return false; } - realVector etha_n(nElem); - realVector etha_t(nElem); + realVector etha_n("etha_n", nElem); + realVector etha_t("etha_t", nElem); + ForAll(i , kn) { etha_n[i] = -2.0*log(en[i])*sqrt(kn[i])/ @@ -144,7 +145,7 @@ protected: sqrt(pow(log(et[i]),2.0)+ pow(Pi,2.0)); } - Vector prop(nElem); + Vector prop("prop", nElem); ForAll(i,kn) { prop[i] = {kn[i], kt[i], etha_n[i], etha_t[i], mu[i]}; @@ -219,10 +220,10 @@ public: void contactForce ( const real dt, - const int32 i, - const int32 j, - const int32 propId_i, - const int32 propId_j, + const uint32 i, + const uint32 j, + const uint32 propId_i, + const uint32 propId_j, const real Ri, const real Rj, const real ovrlp_n, diff --git a/src/Interaction/Models/contactForce/nonLinearCF.hpp b/src/Interaction/Models/contactForce/nonLinearCF.hpp index b9f42d69..3ba1c5c5 100644 --- a/src/Interaction/Models/contactForce/nonLinearCF.hpp +++ b/src/Interaction/Models/contactForce/nonLinearCF.hpp @@ -121,7 +121,7 @@ protected: } - realVector etha_n(nElem); + realVector etha_n("etha_n",nElem); ForAll(i , en) { @@ -137,7 +137,7 @@ protected: } - Vector prop(nElem); + Vector prop("prop",nElem); ForAll(i,Yeff) { prop[i] = {Yeff[i], Geff[i], etha_n[i], mu[i]}; @@ -214,10 +214,10 @@ public: void contactForce ( const real dt, - const int32 i, - const int32 j, - const int32 propId_i, - const int32 propId_j, + const uint32 i, + const uint32 j, + const uint32 propId_i, + const uint32 propId_j, const real Ri, const real Rj, const real ovrlp_n, diff --git a/src/Interaction/Models/contactForce/nonLinearMod.hpp b/src/Interaction/Models/contactForce/nonLinearMod.hpp index 3bfbd29b..9a771970 100644 --- a/src/Interaction/Models/contactForce/nonLinearMod.hpp +++ b/src/Interaction/Models/contactForce/nonLinearMod.hpp @@ -121,7 +121,7 @@ protected: } - Vector prop(nElem); + Vector prop("prop",nElem); ForAll(i,Yeff) { prop[i] = {Yeff[i], Geff[i], etha_n[i], mu[i]}; @@ -198,10 +198,10 @@ public: void contactForce ( const real dt, - const int32 i, - const int32 j, - const int32 propId_i, - const int32 propId_j, + const uint32 i, + const uint32 j, + const uint32 propId_i, + const uint32 propId_j, const real Ri, const real Rj, const real ovrlp_n, diff --git a/src/Interaction/Models/rolling/normalRolling.hpp b/src/Interaction/Models/rolling/normalRolling.hpp index de850e3c..80b8e321 100644 --- a/src/Interaction/Models/rolling/normalRolling.hpp +++ b/src/Interaction/Models/rolling/normalRolling.hpp @@ -76,10 +76,10 @@ public: void rollingFriction ( const real dt, - const int32 i, - const int32 j, - const int32 propId_i, - const int32 propId_j, + const uint32 i, + const uint32 j, + const uint32 propId_i, + const uint32 propId_j, const real Ri, const real Rj, const realx3& wi, diff --git a/src/Interaction/contactLists/sortedContactList.hpp b/src/Interaction/contactLists/sortedContactList.hpp index 45c8e4b0..73f0ce4b 100644 --- a/src/Interaction/contactLists/sortedContactList.hpp +++ b/src/Interaction/contactLists/sortedContactList.hpp @@ -53,7 +53,7 @@ protected: ViewType1D values_; - int32 size0_ = 0; + uint32 size0_ = 0; ViewType1D sortedPairs0_; @@ -73,7 +73,7 @@ protected: using rpReFillPairs = Kokkos::RangePolicy< ExecutionSpace, Kokkos::Schedule, - Kokkos::IndexType, + Kokkos::IndexType, TagReFillPairs>; public: @@ -81,7 +81,7 @@ public: TypeInfoNV("sortedContactList"); - sortedContactList(int32 initialSize =1) + explicit sortedContactList(uint32 initialSize =1) : SortedPairs(initialSize), values_("values", SortedPairs::capacity()), @@ -114,31 +114,31 @@ public: } INLINE_FUNCTION_HD - ValueType getValue(int32 idx)const + ValueType getValue(uint32 idx)const { return values_[idx]; } INLINE_FUNCTION_HD - void setValue(int32 idx, const ValueType& val)const + void setValue(uint32 idx, const ValueType& val)const { values_[idx] = val; } INLINE_FUNCTION_HD - void operator()(TagReFillPairs, int32 idx)const + void operator()(TagReFillPairs, uint32 idx)const { - auto searchLen = max(size0_/1000,10); - auto start = max(0,idx-searchLen); - auto end = min(size0_,idx+searchLen); + uint32 searchLen = max(size0_/1000u,10u); + uint32 start = idx-min(searchLen,idx); + uint32 end = min(size0_,idx+searchLen); auto newPair = this->sortedPairs_[idx]; if( auto idx0 = binarySearch( sortedPairs0_, start, end, newPair); - idx0>=0) + idx0!=-1) { values_[idx] = values0_[idx0]; } @@ -147,7 +147,7 @@ public: start, end, newPair); - idx0>=0) + idx0!=-1) { values_[idx] = values0_[idx0]; diff --git a/src/Interaction/contactLists/sortedPairs.hpp b/src/Interaction/contactLists/sortedPairs.hpp index d8b74a50..12593810 100644 --- a/src/Interaction/contactLists/sortedPairs.hpp +++ b/src/Interaction/contactLists/sortedPairs.hpp @@ -52,24 +52,24 @@ public: { using PairType = typename sortedPairs::PairType; - int32 size_; + uint32 size_; ViewType1D sortedParis_; INLINE_FUNCTION_HD - int32 size()const { return size_; } + uint32 size()const { return size_; } INLINE_FUNCTION_HD - int32 loopCount()const { return size_; } + uint32 loopCount()const { return size_; } INLINE_FUNCTION_HD - bool isValid(int32 i)const { return i flags_; + ViewType1D flags_; ViewType1D sortedPairs_; using rpFillFlag = Kokkos::RangePolicy< ExecutionSpace, Kokkos::Schedule, - Kokkos::IndexType, + Kokkos::IndexType, TagFillFlag >; using rpFillPairs = Kokkos::RangePolicy< ExecutionSpace, Kokkos::Schedule, - Kokkos::IndexType, + Kokkos::IndexType, TagFillPairs>; public: @@ -110,7 +110,7 @@ public: // constructors - sortedPairs(int32 initialSize =1) + explicit sortedPairs(uint32 initialSize =1) : UnsortedPairs(initialSize), flags_("flags_",UnsortedPairs::capacity()+1), @@ -134,7 +134,7 @@ public: // return the pair at index idx // perform no check for size and existance INLINE_FUNCTION_HD - PairType getPair(int32 idx)const + PairType getPair(uint32 idx)const { return sortedPairs_[idx]; } @@ -142,7 +142,7 @@ public: // - Device/host call // return the pair at index idx INLINE_FUNCTION_HD - bool getPair(int32 idx, PairType& p)const + bool getPair(uint32 idx, PairType& p)const { if(isValid(idx)) { @@ -156,7 +156,7 @@ public: } INLINE_FUNCTION_HD - bool isValid(int32 idx)const + bool isValid(uint32 idx)const { return idx < size_; } @@ -164,12 +164,12 @@ public: //use this when the value of size_ is updated INLINE_FUNCTION_H - int32 size()const + uint32 size()const { return size_; } - int32 loopCount()const + uint32 loopCount()const { return size_; } @@ -189,7 +189,7 @@ public: void prepareSorted() { // first check the size of flags_ - int32 capacity = UnsortedPairs::capacity(); + uint32 capacity = UnsortedPairs::capacity(); if( capacity+1 > flags_.size() ) { @@ -218,7 +218,7 @@ public: if( size_>sortedPairs_.size() ) { // get more space to prevent reallocations in next iterations - int32 len = size_*1.1+1; + uint32 len = size_*1.1+1; reallocNoInit(sortedPairs_, len); } @@ -235,7 +235,7 @@ public: } INLINE_FUNCTION_HD - void operator()(TagFillFlag, int32 i)const + void operator()(TagFillFlag, uint32 i)const { if(this->container_.valid_at(i) ) flags_[i] = 1; @@ -244,7 +244,7 @@ public: } INLINE_FUNCTION_HD - void operator()(TagFillPairs, int32 i)const + void operator()(TagFillPairs, uint32 i)const { auto fi = flags_[i]; if(fi!=flags_[i+1]) diff --git a/src/Interaction/contactLists/unsortedContactList.hpp b/src/Interaction/contactLists/unsortedContactList.hpp index f2200fd9..5922c4dc 100644 --- a/src/Interaction/contactLists/unsortedContactList.hpp +++ b/src/Interaction/contactLists/unsortedContactList.hpp @@ -17,10 +17,11 @@ Licence: implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -----------------------------------------------------------------------------*/ - #ifndef __unsortedContactList_hpp__ #define __unsortedContactList_hpp__ +#include "unsortedPairs.hpp" + namespace pFlow { @@ -72,7 +73,7 @@ protected: using rpFillPairs = Kokkos::RangePolicy< ExecutionSpace, Kokkos::Schedule, - Kokkos::IndexType, + Kokkos::IndexType, TagReFillPairs>; @@ -80,7 +81,7 @@ public: TypeInfoNV("unsortedContactList"); - unsortedContactList(int32 capacity=1) + explicit unsortedContactList(uint32 capacity=1) : UnsortedPairs(capacity), values_("values", UnsortedPairs::capacity()), @@ -122,7 +123,7 @@ public: INLINE_FUNCTION_HD bool getValue(const PairType& p, ValueType& val)const { - if(auto idx = this->find(p); idx>=0) + if(auto idx = this->find(p); idx!=-1) { val = getValue(idx); return true; @@ -131,7 +132,7 @@ public: } INLINE_FUNCTION_HD - void setValue(int32 idx, const ValueType& val)const + void setValue(uint32 idx, const ValueType& val)const { values_[idx] = val; } @@ -139,7 +140,7 @@ public: INLINE_FUNCTION_HD bool setValue(const PairType& p, const ValueType& val)const { - if(auto idx = this->find(p); idx>=0) + if(uint32 idx = this->find(p); idx!=-1) { setValue(idx, val); return true;; @@ -148,13 +149,13 @@ public: } INLINE_FUNCTION_HD - void operator()(TagReFillPairs, int32 idx)const + void operator()(TagReFillPairs, uint32 idx)const { if( this->isValid(idx) ) { - if( int32 idx0 = + if( uint32 idx0 = container0_.find(this->getPair(idx)); - idx0>=0 ) + idx0!=-1 ) { values_[idx] = values0_[idx0]; } diff --git a/src/Interaction/contactLists/unsortedPairs.hpp b/src/Interaction/contactLists/unsortedPairs.hpp index e9434751..fd4f117d 100644 --- a/src/Interaction/contactLists/unsortedPairs.hpp +++ b/src/Interaction/contactLists/unsortedPairs.hpp @@ -41,7 +41,7 @@ public: using memory_space = typename ExecutionSpace::memory_space; - using PairType = kPair; + using PairType = Pair; using ContainerType = unorderedSet; @@ -52,19 +52,19 @@ public: ContainerType Container_; INLINE_FUNCTION_HD - int32 size()const { return Container_.size(); } + uint32 size()const { return Container_.size(); } INLINE_FUNCTION_HD - int32 loopCount()const { return Container_.capacity(); } + uint32 loopCount()const { return Container_.capacity(); } INLINE_FUNCTION_HD - bool isValid(int32 idx)const { return Container_.valid_at(idx); } + bool isValid(uint32 idx)const { return Container_.valid_at(idx); } INLINE_FUNCTION_HD - PairType getPair(int idx)const { return Container_.key_at(idx); } + PairType getPair(uint32 idx)const { return Container_.key_at(idx); } INLINE_FUNCTION_HD - bool getPair(int32 idx, PairType& pair)const { + bool getPair(uint32 idx, PairType& pair)const { if(Container_.valid_at(idx)) { pair = Container_.key_at(idx); return true; @@ -84,7 +84,7 @@ public: TypeInfoNV("unsorderedPairs"); // constructor - unsortedPairs(int32 capacity=1) + explicit unsortedPairs(uint32 capacity=1) : container_(capacity) // the minimum capacity would be 128 {} @@ -102,7 +102,7 @@ public: // - Device call INLINE_FUNCTION_HD - int32 insert(idType i, idType j)const + uint32 insert(idType i, idType j)const { if(auto insertResult = container_.insert(PairType(i,j)); insertResult.failed()) return -1; @@ -112,7 +112,7 @@ public: } INLINE_FUNCTION_HD - int32 insert(const PairType& p)const + uint32 insert(const PairType& p)const { if(auto insertResult = container_.insert(p); insertResult.failed()) return -1; @@ -125,7 +125,7 @@ public: // return the pair at index idx // perform no check for size and existance INLINE_FUNCTION_HD - PairType getPair(int32 idx)const + PairType getPair(uint32 idx)const { return container_.key_at(idx); } @@ -133,7 +133,7 @@ public: // - Device call // return the pair at index idx INLINE_FUNCTION_HD - bool getPair(int32 idx, PairType& p)const + bool getPair(uint32 idx, PairType& p)const { if(container_.valid_at(idx)) { @@ -148,7 +148,7 @@ public: } INLINE_FUNCTION_HD - int32 find(const PairType & p)const + uint32 find(const PairType & p)const { if( auto idx = container_.find(p); idx != Kokkos::UnorderedMapInvalidIndex ) @@ -158,26 +158,26 @@ public: } INLINE_FUNCTION_HD - bool isValid(int32 idx)const + bool isValid(uint32 idx)const { return container_.valid_at(idx); } INLINE_FUNCTION_HD - int32 capacity() const + uint32 capacity() const { return container_.capacity(); } - int32 loopCount()const + uint32 loopCount()const { return container_.capacity(); } //use this when the value of size_ is updated INLINE_FUNCTION_H - int32 size()const + uint32 size()const { return container_.size(); } @@ -190,7 +190,7 @@ public: /// increase the capacity of the container by at-least len /// the content will be erased. INLINE_FUNCTION_H - void increaseCapacityBy(int32 len) + void increaseCapacityBy(uint32 len) { uint newCap = container_.capacity()+len; this->clear(); diff --git a/src/Interaction/contactSearch/ContactSearch/ContactSearch.hpp b/src/Interaction/contactSearch/ContactSearch/ContactSearch.hpp index d6428064..531ecad9 100644 --- a/src/Interaction/contactSearch/ContactSearch/ContactSearch.hpp +++ b/src/Interaction/contactSearch/ContactSearch/ContactSearch.hpp @@ -22,16 +22,18 @@ Licence: #ifndef __ContactSearch_hpp__ #define __ContactSearch_hpp__ - +#include "contactSearchGlobals.hpp" #include "contactSearch.hpp" #include "box.hpp" +#include "particles.hpp" +#include "geometry.hpp" +#include "boundaryContactSearchList.hpp" namespace pFlow { template< - template class BaseMethod, - template class WallMapping + class searchMethod > class ContactSearch : @@ -39,89 +41,77 @@ class ContactSearch { public: - using IdType = typename contactSearch::IdType; + using IdType = uint32; - using IndexType = typename contactSearch::IndexType; + using ExecutionSpace = DefaultExecutionSpace; - using ExecutionSpace = typename contactSearch::ExecutionSpace; + using SearchMethodType = searchMethod; - using PairContainerType = typename contactSearch::PairContainerType; - - using ParticleContactSearchType = - BaseMethod< - ExecutionSpace>; - - using WallMappingType = - WallMapping< - ExecutionSpace>; - -protected: +private: + uniquePtr ppwContactSearch_ = nullptr; - uniquePtr particleContactSearch_ = nullptr; - - uniquePtr wallMapping_ = nullptr; + boundaryContactSearchList csBoundaries_; public: - TypeInfoTemplate2("ContactSearch", ParticleContactSearchType, WallMappingType); + TypeInfoTemplate11("ContactSearch", SearchMethodType); ContactSearch( const dictionary& csDict, - const box& domain, + const box& extDomain, const particles& prtcl, const geometry& geom, Timers& timers) : - contactSearch(csDict, domain, prtcl, geom, timers) - + contactSearch( + csDict, + extDomain, + prtcl, + geom, + timers), + csBoundaries_( + csDict, + Particles().pStruct().boundaries(), + *this) { - auto method = dict().getVal("method"); - auto wmMethod = dict().getVal("wallMapping"); - - auto nbDict = dict().subDict(method+"Info"); + /*auto method = dict().getVal("method"); + + auto nbDict = dict().subDict(method+"Info");*/ - real minD, maxD; + real minD; + real maxD; this->Particles().boundingSphereMinMax(minD, maxD); - const auto& position = this->Particles().pointPosition().deviceVectorAll(); - const auto& diam = this->Particles().boundingSphere().deviceVectorAll(); + const auto& position = this->Particles().pointPosition().deviceViewAll(); + const auto& flags = this->Particles().dynPointStruct().activePointsMaskDevice(); + const auto& diam = this->Particles().boundingSphere().deviceViewAll(); - particleContactSearch_ = - makeUnique + uint32 wnPoints = this->Geometry().numPoints(); + uint32 wnTri = this->Geometry().size(); + const auto& wPoints = this->Geometry().points().deviceViewAll(); + const auto& wVertices = this->Geometry().vertices().deviceViewAll(); + const auto& wNormals = this->Geometry().normals().deviceViewAll(); + + ppwContactSearch_ = + makeUnique ( - nbDict, - this->domain(), + dict(), + this->extendedDomainBox(), minD, maxD, position, - diam + flags, + diam, + wnPoints, + wnTri, + wPoints, + wVertices, + wNormals ); REPORT(2)<<"Contact search algorithm for particle-particle is "<< - greenText(particleContactSearch_().typeName())<Geometry().numPoints(); - int32 wnTri = this->Geometry().size(); - - const auto& wPoints = this->Geometry().points().deviceVectorAll(); - const auto& wVertices = this->Geometry().vertices().deviceVectorAll(); - - wallMapping_ = - makeUnique( - wmDict, - particleContactSearch_().numLevels(), - particleContactSearch_().getCellsLevels(), - wnPoints, - wnTri, - wPoints, - wVertices - ); - REPORT(2)<<"Wall mapping algorithm for particle-wall is "<< - greenText(wallMapping_().typeName())<< endREPORT; + Green_Text(ppwContactSearch_().typeName())<Particles().activeRange(); - - sphereSphereTimer_.start(); - - if(this->Particles().allActive()) - { - particleContactSearch_().broadSearch(ppPairs, activeRange, force); - } - else - { - particleContactSearch_().broadSearch(ppPairs, activeRange, this->Particles().activePointsMaskD(), force); - } - - sphereSphereTimer_.end(); - - } - else + fatalErrorInFunction; return false; - - if(wallMapping_) - { - sphereWallTimer_.start(); - wallMapping_().broadSearch(pwPairs, particleContactSearch_(), force); - sphereWallTimer_.end(); } - else - return false; + ppTimer().end(); - - return true; } - - bool ppEnterBroadSearch()const override + bool boundaryBroadSearch( + uint32 i, + uint32 iter, + real t, + real dt, + csPairContainerType& ppPairs, + csPairContainerType& pwPairs, + bool force = false)override { - if(particleContactSearch_) + return csBoundaries_[i].broadSearch( + iter, + t, + dt, + ppPairs, + pwPairs, + force); + } + + + bool enterBroadSearch(uint32 iter, real t, real dt)const override + { + if(ppwContactSearch_) { - return particleContactSearch_().enterBoadSearch(); + return ppwContactSearch_().performSearch(iter); } return false; } - bool pwEnterBroadSearch()const override + bool performedBroadSearch()const override { - if(wallMapping_) - { - return wallMapping_().enterBoadSearch(); - } - return false; + return ppwContactSearch_().performedSearch(); } - - bool ppPerformedBroadSearch()const override - { - if(particleContactSearch_) - { - return particleContactSearch_().performedSearch(); - } - return false; - } - - - bool pwPerformedBroadSearch()const override - { - if(wallMapping_) - { - return wallMapping_().performedSearch(); - } - return false; - } - - /*bool update(const eventMessage& msg) - { - if(msg.isSizeChanged() ) - { - auto newSize = this->prtcl().size(); - if(!particleContactSearch_().objectSizeChanged(newSize)) - { - fatalErrorInFunction<< - "erro in changing the size for particleContactSearch_ \n"; - return false; - } - } - - if(msg.isCapacityChanged() ) - { - auto newSize = this->prtcl().capacity(); - if(!particleContactSearch_().objectSizeChanged(newSize)) - { - fatalErrorInFunction<< - "erro in changing the capacity for particleContactSearch_ \n"; - return false; - } - } - - return true; - }*/ - - }; } diff --git a/src/Interaction/contactSearch/ContactSearch/ContactSearchs.cpp b/src/Interaction/contactSearch/ContactSearch/ContactSearchs.cpp index 043e9b78..61024220 100644 --- a/src/Interaction/contactSearch/ContactSearch/ContactSearchs.cpp +++ b/src/Interaction/contactSearch/ContactSearch/ContactSearchs.cpp @@ -20,11 +20,11 @@ Licence: #include "ContactSearch.hpp" -#include "cellMapping.hpp" +//#include "cellMapping.hpp" #include "NBS.hpp" -#include "multiGridNBS.hpp" -#include "multiGridMapping.hpp" +//#include "multiGridNBS.hpp" +//#include "multiGridMapping.hpp" -template class pFlow::ContactSearch; -template class pFlow::ContactSearch; +template class pFlow::ContactSearch; +//template class pFlow::ContactSearch; diff --git a/src/Interaction/contactSearch/boundaries/boundaryContactSearch/boundaryContactSearch.cpp b/src/Interaction/contactSearch/boundaries/boundaryContactSearch/boundaryContactSearch.cpp new file mode 100644 index 00000000..e7d6145e --- /dev/null +++ b/src/Interaction/contactSearch/boundaries/boundaryContactSearch/boundaryContactSearch.cpp @@ -0,0 +1,77 @@ +/*------------------------------- phasicFlow --------------------------------- + O C enter of + O O E ngineering and + O O M ultiscale modeling of + OOOOOOO F luid flow +------------------------------------------------------------------------------ + Copyright (C): www.cemf.ir + email: hamid.r.norouzi AT gmail.com +------------------------------------------------------------------------------ +Licence: + This file is part of phasicFlow code. It is a free software for simulating + granular and multiphase flows. You can redistribute it and/or modify it under + the terms of GNU General Public License v3 or any other later versions. + + phasicFlow is distributed to help others in their research in the field of + granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +-----------------------------------------------------------------------------*/ + +#include "boundaryContactSearch.hpp" +#include "contactSearch.hpp" + +pFlow::boundaryContactSearch::boundaryContactSearch( + const dictionary &dict, + const boundaryBase &boundary, + const contactSearch &cSearch) + : generalBoundary( + boundary, + cSearch.pStruct(), + "", + ""), + contactSearch_(cSearch), + updateInterval_(dict.getVal("updateInterval")) +{ +} + +pFlow::uniquePtr +pFlow::boundaryContactSearch::create( + const dictionary &dict, + const boundaryBase &boundary, + const contactSearch &cSearch) +{ + + word bType = angleBracketsNames2( + "boundaryContactSearch", + pFlowProcessors().localRunTypeName(), + boundary.type()); + word altBType{"boundaryContactSearch"}; + + if( boundaryBasevCtorSelector_.search(bType) ) + { + REPORT(2)<<"Creating contact search boundary "<< Green_Text(bType)<< + " for "<"); + + boundaryContactSearch( + const dictionary &dict, + const boundaryBase &boundary, + const contactSearch &cSearch); + + create_vCtor( + boundaryContactSearch, + boundaryBase, + ( + const dictionary &dict, + const boundaryBase &boundary, + const contactSearch &cSearch), + (dict, boundary, cSearch)); + + add_vCtor( + boundaryContactSearch, + boundaryContactSearch, + boundaryBase); + + const contactSearch &cSearch() const + { + return contactSearch_; + } + + void fill(const std::any &val) override + { + return; + } + + bool hearChanges( + real t, + real dt, + uint32 iter, + const message &msg, + const anyList &varList) override + { + + if (msg.equivalentTo(message::BNDR_RESET)) + { + // do nothing + } + return true; + } + + virtual bool broadSearch( + uint32 iter, + real t, + real dt, + csPairContainerType &ppPairs, + csPairContainerType &pwPairs, + bool force = false) + { + return true; + } + + static uniquePtr create( + const dictionary &dict, + const boundaryBase &boundary, + const contactSearch &cSearch); +}; + +} + +#endif //__boundaryContactSearch_hpp__ diff --git a/src/Interaction/contactSearch/boundaries/boundaryContactSearchList.cpp b/src/Interaction/contactSearch/boundaries/boundaryContactSearchList.cpp new file mode 100644 index 00000000..4f114430 --- /dev/null +++ b/src/Interaction/contactSearch/boundaries/boundaryContactSearchList.cpp @@ -0,0 +1,29 @@ +#include "boundaryContactSearchList.hpp" +#include "boundaryList.hpp" + +void pFlow::boundaryContactSearchList::setList( + const dictionary &dict, + const contactSearch &cSearch) +{ + for(auto i=0; iset + ( + i, + boundaryContactSearch::create(dict, boundaries_[i], cSearch) + ); + } +} + +pFlow::boundaryContactSearchList::boundaryContactSearchList( + const dictionary &dict, + const boundaryList& bndrs, + const contactSearch &cSearch) + : + ListPtr(bndrs.size()), + boundaries_(bndrs) +{ + setList(dict, cSearch); +} + + diff --git a/src/Interaction/contactSearch/boundaries/boundaryContactSearchList.hpp b/src/Interaction/contactSearch/boundaries/boundaryContactSearchList.hpp new file mode 100644 index 00000000..40e9f32e --- /dev/null +++ b/src/Interaction/contactSearch/boundaries/boundaryContactSearchList.hpp @@ -0,0 +1,35 @@ +#include "ListPtr.hpp" +#include "boundaryContactSearch.hpp" + +namespace pFlow +{ + +class boundaryList; +class contactSearch; + +class boundaryContactSearchList +: + public ListPtr +{ +private: + + const boundaryList& boundaries_; + + void setList( + const dictionary& dict, + const contactSearch& cSearch); +public: + + TypeInfoNV("boundaryContactSearchList"); + + boundaryContactSearchList( + const dictionary& dict, + const boundaryList& bndrs, + const contactSearch& cSearch); + + ~boundaryContactSearchList()=default; + +}; + + +} \ No newline at end of file diff --git a/src/Interaction/contactSearch/boundaries/periodicBoundaryContactSearch/periodicBoundaryContactSearch.cpp b/src/Interaction/contactSearch/boundaries/periodicBoundaryContactSearch/periodicBoundaryContactSearch.cpp new file mode 100644 index 00000000..7dfcd1b5 --- /dev/null +++ b/src/Interaction/contactSearch/boundaries/periodicBoundaryContactSearch/periodicBoundaryContactSearch.cpp @@ -0,0 +1,131 @@ +/*------------------------------- 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 "periodicBoundaryContactSearch.hpp" +#include "contactSearch.hpp" +#include "particles.hpp" +#include "pointStructure.hpp" +#include "geometry.hpp" + + +void pFlow::periodicBoundaryContactSearch::setSearchBox() +{ + + auto db = pStruct().thisDomain().domainBox(); + auto n1 = boundary().mirrorBoundary().boundaryPlane().normal(); + auto l1 = boundary().mirrorBoundary().neighborLength(); + auto n2 = boundary().boundaryPlane().normal(); + auto l2 = boundary().neighborLength(); + + realx3 minP = db.minPoint() + (db.maxPoint()-db.minPoint())* n1+(n2*l2); + realx3 maxP = db.maxPoint() + (n1*l1); + + searchBox_={minP, maxP}; +} + +pFlow::periodicBoundaryContactSearch::periodicBoundaryContactSearch( + const dictionary &dict, + const boundaryBase &boundary, + const contactSearch &cSearch) +: + boundaryContactSearch(dict, boundary, cSearch), + transferVec_(boundary.mirrorBoundary().displacementVectroToMirror()), + thisIndex_(thisBoundaryIndex()), + mirrorIndex_(mirrorBoundaryindex()), + diameter_(cSearch.Particles().boundingSphere()) +{ + + if(thisIndex_%2==1) + { + masterSearch_ = true; + + setSearchBox(); + + real minD; + real maxD; + cSearch.Particles().boundingSphereMinMax(minD, maxD); + + ppContactSearch_ = makeUnique( + searchBox_, + maxD); + + const auto& geom = cSearch.Geometry(); + + pwContactSearch_ = makeUnique( + 0.5, + geom.numPoints(), + geom.size(), + geom.points().deviceViewAll(), + geom.vertices().deviceViewAll(), + geom.normals().deviceViewAll()); + } + else + { + masterSearch_ = false; + searchBox_={{0,0,0},{0,0,0}}; + } +} + +bool pFlow::periodicBoundaryContactSearch::broadSearch +( + uint32 iter, + real t, + real dt, + csPairContainerType &ppPairs, + csPairContainerType &pwPairs, + bool force +) +{ + if(masterSearch_) + { + + auto thisP = boundary().thisPoints(); + auto thisDiams = diameter_.BoundaryField(thisIndex_).thisField(); + auto mirrorP = mirrorBoundary().thisPoints(); + auto mirrorDiams = diameter_.BoundaryField(mirrorIndex_).thisField(); + + ppContactSearch_().broadSearchPP( + ppPairs, + thisP, + thisDiams, + mirrorP, + mirrorDiams, + transferVec_); + + /*pwContactSearch_().broadSearch( + pwPairs, + ppContactSearch_().searchCells(), + thisP, + thisDiams, + mirrorP, + mirrorDiams, + transferVec_, + ppContactSearch_().sizeRatio());*/ + + //output< ppContactSearch_ = nullptr; + + uniquePtr pwContactSearch_ = nullptr; + + const realPointField_D &diameter_; + + bool masterSearch_ = false; + + void setSearchBox(); + +public: + TypeInfo("boundaryContactSearch") + + periodicBoundaryContactSearch( + const dictionary &dict, + const boundaryBase &boundary, + const contactSearch &cSearch); + + ~periodicBoundaryContactSearch() override = default; + + add_vCtor( + boundaryContactSearch, + periodicBoundaryContactSearch, + boundaryBase); + + bool broadSearch( + uint32 iter, + real t, + real dt, + csPairContainerType &ppPairs, + csPairContainerType &pwPairs, + bool force = false) override; +}; + +} + +#endif //__periodicBoundaryContactSearch_hpp__ \ No newline at end of file diff --git a/src/Interaction/contactSearch/boundaries/periodicBoundaryContactSearch/ppwBndryContactSearch.cpp b/src/Interaction/contactSearch/boundaries/periodicBoundaryContactSearch/ppwBndryContactSearch.cpp new file mode 100644 index 00000000..ba6928a5 --- /dev/null +++ b/src/Interaction/contactSearch/boundaries/periodicBoundaryContactSearch/ppwBndryContactSearch.cpp @@ -0,0 +1,109 @@ + +#include "ppwBndryContactSearch.hpp" +#include "ppwBndryContactSearchKernels.hpp" +#include "phasicFlowKokkos.hpp" +#include "streams.hpp" + +void pFlow::ppwBndryContactSearch::checkAllocateNext(uint32 n) +{ + if( nextCapacity_ < n) + { + nextCapacity_ = n; + reallocNoInit(next_, n); + } +} + +void pFlow::ppwBndryContactSearch::nullifyHead() +{ + fill(head_, static_cast(-1)); +} + +void pFlow::ppwBndryContactSearch::nullifyNext(uint32 n) +{ + fill(next_, 0u, n, static_cast(-1)); +} + +void pFlow::ppwBndryContactSearch::buildList( + const deviceScatteredFieldAccess &points) +{ + if(points.empty())return; + uint32 n = points.size(); + checkAllocateNext(n); + nullifyNext(n); + nullifyHead(); + + pFlow::pweBndryContactSearchKernels::buildNextHead( + points, + searchCells_, + head_, + next_ + ); +} + +pFlow::ppwBndryContactSearch::ppwBndryContactSearch +( + const box &domain, + real cellSize, + real sizeRatio +) +: + searchCells_(domain, cellSize), + head_("periodic:head",searchCells_.nx(), searchCells_.ny(), searchCells_.nz()), + sizeRatio_(sizeRatio) +{ + +} + +bool pFlow::ppwBndryContactSearch::broadSearchPP +( + csPairContainerType &ppPairs, + const deviceScatteredFieldAccess &points, + const deviceScatteredFieldAccess& diams, + const deviceScatteredFieldAccess &mirrorPoints, + const deviceScatteredFieldAccess& mirrorDiams, + const realx3& transferVec +) +{ + + buildList(points); + + uint32 nNotInserted = 1; + + // loop until the container size fits the numebr of contact pairs + while (nNotInserted > 0) + { + + nNotInserted = pFlow::pweBndryContactSearchKernels::broadSearchPP + ( + ppPairs, + points, + diams, + mirrorPoints, + mirrorDiams, + transferVec, + head_, + next_, + searchCells_, + sizeRatio_ + ); + + + if(nNotInserted) + { + // - resize the container + // note that getFull now shows the number of failed insertions. + uint32 len = max(nNotInserted,100u) ; + + auto oldCap = ppPairs.capacity(); + + ppPairs.increaseCapacityBy(len); + + INFORMATION<< "Particle-particle contact pair container capacity increased from "<< + oldCap << " to "<; + + using NextType = deviceViewType1D; + +private: + cells searchCells_; + + HeadType head_{"periodic::head", 1, 1, 1}; + + NextType next_{"periodic::next", 1}; + + real sizeRatio_ = 1.0; + + uint32 nextCapacity_ = 0; + + void checkAllocateNext(uint32 n); + + void nullifyHead(); + + void nullifyNext(uint32 n); + + void buildList( + const deviceScatteredFieldAccess &points); + +public: + ppwBndryContactSearch( + const box &domain, + real cellSize, + real sizeRatio = 1.0); + + bool broadSearchPP( + csPairContainerType &ppPairs, + const deviceScatteredFieldAccess &points, + const deviceScatteredFieldAccess &diams, + const deviceScatteredFieldAccess &mirrorPoints, + const deviceScatteredFieldAccess &mirrorDiams, + const realx3 &transferVec); + + const auto& searchCells()const + { + return searchCells_; + } + + real sizeRatio()const + { + return sizeRatio_; + } +}; + +} + +#endif //__ppwBndryContactSearch_hpp__ \ No newline at end of file diff --git a/src/Interaction/contactSearch/boundaries/periodicBoundaryContactSearch/ppwBndryContactSearchKernels.cpp b/src/Interaction/contactSearch/boundaries/periodicBoundaryContactSearch/ppwBndryContactSearchKernels.cpp new file mode 100644 index 00000000..ea266e78 --- /dev/null +++ b/src/Interaction/contactSearch/boundaries/periodicBoundaryContactSearch/ppwBndryContactSearchKernels.cpp @@ -0,0 +1,105 @@ +#include "ppwBndryContactSearchKernels.hpp" + +INLINE_FUNCTION_HD +bool sphereSphereCheckB(const pFlow::realx3& p1, const pFlow::realx3 p2, pFlow::real d1, pFlow::real d2) +{ + return pFlow::length(p2-p1) < 0.5*(d2+d1); +} + +void pFlow::pweBndryContactSearchKernels::buildNextHead +( + const deviceScatteredFieldAccess &points, + const cells &searchCells, + deviceViewType3D &head, + deviceViewType1D &next +) +{ + if(points.empty())return; + + uint32 n= points.size(); + + Kokkos::parallel_for( + "pFlow::ppwBndryContactSearch::buildList", + deviceRPolicyStatic(0,n), + LAMBDA_HD(uint32 i) + { + int32x3 ind; + if( searchCells.pointIndexInDomain(points[i], ind) ) + { + // discards points out of searchCell + uint32 old = Kokkos::atomic_exchange(&head(ind.x(), ind.y(), ind.z()), i); + next[i] = old; + } + } + ); + Kokkos::fence(); +} + +pFlow::uint32 pFlow::pweBndryContactSearchKernels::broadSearchPP +( + csPairContainerType &ppPairs, + const deviceScatteredFieldAccess &points, + const deviceScatteredFieldAccess &diams, + const deviceScatteredFieldAccess &mirrorPoints, + const deviceScatteredFieldAccess &mirrorDiams, + const realx3 &transferVec, + const deviceViewType3D &head, + const deviceViewType1D &next, + const cells &searchCells, + const real sizeRatio +) +{ + + if(points.empty()) return 0; + if(mirrorPoints.empty())return 0; + + auto nMirror = mirrorPoints.size(); + + uint32 getFull = 0; + + Kokkos::parallel_reduce( + "pFlow::pweBndryContactSearchKernels::broadSearchPP", + deviceRPolicyStatic(0, nMirror), + LAMBDA_HD(const uint32 mrrI, uint32 &getFullUpdate) + { + realx3 p_m = mirrorPoints(mrrI) + transferVec; + + int32x3 ind_m; + if( !searchCells.pointIndexInDomain(p_m, ind_m))return; + + real d_m = sizeRatio*mirrorDiams[mrrI]; + + for(int ii=-1; ii<2; ii++) + { + for(int jj=-1; jj<2; jj++) + { + for(int kk =-1; kk<2; kk++) + { + auto ind = ind_m + int32x3{ii,jj,kk}; + + if(!searchCells.inCellRange(ind))continue; + + uint32 thisI = head(ind.x(),ind.y(),ind.z()); + while (thisI!=-1) + { + + auto d_n = sizeRatio*diams[thisI]; + + // first item is for this boundary and second itme, for mirror + if(sphereSphereCheckB(p_m, points[thisI], d_m, d_n)&& + ppPairs.insert(thisI,mrrI) == -1) + { + getFullUpdate++; + } + + thisI = next(thisI); + } + } + } + } + }, + getFull + ); + + return getFull; +} diff --git a/src/Interaction/contactSearch/boundaries/periodicBoundaryContactSearch/ppwBndryContactSearchKernels.hpp b/src/Interaction/contactSearch/boundaries/periodicBoundaryContactSearch/ppwBndryContactSearchKernels.hpp new file mode 100644 index 00000000..78c4a125 --- /dev/null +++ b/src/Interaction/contactSearch/boundaries/periodicBoundaryContactSearch/ppwBndryContactSearchKernels.hpp @@ -0,0 +1,31 @@ + +#include "contactSearchGlobals.hpp" +#include "cells.hpp" +#include "contactSearchFunctions.hpp" +#include "scatteredFieldAccess.hpp" + +namespace pFlow::pweBndryContactSearchKernels +{ + +void buildNextHead( + const deviceScatteredFieldAccess &points, + const cells &searchCells, + deviceViewType3D &head, + deviceViewType1D &next ); + + +uint32 broadSearchPP +( + csPairContainerType &ppPairs, + const deviceScatteredFieldAccess &points, + const deviceScatteredFieldAccess &diams, + const deviceScatteredFieldAccess &mirrorPoints, + const deviceScatteredFieldAccess &mirrorDiams, + const realx3 &transferVec, + const deviceViewType3D &head, + const deviceViewType1D &next, + const cells &searchCells, + real sizeRatio +); + +} \ No newline at end of file diff --git a/src/Interaction/contactSearch/boundaries/periodicBoundaryContactSearch/wallBoundaryContactSearch.cpp b/src/Interaction/contactSearch/boundaries/periodicBoundaryContactSearch/wallBoundaryContactSearch.cpp new file mode 100644 index 00000000..99bbb8ac --- /dev/null +++ b/src/Interaction/contactSearch/boundaries/periodicBoundaryContactSearch/wallBoundaryContactSearch.cpp @@ -0,0 +1,141 @@ +#include "wallBoundaryContactSearch.hpp" +#include "streams.hpp" + +pFlow::wallBoundaryContactSearch::wallBoundaryContactSearch +( + real cellExtent, + uint32 numPoints, + uint32 numElements, + const ViewType1D &points, + const ViewType1D &vertices, + const ViewType1D &normals +) +: + cellExtent_( max(cellExtent, 0.5 ) ), + numElements_(numElements), + numPoints_(numPoints), + vertices_(vertices), + points_(points), + normals_(normals) +{ + allocateArrays(); +} + +bool pFlow::wallBoundaryContactSearch::build(const cells &searchBox, const realx3& transferVec) +{ + Kokkos::parallel_for( + "pFlow::cellsWallLevel0::build", + deviceRPolicyStatic(0,numElements_), + CLASS_LAMBDA_HD(uint32 i) + { + auto v = vertices_[i]; + auto p1 = points_[v.x()]+transferVec; + auto p2 = points_[v.y()]+transferVec; + auto p3 = points_[v.z()]+transferVec; + + realx3 minP; + realx3 maxP; + + searchBox.extendBox(p1, p2, p3, cellExtent_, minP, maxP); + elementBox_[i] = iBoxType(searchBox.pointIndex(minP), searchBox.pointIndex(maxP)); + auto d = elementBox_[i].maxPoint()-elementBox_[i].minPoint(); + validBox_[i] = (d.x()*d.y()*d.z())==0? 0:1; + }); + Kokkos::fence(); + + return true; +} + +bool pFlow::wallBoundaryContactSearch::broadSearch +( + csPairContainerType &pairs, + const cells &searchCells, + const deviceScatteredFieldAccess &thisPoints, + const deviceScatteredFieldAccess &thisDiams, + const deviceScatteredFieldAccess &mirrorPoints, + const deviceScatteredFieldAccess &mirroDiams, + const realx3 &transferVec, + real sizeRatio +) +{ + uint32 nNotInserted = 1; + + while (nNotInserted>0u) + { + build(searchCells,{0,0,0}); + nNotInserted = findPairsElementRangeCount( + pairs, + searchCells, + thisPoints, + thisDiams, + {0,0,0}, + 0 + ); + + build(searchCells, transferVec); + nNotInserted += findPairsElementRangeCount( + pairs, + searchCells, + mirrorPoints, + mirroDiams, + transferVec, + BASE_MIRROR_WALL_INDEX + ); + + if(nNotInserted>0u) + { + // note that getFull now shows the number of failed insertions. + uint32 incCap = max(nNotInserted,50u) ; + + auto oldCap = pairs.capacity(); + + pairs.increaseCapacityBy(incCap); + + INFORMATION<< "The contact pair container capacity increased from "<< + oldCap << " to "< &pPoints, + const deviceScatteredFieldAccess &pDiams, + const realx3 &transferVec, + uint baseTriIndex +) +{ + + if(pPoints.empty())return 0u; + + uint32 nNotInserted = 0; + uint32 nThis = pPoints.size(); + + Kokkos::parallel_reduce( + "pFlow::wallBoundaryContactSearch::findPairsElementRangeCount", + deviceRPolicyDynamic(0,nThis), + LAMBDA_HD(uint32 i, uint32 ¬InsertedUpdate) + { + auto p = pPoints[i]+transferVec; + int32x3 ind; + if( searchCells.pointIndexInDomain(p, ind) ) + { + for(uint32 nTri=0; nTri; + +private: + + // - box extent + real cellExtent_ = 0.5; + + // - number of triangle elements + uint32 numElements_ = 0; + + // - number of points + uint32 numPoints_ = 0; + + // - ref to vectices (borrowed) + ViewType1D vertices_; + + // - ref to points in the trisurface (borrowed) + ViewType1D points_; + + // - ref to normal vectors of triangles (borrowed) + ViewType1D normals_; + + // cell range of element/triangle bounding box + ViewType1D elementBox_; + + ViewType1D validBox_; + + + FUNCTION_H + void allocateArrays() + { + reallocNoInit( elementBox_, numElements_); + reallocNoInit( validBox_, numElements_); + } + +public: + + TypeInfoNV("wallBoundaryContactSearch"); + + INLINE_FUNCTION_HD + wallBoundaryContactSearch()=default; + + FUNCTION_H + wallBoundaryContactSearch( + real cellExtent, + uint32 numPoints, + uint32 numElements, + const ViewType1D& points, + const ViewType1D& vertices, + const ViewType1D& normals); + + + + INLINE_FUNCTION_HD + uint32 numElements()const + { + return numElements_; + } + + + bool build(const cells& searchBox, const realx3& transferVec); + + bool broadSearch( + csPairContainerType& pairs, + const cells &searchCells, + const deviceScatteredFieldAccess& thisPoints, + const deviceScatteredFieldAccess& thisDiams, + const deviceScatteredFieldAccess& mirrorPoints, + const deviceScatteredFieldAccess& mirroDiams, + const realx3& transferVec, + real sizeRatio); + + uint32 findPairsElementRangeCount( + csPairContainerType &pairs, + const cells &searchCells, + const deviceScatteredFieldAccess &pPoints, + const deviceScatteredFieldAccess &pDiams, + const realx3 &transferVec, + uint baseTriIndex); + + + +}; // wallBoundaryContactSearch + +} // pFlow + + +#endif // __wallBoundaryContactSearch_hpp__ diff --git a/src/Interaction/contactSearch/contactSearch/contactSearch.cpp b/src/Interaction/contactSearch/contactSearch/contactSearch.cpp index 17c1dbd3..03574077 100644 --- a/src/Interaction/contactSearch/contactSearch/contactSearch.cpp +++ b/src/Interaction/contactSearch/contactSearch/contactSearch.cpp @@ -19,54 +19,56 @@ Licence: -----------------------------------------------------------------------------*/ #include "contactSearch.hpp" - +#include "streams.hpp" +#include "particles.hpp" pFlow::contactSearch::contactSearch( const dictionary& dict, - const box& domain, + const box& extDomain, const particles& prtcl, const geometry& geom, Timers& timers) : - interactionBase(prtcl, geom), - domain_(domain), - dict_(dict), - sphereSphereTimer_("particle-particle contact search", &timers), - sphereWallTimer_("particle-wall contact search", &timers) + extendedDomainBox_(extDomain), + particles_(prtcl), + geometry_(geom), + ppTimer_("particle-particle contact search", &timers), + pwTimer_("particle-wall contact search", &timers), + dict_(dict) { } +const pFlow::pointStructure &pFlow::contactSearch::pStruct() const +{ + return particles_.pStruct(); +} pFlow::uniquePtr pFlow::contactSearch::create( - const dictionary& dict, - const box& domain, - const particles& prtcl, - const geometry& geom, - Timers& timers) + const dictionary &dict, + const box &extDomain, + const particles &prtcl, + const geometry &geom, + Timers &timers) { + word baseMethName = dict.getVal("method"); - word baseMethName = dict.getVal("method"); - word wallMethod = dict.getVal("wallMapping"); + auto model = angleBracketsNames("ContactSearch", baseMethName); - auto model = angleBracketsNames2("ContactSearch", baseMethName, wallMethod); - - - REPORT(1)<<"Selecting contact search model . . ."<; + const geometry& geometry_; -protected: + Timer ppTimer_; - const box& domain_; + Timer pwTimer_; dictionary dict_; - Timer sphereSphereTimer_; - - Timer sphereWallTimer_; - - auto& dict() - { - return dict_; - } - public: TypeInfo("contactSearch"); contactSearch( const dictionary& dict, - const box& domain, + const box& extDomain, const particles& prtcl, const geometry& geom, Timers& timers); @@ -88,40 +82,68 @@ public: (dict, domain, prtcl, geom, timers) ); - const auto& domain()const - { - return domain_; - } - + const auto& dict()const { return dict_; } + const auto& extendedDomainBox()const + { + return extendedDomainBox_; + } + + const auto& Particles()const + { + return particles_; + } + + const pointStructure& pStruct()const; + + const auto& Geometry()const + { + return geometry_; + } + + auto& ppTimer() + { + return ppTimer_; + } + + auto& pwTimer() + { + return pwTimer_; + } virtual bool broadSearch( - PairContainerType& ppPairs, - PairContainerType& pwPairs, + uint32 iter, + real t, + real dt, + csPairContainerType& ppPairs, + csPairContainerType& pwPairs, bool force = false) = 0; - - virtual - bool ppEnterBroadSearch()const = 0; - - virtual - bool pwEnterBroadSearch()const = 0; - - virtual - bool ppPerformedBroadSearch()const = 0; - - virtual - bool pwPerformedBroadSearch()const = 0; + virtual + bool boundaryBroadSearch( + uint32 i, + uint32 iter, + real t, + real dt, + csPairContainerType& ppPairs, + csPairContainerType& pwPairs, + bool force = false)=0; + + virtual + bool enterBroadSearch(uint32 iter, real t, real dt)const = 0; + + virtual + bool performedBroadSearch()const = 0; static uniquePtr create( const dictionary& dict, - const box& domain, + const box& extDomain, const particles& prtcl, const geometry& geom, Timers& timers); diff --git a/src/Interaction/contactSearch/contactSearchFunctions.hpp b/src/Interaction/contactSearch/contactSearchFunctions.hpp index 55879c95..96ee9596 100644 --- a/src/Interaction/contactSearch/contactSearchFunctions.hpp +++ b/src/Interaction/contactSearch/contactSearchFunctions.hpp @@ -96,17 +96,6 @@ void indexToCell(const indexType idx, const iBox& box, triple; -//constexpr int32 minCellIndex = largestNegative(); - -//constexpr int32 maxCellIndex = largestPositive(); +inline +const uint32 BASE_MIRROR_WALL_INDEX = 1000000; } - -#endif //__interactionTypes_hpp__ +#endif diff --git a/src/Interaction/contactSearch/methods/NBS.hpp b/src/Interaction/contactSearch/methods/NBS.hpp deleted file mode 100644 index fb3cc4f8..00000000 --- a/src/Interaction/contactSearch/methods/NBS.hpp +++ /dev/null @@ -1,209 +0,0 @@ -/*------------------------------- 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 __NBS_hpp__ -#define __NBS_hpp__ - -#include "NBSLevel0.hpp" - -namespace pFlow -{ - - -template -class NBS -{ -public: - - using NBSLevel0Type = NBSLevel0; - - using cellIterator = typename NBSLevel0Type::cellIterator; - - using IdType = typename NBSLevel0Type::IdType; - - using IndexType = typename NBSLevel0Type::IndexType; - - using Cells = typename NBSLevel0Type::Cells; - - using CellType = typename Cells::CellType; - - using execution_space = typename NBSLevel0Type::execution_space; - - using memory_space = typename NBSLevel0Type::memory_space; - - -protected: - - real sizeRatio_ = 1.0; - - int32 updateFrequency_= 1; - - int32 currentIter_ = 0; - - bool performedSearch_ = false; - - NBSLevel0Type NBSLevel0_; - -private: - - bool performSearch() - { - if(currentIter_ % updateFrequency_ == 0) - { - currentIter_++; - return true; - - }else - { - currentIter_++; - return false; - } - } - -public: - - TypeInfoNV("NBS"); - - NBS( - const dictionary& dict, - const box& domain, - real minSize, - real maxSize, - const ViewType1D& position, - const ViewType1D& diam) - : - sizeRatio_( - max( - dict.getValOrSet("sizeRatio", 1.0), - 1.0 - )), - updateFrequency_( - max( - dict.getValOrSet("updateFrequency", 1), - 1 - )), - NBSLevel0_( - domain, - maxSize*sizeRatio_, - sizeRatio_, - position, - diam) - {} - - INLINE_FUNCTION_HD - NBS(const NBS&) = default; - - INLINE_FUNCTION_HD - NBS& operator = (const NBS&) = default; - - INLINE_FUNCTION_HD - ~NBS()=default; - - //// - Methods - - bool enterBoadSearch()const - { - return currentIter_%updateFrequency_==0; - } - - bool performedSearch()const - { - return performedSearch_; - } - - Vector getCellIteratorLevels() - { - return Vector("cellIterator", 1, NBSLevel0_.getCellIterator()); - } - - auto getCellIterator(int32 lvl)const - { - return NBSLevel0_.getCellIterator(); - } - - int32 numLevels()const - { - return 1; - } - - Vector getCellsLevels()const - { - return Vector("Cells", 1, NBSLevel0_.getCells()); - } - - auto getCells()const - { - return NBSLevel0_.getCells(); - } - - bool objectSizeChanged(int32 newSize) - { - NBSLevel0_.checkAllocateNext(newSize); - return true; - } - - // - Perform the broad search to find pairs - // with force = true, perform broad search regardless of - // updateFrequency_ value - // on all the points in the range of [0,numPoints_) - template - bool broadSearch(PairsContainer& pairs, range activeRange, bool force=false) - { - - if(force) currentIter_ = 0; - performedSearch_ = false; - - if( !performSearch() ) return true; - - - NBSLevel0_.build(activeRange); - - NBSLevel0_.findPairs(pairs); - - performedSearch_ = true; - return true; - } - - // - Perform the broad search to find pairs, - // ignore particles with incld(i) = true, - // with force = true, perform broad search regardless of - // updateFrequency_ value - template - bool broadSearch(PairsContainer& pairs, range activeRange, IncludeFunction incld, bool force = false) - { - if(force) currentIter_ = 0; - performedSearch_ = false; - - if( !performSearch() ) return true; - - NBSLevel0_.build(activeRange, incld); - - NBSLevel0_.findPairs(pairs); - - performedSearch_ = true; - return true; - } - -}; - -} - -#endif diff --git a/src/Interaction/contactSearch/methods/NBSCrossLoop.hpp b/src/Interaction/contactSearch/methods/NBSCrossLoop.hpp deleted file mode 100644 index adce7409..00000000 --- a/src/Interaction/contactSearch/methods/NBSCrossLoop.hpp +++ /dev/null @@ -1,82 +0,0 @@ -/*------------------------------- 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. - ------------------------------------------------------------------------------*/ - - -int32 m = this->head_(i,j,k); -CellType currentCell(i,j,k); -int32 n = -1; - -while( m > -1 ) -{ - - auto p_m = this->pointPosition_[m]; - auto d_m = this->sizeRatio_* this->diameter_[m]; - - int32x3 crossIndex = mapIndexLevels( - int32x3(i,j,k), - level_, - upperLevel.level()); - - - for(int32 ii = -1; ii<2; ii++) - { - for(int32 jj=-1; jj<2; jj++) - { - int32 kk=-1; - while( kk < 2) - { - int32x3 nghbrCI = crossIndex + int32x3(ii,jj,kk); - - if( upperLevel.isInRange(nghbrCI) ) - { - n = upperLevel.head_( - nghbrCI.x(), - nghbrCI.y(), - nghbrCI.z()); - - while( n >-1) - { - auto p_n = this->pointPosition_[n]; - auto d_n = this->sizeRatio_*this->diameter_[n]; - - if( sphereSphereCheck(p_m, p_n, d_m, d_n) ) - { - auto ln = n; - auto lm = m; - if(lm>ln) this->Swap(lm,ln); - if( auto res = pairs.insert(lm,ln); res <0) - { - getFullUpdate++; - } - } - - n = this->next_[n]; - } - - } - - kk++; - } - } - } - - m = this->next_[m]; -} - diff --git a/src/Interaction/contactSearch/methods/NBSLevel.hpp b/src/Interaction/contactSearch/methods/NBSLevel.hpp deleted file mode 100644 index f355d566..00000000 --- a/src/Interaction/contactSearch/methods/NBSLevel.hpp +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef __NBSLevel_hpp__ -#define __NBSLevel_hpp__ - - -#include "NBSLevel0.hpp" - - -namespace pFlow -{ - -INLINE_FUNCTION_HD -int32x3 mapIndexLevels(const int32x3& ind, int32 lowerLevel, int32 upperLevel); - -template -class -NBSLevel -: - public NBSLevel0 -{ -public: - - using NBSLevel0Type = NBSLevel0; - - using cellIterator = typename NBSLevel0Type::cellIterator; - - using IdType = typename NBSLevel0Type::IdType; - - using IndexType = typename NBSLevel0Type::IndexType; - - using Cells = typename NBSLevel0Type::Cells; - - using CellType = typename Cells::CellType; - - using execution_space = typename NBSLevel0Type::execution_space; - - using memory_space = typename NBSLevel0Type::memory_space; - - using mdrPolicyFindPairs = typename NBSLevel0Type::mdrPolicyFindPairs; - - using HeadType = typename NBSLevel0Type::HeadType; - - using NextType = typename NBSLevel0Type::NextType; - - template - friend class NBSLevels; - -protected: - - int32 level_ = 0; - - -public: - - TypeInfoNV("NBSLevel0"); - - INLINE_FUNCTION_HD - NBSLevel(){} - - NBSLevel( - int32 lvl, - const box& domain, - real cellSize, - real sizeRatio, - const ViewType1D& position, - const ViewType1D& diam) - : - NBSLevel0Type( - domain, - cellSize, - sizeRatio, - position, - diam, - lvl==0), - level_(lvl) - {} - - INLINE_FUNCTION_HD - NBSLevel(const NBSLevel&) = default; - - INLINE_FUNCTION_HD - NBSLevel& operator = (const NBSLevel&) = default; - - INLINE_FUNCTION_HD - ~NBSLevel() = default; - - INLINE_FUNCTION_HD - auto level()const - { - return level_; - } - - template - INLINE_FUNCTION_H - int32 findPairsCountCross(PairsContainer& pairs, NBSLevel& upperLevel) - { - - mdrPolicyFindPairs - mdrPolicy( - {0,0,0}, - {this->nx(),this->ny(),this->nz()} ); - - int32 notInsertedPairs; - - Kokkos::parallel_reduce ( - "NBSLevel::findPairsCountCross", - mdrPolicy, - CLASS_LAMBDA_HD(int32 i, int32 j, int32 k, int32& getFullUpdate){ - #include "NBSCrossLoop.hpp" - }, notInsertedPairs); - - return notInsertedPairs; - } - - -}; - -INLINE_FUNCTION_HD -int32x3 mapIndexLevels( const int32x3& ind, int32 lowerLevel, int32 upperLevel) -{ - int32 a = pow(2, static_cast(upperLevel-lowerLevel)); - return ind/a; -} - - -} - -#endif diff --git a/src/Interaction/contactSearch/methods/NBSLevel0.hpp b/src/Interaction/contactSearch/methods/NBSLevel0.hpp deleted file mode 100644 index d9ae2f83..00000000 --- a/src/Interaction/contactSearch/methods/NBSLevel0.hpp +++ /dev/null @@ -1,240 +0,0 @@ -/*------------------------------- 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 __NBSLevel0_hpp__ -#define __NBSLevel0_hpp__ - -#include "mapperNBS.hpp" - -namespace pFlow -{ - - -template -class NBSLevel0 -: - public mapperNBS -{ -public: - - using MapperType = mapperNBS; - - using cellIterator = typename MapperType::cellIterator; - - using IdType = typename MapperType::IdType; - - using IndexType = typename MapperType::IndexType; - - using Cells = typename MapperType::Cells; - - using CellType = typename Cells::CellType; - - using execution_space = typename MapperType::execution_space; - - using memory_space = typename MapperType::memory_space; - - using HeadType = typename MapperType::HeadType; - - using NextType = typename MapperType::NextType; - - struct TagFindPairs{}; - - -protected: - - real sizeRatio_ = 1.0; - - // borrowed ownership - ViewType1D diameter_; - - - using mdrPolicyFindPairs = - Kokkos::MDRangePolicy< - Kokkos::Rank<3>, - Kokkos::Schedule, - execution_space>; - - static INLINE_FUNCTION_HD - void Swap(int32& x, int32& y) - { - int32 tmp = x; - x = y; - y = tmp; - } - -public: - - TypeInfoNV("NBSLevel0"); - - INLINE_FUNCTION_HD - NBSLevel0(){} - - NBSLevel0( - const box& domain, - real cellSize, - const ViewType1D& position, - const ViewType1D& diam) - : - MapperType(domain, cellSize, position), - diameter_(diam) - {} - - NBSLevel0( - const box& domain, - int32 nx, - int32 ny, - int32 nz, - const ViewType1D& position, - const ViewType1D& diam) - : - MapperType(domain, nx, ny, nz, position), - diameter_(diam) - { } - - NBSLevel0( - const box& domain, - real cellSize, - real sizeRatio, - const ViewType1D& position, - const ViewType1D& diam, - bool nextOwner = true) - : - MapperType(domain, cellSize, position, nextOwner), - sizeRatio_(sizeRatio), - diameter_(diam) - {} - - INLINE_FUNCTION_HD - NBSLevel0(const NBSLevel0&) = default; - - INLINE_FUNCTION_HD - NBSLevel0& operator = (const NBSLevel0&) = default; - - INLINE_FUNCTION_HD - ~NBSLevel0()=default; - - - INLINE_FUNCTION_HD - auto sizeRatio()const - { - return sizeRatio_; - } - - INLINE_FUNCTION_HD - auto& diameter() - { - return diameter_; - } - - // - Perform the broad search to find pairs - // with force = true, perform broad search regardless of - // updateFrequency_ value - // on all the points in the range of [0,numPoints_) - template - bool broadSearch(PairsContainer& pairs, range activeRange) - { - - - this->build(activeRange); - - findPairs(pairs); - - return true; - } - - // - Perform the broad search to find pairs, - // ignore particles with incld(i) = true, - // with force = true, perform broad search regardless of - // updateFrequency_ value - template - bool broadSearch(PairsContainer& pairs, range activeRange, IncludeFunction incld) - { - - this->build(activeRange, incld); - - findPairs(pairs); - - return true; - } - - template - INLINE_FUNCTION_H - bool findPairs(PairsContainer& pairs) - { - - - int32 getFull = 1; - - - // loop until the container size fits the numebr of contact pairs - while (getFull > 0) - { - - getFull = findPairsCount(pairs); - - if(getFull) - { - // - resize the container - // note that getFull now shows the number of failed insertions. - uint32 len = max(getFull,500) ; - - auto oldCap = pairs.capacity(); - - pairs.increaseCapacityBy(len); - - INFORMATION<< "The contact pair container capacity increased from "<< - oldCap << " to "< - INLINE_FUNCTION_H - int32 findPairsCount(PairsContainer& pairs) - { - mdrPolicyFindPairs - mdrPolicy( - {0,0,0}, - {this->nx(),this->ny(),this->nz()} ); - - int32 notInsertedPairs; - - Kokkos::parallel_reduce ( - "NBSLevel0::findPairs", - mdrPolicy, - CLASS_LAMBDA_HD(int32 i, int32 j, int32 k, int32& getFullUpdate){ - #include "NBSLoop.hpp" - }, notInsertedPairs); - - return notInsertedPairs; - - } - -}; - -} // pFlow - -#endif // __NBSLevel0_hpp__ diff --git a/src/Interaction/contactSearch/methods/NBSLevels.hpp b/src/Interaction/contactSearch/methods/NBSLevels.hpp deleted file mode 100644 index 30603bd3..00000000 --- a/src/Interaction/contactSearch/methods/NBSLevels.hpp +++ /dev/null @@ -1,438 +0,0 @@ -#ifndef __NBSLevels_hpp__ -#define __NBSLevels_hpp__ - -#include "NBSLevel.hpp" -#include "NBSLevel0.hpp" -#include "KokkosTypes.hpp" - -namespace pFlow -{ - -template -class NBSLevels -{ - -public: - - using NBSLevelType = NBSLevel; - - using cellIterator = typename NBSLevelType::cellIterator; - - using IdType = typename NBSLevelType::IdType; - - using IndexType = typename NBSLevelType::IndexType; - - using Cells = typename NBSLevelType::Cells; - - using CellType = typename Cells::CellType; - - using execution_space = typename NBSLevelType::execution_space; - - using memory_space = typename NBSLevelType::memory_space; - - using realRange = kPair; - -protected: - - real minSize_; - - real maxSize_; - - int32 numLevels_=1; - - Vector nbsLevels_; - - ViewType1D sizeRangeLevels_; - - ViewType1D sizeRangeLevelsHost_; - - ViewType1D maxSizeLevels_; - - ViewType1D maxSizeLevelsHost_; - - ViewType1D particleLevel_; - - range activeRange_{0,0}; - - using rangePolicyType = - Kokkos::RangePolicy< - Kokkos::IndexType, - Kokkos::Schedule, - execution_space>; - - int32 setNumLevels() - { - - int32 maxOvermin = static_cast(maxSize_/minSize_); - - if (maxOvermin <=1) - return 1; - else if(maxOvermin<=3) - return 2; - else if(maxOvermin<=7) - return 3; - else if(maxOvermin<15) - return 4; - else if(maxOvermin<31) - return 5; - else if(maxOvermin<63) - return 6; - else if(maxOvermin <127) - return 7; - else - { - fatalErrorInFunction<< - "size ratio is not valid for multi-grid NBS "<< maxOvermin<=0; lvl--) - { - - if(lvl == 0 ) lvl_minD = 0.01*minSize_; - - sizeRangeLevelsHost_[lvl] = {lvl_minD, lvl_maxD}; - maxSizeLevelsHost_[lvl] = lvl_maxD; - lvl_maxD = lvl_minD; - lvl_minD /= 2.0; - } - - copy(sizeRangeLevels_, sizeRangeLevelsHost_); - copy(maxSizeLevels_, maxSizeLevelsHost_); - - REPORT(2)<<"Grids with "<< yellowText(numLevels_)<< " levels have been created."<& position, - const ViewType1D& diam) - { - - - for(int32 lvl = 0; lvl nbsLevels_[0].capacity()) - { - nbsLevels_[0].checkAllocateNext(activeRange_.second); - - auto next0 = nbsLevels_[0].next(); - - for(int32 lvl=1; lvl& position, - const ViewType1D& diam) - : - minSize_(minSize), - maxSize_(maxSize), - numLevels_(setNumLevels()), - nbsLevels_("nbsLevels", numLevels_, numLevels_, RESERVE()), - sizeRangeLevels_("sizeRangeLevels", numLevels_), - sizeRangeLevelsHost_("sizeRangeLevelsHost", numLevels_), - maxSizeLevels_("maxSizeLevels", numLevels_), - maxSizeLevelsHost_("maxSizeLevelsHost", numLevels_) - { - - setDiameterRange(sizeRatio); - - initLevels(domain, sizeRatio, position, diam); - } - - auto getCellIterator(int32 lvl)const - { - return nbsLevels_[lvl].getCellIterator(); - } - - int32 numLevels()const - { - return numLevels_; - } - - Cells getCells(int32 lvl)const - { - return nbsLevels_[lvl].getCells(); - } - - template - INLINE_FUNCTION_H - bool findPairs(PairsContainer& pairs) - { - - int32 getFull = 1; - - // loop until the container size fits the numebr of contact pairs - while (getFull > 0) - { - - getFull = findPairsCount(pairs); - - if(getFull) - { - // - resize the container - // note that getFull now shows the number of failed insertions. - uint32 len = max(getFull,100) ; - - auto oldCap = pairs.capacity(); - - pairs.increaseCapacityBy(len); - - INFORMATION<< "The contact pair container capacity increased from "<< - oldCap << " to "< - INLINE_FUNCTION_H - int32 findPairsCount(PairsContainer& pairs) - { - - int32 notInsertedCount = 0; - - for(int32 lvl=0; lvl1) head1 = nbsLevels_[1].head(); - if(numLevels_>2) head2 = nbsLevels_[2].head(); - if(numLevels_>3) head3 = nbsLevels_[3].head(); - if(numLevels_>4) head4 = nbsLevels_[4].head(); - if(numLevels_>5) head5 = nbsLevels_[5].head(); - if(numLevels_>6) head6 = nbsLevels_[6].head(); - - - - Kokkos::parallel_for( - "NBSLevels::build", - rPolicy, - LAMBDA_HD(int32 i){ - - int8 lvl = particleLevel[i]; - auto ind = nbsLevel0.pointIndex(pointPosition[i]); - ind = mapIndexLevels(ind, 0, lvl); - int32 old; - if(lvl==0) - old =Kokkos::atomic_exchange(&head0(ind.x(), ind.y(), ind.z()),i); - else if(lvl==1) - old =Kokkos::atomic_exchange(&head1(ind.x(), ind.y(), ind.z()),i); - else if(lvl==2) - old =Kokkos::atomic_exchange(&head2(ind.x(), ind.y(), ind.z()),i); - else if(lvl==3) - old =Kokkos::atomic_exchange(&head3(ind.x(), ind.y(), ind.z()),i); - else if(lvl==4) - old =Kokkos::atomic_exchange(&head4(ind.x(), ind.y(), ind.z()),i); - else if(lvl==5) - old =Kokkos::atomic_exchange(&head5(ind.x(), ind.y(), ind.z()),i); - else if(lvl==6) - old =Kokkos::atomic_exchange(&head6(ind.x(), ind.y(), ind.z()),i); - - next(i) = old; - }); - - Kokkos::fence(); - } - - template - INLINE_FUNCTION_H - void build(range activeRange, IncludeFunction incld) - { - // nullify next and heads - findParticleLevel(activeRange.first, activeRange.second); - manageAllocateNext(activeRange); - nullify(activeRange); - - - rangePolicyType rPolicy(activeRange.first, activeRange.second); - - auto nbsLevel0 = nbsLevels_[0]; - auto pointPosition = nbsLevel0.pointPosition(); - auto particleLevel = particleLevel_; - auto next = nbsLevel0.next(); - auto head0 = nbsLevel0.head(); - - typename NBSLevelType::HeadType head1, head2, head3, head4, head5, head6; - - if(numLevels_>1) head1 = nbsLevels_[1].head(); - if(numLevels_>2) head2 = nbsLevels_[2].head(); - if(numLevels_>3) head3 = nbsLevels_[3].head(); - if(numLevels_>4) head4 = nbsLevels_[4].head(); - if(numLevels_>5) head5 = nbsLevels_[5].head(); - if(numLevels_>6) head6 = nbsLevels_[6].head(); - - Kokkos::parallel_for( - "NBSLevels::build", - rPolicy, - LAMBDA_HD(int32 i){ - if(!incld(i)) return; - - int8 lvl = particleLevel[i]; - auto ind = nbsLevel0.pointIndex(pointPosition[i]); - - ind = mapIndexLevels(ind, 0, lvl); - int32 old; - if(lvl==0) - old =Kokkos::atomic_exchange(&head0(ind.x(), ind.y(), ind.z()),i); - else if(lvl==1) - old =Kokkos::atomic_exchange(&head1(ind.x(), ind.y(), ind.z()),i); - else if(lvl==2) - old =Kokkos::atomic_exchange(&head2(ind.x(), ind.y(), ind.z()),i); - else if(lvl==3) - old =Kokkos::atomic_exchange(&head3(ind.x(), ind.y(), ind.z()),i); - else if(lvl==4) - old =Kokkos::atomic_exchange(&head4(ind.x(), ind.y(), ind.z()),i); - else if(lvl==5) - old =Kokkos::atomic_exchange(&head5(ind.x(), ind.y(), ind.z()),i); - else if(lvl==6) - old =Kokkos::atomic_exchange(&head6(ind.x(), ind.y(), ind.z()),i); - - next(i) = old; - - }); - - Kokkos::fence(); - - } - - bool findParticleLevel(int32 first, int32 last) - { - - if(last > particleLevel_.size()) - { - reallocNoInit(particleLevel_,last); - } - - auto diameter = nbsLevels_[0].diameter(); - auto const maxSizes = maxSizeLevels_; - auto particleLevel = particleLevel_; - auto const sizeRatio = 0.999*nbsLevels_[0].sizeRatio(); - - int8 maxLvl = sizeRangeLevels_.size(); - - rangePolicyType rPolicy(first, last); - - Kokkos::parallel_for( - "NBSLevels::findParticleLevel", - rPolicy, - LAMBDA_HD(int32 i) - { - for(int8 lvl = 0; lvl(-1); - }); - Kokkos::fence(); - - return true; - } - - -}; //NBSLevels - -} - -#endif diff --git a/src/Interaction/contactSearch/methods/NBSLoop.hpp b/src/Interaction/contactSearch/methods/NBSLoop.hpp deleted file mode 100644 index 8aed3e26..00000000 --- a/src/Interaction/contactSearch/methods/NBSLoop.hpp +++ /dev/null @@ -1,101 +0,0 @@ -/*------------------------------- 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. - ------------------------------------------------------------------------------*/ - - -int32 m = this->head_(i,j,k); -CellType currentCell(i,j,k); -int32 n = -1; - -while( m > -1 ) -{ - - auto p_m = this->pointPosition_[m]; - auto d_m = sizeRatio_* diameter_[m]; - - // the same cell - n = this->next_(m); - - while(n >-1) - { - - auto p_n = this->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 = this->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 = this->head_(neighborCell.x(), neighborCell.y(), neighborCell.z()); - while( n>-1) - { - - auto p_n = this->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 = this->next_[n]; - } - } - - } - m = this->next_[m]; -} - diff --git a/src/Interaction/contactSearch/methods/cellBased/NBS/NBS.cpp b/src/Interaction/contactSearch/methods/cellBased/NBS/NBS.cpp new file mode 100644 index 00000000..733313b4 --- /dev/null +++ b/src/Interaction/contactSearch/methods/cellBased/NBS/NBS.cpp @@ -0,0 +1,69 @@ +/*------------------------------- 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 "NBS.hpp" + +pFlow::NBS::NBS +( + const dictionary& dict, + const box& domainBox, + real minBSSize, + real maxBSSize, + const deviceViewType1D &position, + const pFlagTypeDevice &flags, + const deviceViewType1D &diam, + uint32 nWallPoints, + uint32 nWallElements, + const ViewType1D& wallPoints, + const ViewType1D& wallVertices, + const ViewType1D& wallNormals +) +: + particleWallContactSearchs( + dict, + domainBox, + minBSSize, + maxBSSize, + position, + flags, + diam), + sizeRatio_(max(dict.getVal("sizeRatio"), 1.0)), + cellExtent_(max(dict.getVal("cellExtent"), 0.5)), + adjustableBox_(dict.getVal("adjustableBox")), + NBSLevel0_ + ( + this->domainBox_, + maxBSSize, + sizeRatio_, + position, + flags, + adjustableBox_() + ), + cellsWallLevel0_ + ( + cellExtent_, + nWallPoints, + nWallElements, + wallPoints, + wallVertices, + wallNormals + ) +{ +} diff --git a/src/Interaction/contactSearch/methods/cellBased/NBS/NBS.hpp b/src/Interaction/contactSearch/methods/cellBased/NBS/NBS.hpp new file mode 100644 index 00000000..11d2e108 --- /dev/null +++ b/src/Interaction/contactSearch/methods/cellBased/NBS/NBS.hpp @@ -0,0 +1,152 @@ +/*------------------------------- 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 __NBS_hpp__ +#define __NBS_hpp__ + +#include "particleWallContactSearchs.hpp" +#include "NBSLevel0.hpp" +#include "cellsWallLevel0.hpp" +#include "Vector.hpp" + +namespace pFlow +{ + + +class NBS +: + public particleWallContactSearchs +{ +public: + + using CellIterator = typename NBSLevel0::CellIterator; + +private: + + real sizeRatio_ = 1.0; + + real cellExtent_ = 0.5; + + Logical adjustableBox_; + + NBSLevel0 NBSLevel0_; + + cellsWallLevel0 cellsWallLevel0_; + +protected: + + friend particleWallContactSearchs; + + bool impl_broadSearch + ( + csPairContainerType& ppPairs, + csPairContainerType& pwPairs, + const deviceViewType1D& pointPos, + const pFlagTypeDevice& flags, + const deviceViewType1D& diameter + ) + { + bool searchBoxChanged; + if( !NBSLevel0_.broadSearch( + ppPairs, + pointPos, + flags, + diameter, + searchBoxChanged)) + { + fatalErrorInFunction<< + "Error in broadSearch for NBS (particle-particle)"< &position, + const pFlagTypeDevice &flags, + const deviceViewType1D &diam, + uint32 nWallPoints, + uint32 nWallElements, + const ViewType1D& wallPoints, + const ViewType1D& wallVertices, + const ViewType1D& wallNormals ); + + + INLINE_FUNCTION_HD + NBS(const NBS&) = default; + + INLINE_FUNCTION_HD + NBS(NBS&&) = default; + + INLINE_FUNCTION_HD + NBS& operator = (const NBS&) = default; + + INLINE_FUNCTION_HD + NBS& operator = (NBS&&) = default; + + INLINE_FUNCTION_HD + ~NBS()=default; + + + //// - Methods + + uint32 numLevels()const + { + return 1; + } + + auto getCellIterator([[maybe_unused]] uint32 lvl)const + { + return NBSLevel0_.getCellIterator(); + } + + Vector getDomainCellsLevels()const + { + return Vector("Cells", 1, NBSLevel0_.getDomainCells()); + } + +}; + +} + +#endif diff --git a/src/Interaction/contactSearch/methods/cellBased/NBS/NBSLevel0.cpp b/src/Interaction/contactSearch/methods/cellBased/NBS/NBSLevel0.cpp new file mode 100644 index 00000000..8e43c35f --- /dev/null +++ b/src/Interaction/contactSearch/methods/cellBased/NBS/NBSLevel0.cpp @@ -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. + +-----------------------------------------------------------------------------*/ + +#include "NBSLevel0.hpp" +#include "streams.hpp" + +bool pFlow::NBSLevel0::findPairs +( + csPairContainerType &pairs, + const deviceViewType1D &pointPos, + const pFlagTypeDevice &flags, + const deviceViewType1D &diameter +) +{ + uint32 getFull = 1; + + // loop until the container size fits the numebr of contact pairs + while (getFull > 0) + { + + getFull = pFlow::NBSLevel0Kernels::findPairsCount + ( + pairs, + sizeRatio_, + pointPos, + flags, + diameter, + getCellIterator() + ); + + if(getFull) + { + // - resize the container + // note that getFull now shows the number of failed insertions. + uint32 len = max(getFull,500u) ; + + auto oldCap = pairs.capacity(); + + pairs.increaseCapacityBy(len); + + INFORMATION<< "The contact pair container capacity increased from "<< + oldCap << " to "<& pointPos, + const pFlagTypeDevice& flags, + bool adjustableBox +) +: + mapperNBS + ( + domain, + cellSize, + pointPos, + flags, + adjustableBox, + true + ), + sizeRatio_(sizeRatio) +{ + +} + +bool pFlow::NBSLevel0::broadSearch +( + csPairContainerType &pairs, + const deviceViewType1D &pointPos, + const pFlagTypeDevice &flags, + const deviceViewType1D &diameter, + bool& searchBoxChanged +) +{ + if(!build(pointPos, flags, searchBoxChanged)) + { + fatalErrorInFunction; + return false; + } + + if(!findPairs(pairs, pointPos, flags, diameter)) + { + fatalErrorInFunction; + return false; + } + + return true; +} + + diff --git a/src/Interaction/contactSearch/methods/cellBased/NBS/NBSLevel0.hpp b/src/Interaction/contactSearch/methods/cellBased/NBS/NBSLevel0.hpp new file mode 100644 index 00000000..2f87c151 --- /dev/null +++ b/src/Interaction/contactSearch/methods/cellBased/NBS/NBSLevel0.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 __NBSLevel0_hpp__ +#define __NBSLevel0_hpp__ + +#include "NBSLevel0Kernels.hpp" +#include "mapperNBS.hpp" + +namespace pFlow +{ + + +class NBSLevel0 +: + public mapperNBS +{ +public: + + using MapperType = mapperNBS; + + using CellIterator = typename MapperType::CellIterator; + + using HeadType = typename MapperType::HeadType; + + using NextType = typename MapperType::NextType; + + +private: + + real sizeRatio_ = 1.0; + + bool findPairs + ( + csPairContainerType& pairs, + const deviceViewType1D& pointPos, + const pFlagTypeDevice& flags, + const deviceViewType1D& diameter + ); + +public: + + TypeInfoNV("NBSLevel0"); + + INLINE_FUNCTION_HD + NBSLevel0() = default; + + NBSLevel0( + const box& domain, + real cellSize, + real sizeRatio, + const deviceViewType1D& pointPos, + const pFlagTypeDevice& flags, + bool adjustableBox); + + INLINE_FUNCTION_HD + NBSLevel0(const NBSLevel0&) = default; + + INLINE_FUNCTION_HD + NBSLevel0& operator = (const NBSLevel0&) = default; + + INLINE_FUNCTION_HD + ~NBSLevel0()=default; + + + bool broadSearch( + csPairContainerType& pairs, + const deviceViewType1D& pointPos, + const pFlagTypeDevice& flags, + const deviceViewType1D& diameter, + bool& searchBoxChanged); + + + + +}; + +} // pFlow + +#endif // __NBSLevel0_hpp__ diff --git a/src/Interaction/contactSearch/methods/cellBased/NBS/NBSLevel0Kernels.hpp b/src/Interaction/contactSearch/methods/cellBased/NBS/NBSLevel0Kernels.hpp new file mode 100644 index 00000000..31df063c --- /dev/null +++ b/src/Interaction/contactSearch/methods/cellBased/NBS/NBSLevel0Kernels.hpp @@ -0,0 +1,83 @@ +/*------------------------------- 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 "mapperNBS.hpp" +#include "contactSearchGlobals.hpp" + +#include "streams.hpp" + +namespace pFlow::NBSLevel0Kernels +{ + +using mdrPolicyFindPairs = + Kokkos::MDRangePolicy< + Kokkos::IndexType, + Kokkos::Rank<3>, + Kokkos::Schedule, + DefaultExecutionSpace>; + +template +INLINE_FUNCTION_HD +void Swap(T& x, T& y) +{ + T tmp = x; + x = y; + y = tmp; +} + +INLINE_FUNCTION_HD +bool sphereSphereCheck(const realx3& p1, const realx3 p2, real d1, real d2) +{ + return length(p2-p1) < 0.5*(d2+d1); +} + +inline +uint32 findPairsCount +( + csPairContainerType& pairs, + real sizeRatio, + const deviceViewType1D& pointPos, + const pFlagTypeDevice& flags, + const deviceViewType1D& diameter, + mapperNBS::CellIterator cellIter +) +{ + + auto nCells = cellIter.numCells(); + + mdrPolicyFindPairs + mdrPolicy( + {0,0,0}, + {nCells.x(), nCells.y(), nCells.z()} ); + + uint32 notInsertedPairs = 0u; + + + Kokkos::parallel_reduce ( + "pFlow::NBSLevel0Kernels::findPairsCount", + mdrPolicy, + LAMBDA_HD(uint32 i, uint32 j, uint32 k, uint32& getFullUpdate){ + #include "NBSLoop.hpp" + }, notInsertedPairs); + + return notInsertedPairs; +} + +} \ No newline at end of file diff --git a/src/Interaction/contactSearch/methods/cellBased/NBS/NBSLoop.hpp b/src/Interaction/contactSearch/methods/cellBased/NBS/NBSLoop.hpp new file mode 100644 index 00000000..ab3eeea7 --- /dev/null +++ b/src/Interaction/contactSearch/methods/cellBased/NBS/NBSLoop.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. + +-----------------------------------------------------------------------------*/ + + +uint32 m = cellIter.start(i,j,k); +int32x3 currentCell(i,j,k); +uint32 n = mapperNBS::NoPos; + +while( m != mapperNBS::NoPos) +{ + + auto p_m = pointPos[m]; + auto d_m = sizeRatio* diameter[m]; + + // the same cell + n = cellIter.getNext(m); + + while(n != mapperNBS::NoPos) + { + auto p_n = pointPos[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( pairs.insert(lm,ln) == -1) + { + getFullUpdate++; + } + } + + n = cellIter.getNext(n);; + } + + // neighbor cells + int32x3 neighborCell; + for(uint32 ni=0u; ni<13; ni++) + { + if(ni==0) neighborCell = currentCell + int32x3( 0, 0,-1); + else if(ni==1) neighborCell = currentCell + int32x3(-1, 0,-1); + else if(ni==2) neighborCell = currentCell + int32x3(-1, 0, 0); + else if(ni==3) neighborCell = currentCell + int32x3(-1, 0, 1); + else if(ni==4) neighborCell = currentCell + int32x3( 0,-1,-1); + else if(ni==5) neighborCell = currentCell + int32x3( 0,-1, 0); + else if(ni==6) neighborCell = currentCell + int32x3( 0,-1, 1); + else if(ni==7) neighborCell = currentCell + int32x3(-1,-1,-1); + else if(ni==8) neighborCell = currentCell + int32x3(-1,-1, 0); + else if(ni==9) neighborCell = currentCell + int32x3(-1,-1, 1); + else if(ni==10) neighborCell = currentCell + int32x3( 1,-1,-1); + else if(ni==11) neighborCell = currentCell + int32x3( 1,-1, 0); + else if(ni==12) neighborCell = currentCell + int32x3( 1,-1, 1); + + if( neighborCell.x()>=0 && neighborCell.y()>=0 && neighborCell.z()>=0 && + neighborCell.x()ln) Swap(lm,ln); + if( pairs.insert(lm,ln) == -1) + { + getFullUpdate++; + } + } + n = cellIter.next(n); + } + } + } + m = cellIter.next(m); +} + diff --git a/src/Interaction/contactSearch/methods/cellBased/NBS/cellsWallLevel0.cpp b/src/Interaction/contactSearch/methods/cellBased/NBS/cellsWallLevel0.cpp new file mode 100644 index 00000000..00932281 --- /dev/null +++ b/src/Interaction/contactSearch/methods/cellBased/NBS/cellsWallLevel0.cpp @@ -0,0 +1,209 @@ +/*------------------------------- 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 "cellsWallLevel0.hpp" +#include "streams.hpp" + +pFlow::cellsWallLevel0::cellsWallLevel0 +( + real cellExtent, + uint32 numPoints, + uint32 numElements, + const ViewType1D &points, + const ViewType1D &vertices, + const ViewType1D& normals +) +: + cellExtent_( max(cellExtent, 0.5 ) ), + numElements_(numElements), + numPoints_(numPoints), + vertices_(vertices), + points_(points), + normals_(normals) +{ + allocateArrays(); +} + +bool pFlow::cellsWallLevel0::resetElements +( + uint32 numElements, + uint32 numPoints, + const ViewType1D& points, + const ViewType1D& vertices, + const ViewType1D& normals +) +{ + + numElements_ = numElements; + numPoints_ = numPoints; + points_ = points; + vertices_ = vertices; + normals_ = normals; + + allocateArrays(); + + return true; +} + +bool pFlow::cellsWallLevel0::broadSearch +( + csPairContainerType &pairs, + const cells& searchBox, + const mapperNBS::CellIterator &particleMap, + const deviceViewType1D& pPoints, + const deviceViewType1D& pDiams, + real sizeRatio +) +{ + + // map walls onto the cells + + this->build(searchBox); + + this->particleWallFindPairs(pairs, particleMap, pPoints, pDiams, sizeRatio); + + return true; +} + +bool pFlow::cellsWallLevel0::build(const cells & searchBox) +{ + + Kokkos::parallel_for( + "pFlow::cellsWallLevel0::build", + deviceRPolicyStatic(0,numElements_), + CLASS_LAMBDA_HD(uint32 i) + { + auto v = vertices_[i]; + auto p1 = points_[v.x()]; + auto p2 = points_[v.y()]; + auto p3 = points_[v.z()]; + + realx3 minP; + realx3 maxP; + + searchBox.extendBox(p1, p2, p3, cellExtent_, minP, maxP); + elementBox_[i] = iBoxType(searchBox.pointIndex(minP), searchBox.pointIndex(maxP)); + }); + Kokkos::fence(); + + return true; +} + +bool pFlow::cellsWallLevel0::particleWallFindPairs +( + csPairContainerType &pairs, + const mapperNBS::CellIterator &particleMap, + const deviceViewType1D& pPoints, + const deviceViewType1D& pDiams, + real sizeRatio +) +{ + + uint32 getFull = 1; + + while (getFull) + { + + getFull = findPairsElementRangeCount(pairs, particleMap, pPoints, pDiams, sizeRatio); + + if(getFull) + { + // - resize the container + // note that getFull now shows the number of failed insertions. + uint32 len = max(getFull, 50u); + auto oldCap = pairs.capacity(); + pairs.increaseCapacityBy(len); + + INFORMATION<<"Contact pair container capacity increased from "<< + oldCap << " to " + << pairs.capacity() <<" in cellsWallLevel0."<& pPoints, + const deviceViewType1D& pDiams, + real sizeRatio +) +{ + uint32 getFull =0; + + + Kokkos::parallel_reduce( + "pFlow::cellsWallLevel0::findPairsElementRangeCount", + tpPWContactSearch(numElements_, Kokkos::AUTO), + LAMBDA_HD( + const typename tpPWContactSearch::member_type & teamMember, + uint32& valueToUpdate){ + + const uint32 iTri = teamMember.league_rank(); + + const auto triBox = elementBox_[iTri]; + const auto triPlane = infinitePlane( + normals_[iTri], + points_[vertices_[iTri].x()]); + + uint32 getFull2 = 0; + + auto bExtent = boxExtent(triBox); + uint32 numCellBox = bExtent.x()*bExtent.y()*bExtent.z(); + + Kokkos::parallel_reduce( + Kokkos::TeamThreadRange( teamMember, numCellBox ), + [&] ( const uint32 linIndex, uint32 &innerUpdate ) + { + + int32x3 cell; + indexToCell(linIndex, triBox, cell); + + uint32 n = particleMap.start(cell.x(),cell.y(),cell.z()); + + while( n != particleMap.NoPos) + { + // id is wall id the pair is (particle id, wall id) + if( abs(triPlane.pointFromPlane(pPoints[n]))< pDiams[n]*sizeRatio*cellExtent_) + { + if( pairs.insert( + static_cast(n), + static_cast(iTri) ) == -1 ) + innerUpdate++; + } + n = particleMap.next(n); + + } + + }, + getFull2 + ); + + if ( teamMember.team_rank() == 0 ) valueToUpdate += getFull2; + }, + getFull + ); + return getFull; +} \ No newline at end of file diff --git a/src/Interaction/contactSearch/methods/cellBased/NBS/cellsWallLevel0.hpp b/src/Interaction/contactSearch/methods/cellBased/NBS/cellsWallLevel0.hpp new file mode 100644 index 00000000..da7d77d1 --- /dev/null +++ b/src/Interaction/contactSearch/methods/cellBased/NBS/cellsWallLevel0.hpp @@ -0,0 +1,153 @@ +/*------------------------------- 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 __cellsWallLevel0_hpp__ +#define __cellsWallLevel0_hpp__ + +#include "contactSearchGlobals.hpp" +#include "contactSearchFunctions.hpp" +#include "mapperNBS.hpp" +#include "iBox.hpp" + + + +namespace pFlow +{ + +class cellsWallLevel0 +{ +public: + + using execution_space = csExecutionSpace; + + using memory_space = typename execution_space::memory_space; + + using iBoxType = iBox; + + class TagFindCellRange2{}; + +private: + + // - box extent + real cellExtent_ = 0.5; + + // - number of triangle elements + uint32 numElements_ = 0; + + // - number of points + uint32 numPoints_ = 0; + + // - ref to vectices (borrowed) + ViewType1D vertices_; + + // - ref to points in the trisurface (borrowed) + ViewType1D points_; + + // - ref to normal vectors of triangles (borrowed) + ViewType1D normals_; + + // cell range of element/triangle bounding box + ViewType1D elementBox_; + + + using tpPWContactSearch = Kokkos::TeamPolicy< + execution_space, + Kokkos::Schedule, + Kokkos::IndexType>; + + FUNCTION_H + void allocateArrays() + { + reallocNoInit( elementBox_, numElements_); + } + +public: + + TypeInfoNV("cellsWallLevel0"); + + INLINE_FUNCTION_HD + cellsWallLevel0(){} + + FUNCTION_H + cellsWallLevel0( + real cellExtent, + uint32 numPoints, + uint32 numElements, + const ViewType1D& points, + const ViewType1D& vertices, + const ViewType1D& normals); + + + + // - host call + // reset triangle elements if they have changed + bool resetElements( + uint32 numElements, + uint32 numPoints, + const ViewType1D& points, + const ViewType1D& vertices, + const ViewType1D& normals); + + + INLINE_FUNCTION_HD + iBoxType elementBox(uint32 i)const + { + return elementBox_[i]; + } + + INLINE_FUNCTION_HD + uint32 numElements()const + { + return numElements_; + } + + bool broadSearch( + csPairContainerType& pairs, + const cells& searchBox, + const mapperNBS::CellIterator& particleMap, + const deviceViewType1D& pPoints, + const deviceViewType1D& pDiams, + real sizeRatio); + + + bool build(const cells& searchBox); + + bool particleWallFindPairs( + csPairContainerType& pairs, + const mapperNBS::CellIterator& particleMap, + const deviceViewType1D& pPoints, + const deviceViewType1D& pDiams, + real sizeRatio); + + int32 findPairsElementRangeCount( + csPairContainerType& pairs, + const mapperNBS::CellIterator& particleMap, + const deviceViewType1D& pPoints, + const deviceViewType1D& pDiams, + real sizeRatio); + + + +}; // cellsWallLevel0 + +} // pFlow + + +#endif // __cellsWallLevel0_hpp__ diff --git a/src/Interaction/contactSearch/methods/cellBased/NBS/mapperNBS.cpp b/src/Interaction/contactSearch/methods/cellBased/NBS/mapperNBS.cpp new file mode 100644 index 00000000..b0f16804 --- /dev/null +++ b/src/Interaction/contactSearch/methods/cellBased/NBS/mapperNBS.cpp @@ -0,0 +1,194 @@ +/*------------------------------- 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 "mapperNBS.hpp" +#include "mapperNBSKernels.hpp" +#include "streams.hpp" + +pFlow::uint32 pFlow::mapperNBS::checkInterval_ = 1000; +pFlow::real pFlow::mapperNBS::enlargementFactor_ = 1.1; + +bool pFlow::mapperNBS::setSearchBox +( + const deviceViewType1D &pointPos, + const pFlagTypeDevice &flags, + real cellSize +) +{ + box domainBox = domainCells_.domainBox(); + + + if(adjustableBox_) + { + lastCheckForBox_ = buildCount_; + + realx3 minP; + realx3 maxP; + pFlow::mapperNBSKernels::findPointExtends + ( + pointPos, + flags, + minP, maxP + ); + + minP = max( minP - enlargementFactor_*cellSize, domainBox.minPoint()); + maxP = min( maxP + enlargementFactor_*cellSize, domainBox.maxPoint()); + + box searchBox = {minP, maxP}; + searchCells_ = cells(searchBox, cellSize); + INFORMATION<<"Search box for contact search has changed: "<< + "search box is ["< &pointPos, + const pFlagTypeDevice &flags, + bool adjustableBox, + bool nextOwner +) +: + domainCells_(domain, cellSize), + searchCells_(domain, cellSize), + adjustableBox_(adjustableBox), + nextOwner_(nextOwner) +{ + setSearchBox(pointPos, flags, cellSize); + + allocateArrays(flags.activeRange()); +} + +bool pFlow::mapperNBS::build +( + const deviceViewType1D& pointPos, + const pFlagTypeDevice & flags, + bool& searchBoxChanged +) +{ + auto aRange = flags.activeRange(); + buildCount_++; + if(adjustableBox_ && buildCount_%checkInterval_ == 0) + { + + if(searchBoxChanged = + setSearchBox(pointPos, flags, searchCells_.cellSize());searchBoxChanged) + { + allocateArrays(aRange); + } + + } + else + { + checkAllocateNext(aRange); + nullifyHead(); + nullifyNext(aRange); + } + + if( adjustableBox_ ) + { + if(!pFlow::mapperNBSKernels::buildListsReduce( + searchCells_, + head_, + next_, + pointPos, + flags) ) + { + + buildCount_++; + setSearchBox(pointPos, flags, searchCells_.cellSize()); + + searchBoxChanged = true; + + allocateArrays(flags.activeRange()); + + if(!pFlow::mapperNBSKernels::buildListsReduce( + searchCells_, + head_, + next_, + pointPos, + flags)) + { + fatalErrorInFunction<<"failed to build list in anjustable search box mode!"<; + + using NextType = deviceViewType1D; + + + static constexpr uint32 NoPos = 0xFFFFFFFF; + + class CellIterator + { + private: + HeadType head_; + + NextType next_; + + public: + + CellIterator(const HeadType& head, const NextType& next) + : + head_(head), + next_(next) + {} + + static constexpr uint32 NoPos = 0xFFFFFFFF; + + INLINE_FUNCTION_HD + int32x3 numCells()const { + return int32x3(head_.extent(0), head_.extent(1), head_.extent(2));} + + INLINE_FUNCTION_HD + uint32 start(int32 i, int32 j, int32 k)const { + return head_(i,j,k); } + + INLINE_FUNCTION_HD + uint32 getNext(uint32 n)const { + if(n == NoPos ) return NoPos; + return next_(n); } + + INLINE_FUNCTION_HD + uint32 next(uint32 n)const{ + return next_(n);} + }; + +private: + + cells domainCells_; + + cells searchCells_; + + HeadType head_{"NBS::head",1,1,1}; + + NextType next_{"NBS::next", 1}; + + uint32 nextCapacity_ = 0; + + uint32 lastCheckForBox_ = 0; + + uint32 buildCount_ = 0; + + bool adjustableBox_ = false; + + bool nextOwner_ = true; + + static uint32 checkInterval_; + + static real enlargementFactor_; + + bool setSearchBox( + const deviceViewType1D& pointPos, + const pFlagTypeDevice& flags, + real cellSize + ); + + void allocateArrays(rangeU32 nextRng); + + void checkAllocateNext(rangeU32 nextRng); + + void nullifyHead(); + + void nullifyNext(rangeU32 nextRng); + +public: + + TypeInfoNV("mapperNBS"); + + INLINE_FUNCTION_HD + mapperNBS() = default; + + mapperNBS( + const box& domain, + real cellSize, + const deviceViewType1D& pointPos, + const pFlagTypeDevice& flags, + bool adjustableBox, + bool nextOwner = true); + + INLINE_FUNCTION_HD + mapperNBS(const mapperNBS&) = default; + + INLINE_FUNCTION_HD + mapperNBS(mapperNBS&&) = default; + + INLINE_FUNCTION_HD + mapperNBS& operator = (const mapperNBS&) = default; + + INLINE_FUNCTION_HD + mapperNBS& operator = (mapperNBS&&) = default; + + INLINE_FUNCTION_HD + ~mapperNBS()=default; + + //// - Methods + + auto getCellIterator()const + { + return CellIterator(head_, next_); + } + + const auto& getDomainCells()const + { + return domainCells_; + } + + const auto& getSearchCells()const + { + return searchCells_; + } + + bool build( + const deviceViewType1D& pointPos, + const pFlagTypeDevice& flags, + bool& searchBoxChanged); + + + + +}; + +} // pFlow + +#endif // __mapperNBS_hpp__ + + + + +/* +INLINE_FUNCTION_HD + auto& head() + { + return head_; + } + + INLINE_FUNCTION_HD + auto& next() + { + return next_; + } + + INLINE_FUNCTION_HD + const auto& head()const + { + return head_; + } + + INLINE_FUNCTION_HD + const auto& next()const + { + return next_; + } + + INLINE_FUNCTION_HD + auto& pointPosition() + { + return pointPosition_; + } +*/ \ No newline at end of file diff --git a/src/Interaction/contactSearch/methods/cellBased/NBS/mapperNBSKernels.cpp b/src/Interaction/contactSearch/methods/cellBased/NBS/mapperNBSKernels.cpp new file mode 100644 index 00000000..01141eac --- /dev/null +++ b/src/Interaction/contactSearch/methods/cellBased/NBS/mapperNBSKernels.cpp @@ -0,0 +1,192 @@ + + +/*------------------------------- 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 "mapperNBSKernels.hpp" + + +void pFlow::mapperNBSKernels::findPointExtends +( + const deviceViewType1D& points, + const pFlagTypeDevice& flags, + realx3& minPoint, + realx3& maxPoint +) +{ + if(flags.numActive() == 0) + { + minPoint = {0,0,0}; + maxPoint = {0,0,0}; + return; + } + + real minX; + real minY; + real minZ; + real maxX; + real maxY; + real maxZ; + auto aRange = flags.activeRange(); + Kokkos::parallel_reduce( + "pFlow::mapperNBSKernels::findPointExtends", + deviceRPolicyStatic(aRange.start(), aRange.end()), + LAMBDA_HD( + uint32 i, + real& minXUpdate, + real& minYUpdate, + real& minZUpdate, + real& maxXUpdate, + real& maxYUpdate, + real& maxZUpdate) + { + if(flags(i)) + { + auto p = points(i); + minXUpdate = min(p.x(), minXUpdate); + minYUpdate = min(p.y(), minYUpdate); + minZUpdate = min(p.z(), minZUpdate); + maxXUpdate = max(p.x(), maxXUpdate); + maxYUpdate = max(p.y(), maxYUpdate); + maxZUpdate = max(p.z(), maxZUpdate); + } + + }, + Kokkos::Min(minX), + Kokkos::Min(minY), + Kokkos::Min(minZ), + Kokkos::Max(maxX), + Kokkos::Max(maxY), + Kokkos::Max(maxZ) + ); + + minPoint = {minX, minY, minZ}; + maxPoint = {maxX, maxY, maxZ}; +} + +bool pFlow::mapperNBSKernels::buildListsReduce +( + const cells &searchCell, + const deviceViewType3D &head, + const deviceViewType1D &next, + const deviceViewType1D &points, + const pFlagTypeDevice &flags +) +{ + uint32 numOut = 0; + auto aRange = flags.activeRange(); + + if(flags.isAllActive()) + { + Kokkos::parallel_reduce + ( + "pFlow::mapperNBSKernels::buildListsReduce", + deviceRPolicyStatic(aRange.start(), aRange.end()), + LAMBDA_HD(uint32 i, uint32& valToUpdate) + { + int32x3 ind; + if( searchCell.pointIndexInDomain(points[i], ind) ) + { + uint32 old = Kokkos::atomic_exchange(&head(ind.x(), ind.y(), ind.z()), i); + next[i] = old; + } + else + { + valToUpdate++; + } + }, + numOut + ); + } + else + { + Kokkos::parallel_reduce + ( + "pFlow::mapperNBSKernels::buildListsReduce", + deviceRPolicyStatic(aRange.start(), aRange.end()), + LAMBDA_HD(uint32 i, uint32& valToUpdate) + { + int32x3 ind; + if( flags(i) ) + { + if( searchCell.pointIndexInDomain(points[i], ind) ) + { + uint32 old = Kokkos::atomic_exchange(&head(ind.x(), ind.y(), ind.z()), i); + next[i] = old; + } + else + { + valToUpdate++; + } + } + }, + numOut + ); + } + + return numOut == 0u ; +} + +bool pFlow::mapperNBSKernels::buildLists +( + const cells &searchCell, + const deviceViewType3D &head, + const deviceViewType1D &next, + const deviceViewType1D &points, + const pFlagTypeDevice &flags +) +{ + auto aRange = flags.activeRange(); + if(flags.isAllActive() ) + { + Kokkos::parallel_for + ( + "pFlow::mapperNBSKernels::buildLists", + deviceRPolicyStatic(aRange.start(), aRange.end()), + LAMBDA_HD(uint32 i) + { + auto ind = searchCell.pointIndex(points[i]); + uint32 old = Kokkos::atomic_exchange(&head(ind.x(), ind.y(), ind.z()), i); + next[i] = old; + } + ); + Kokkos::fence(); + } + else + { + Kokkos::parallel_for + ( + "pFlow::mapperNBSKernels::buildLists", + deviceRPolicyStatic(aRange.start(), aRange.end()), + LAMBDA_HD(uint32 i) + { + if( flags(i) ) + { + auto ind = searchCell.pointIndex(points[i]); + uint32 old = Kokkos::atomic_exchange(&head(ind.x(), ind.y(), ind.z()), i); + next[i] = old; + } + } + ); + Kokkos::fence(); + } + + return true; +} diff --git a/src/Interaction/contactSearch/methods/cellBased/NBS/mapperNBSKernels.hpp b/src/Interaction/contactSearch/methods/cellBased/NBS/mapperNBSKernels.hpp new file mode 100644 index 00000000..6730ff22 --- /dev/null +++ b/src/Interaction/contactSearch/methods/cellBased/NBS/mapperNBSKernels.hpp @@ -0,0 +1,49 @@ +/*------------------------------- 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 "phasicFlowKokkos.hpp" +#include "cells.hpp" +#include "pointFlag.hpp" + + +namespace pFlow::mapperNBSKernels +{ + +void findPointExtends( + const deviceViewType1D& points, + const pFlagTypeDevice& flags, + realx3& minPoint, + realx3& maxPoint); + +bool buildListsReduce( + const cells& searchCell, + const deviceViewType3D& head, + const deviceViewType1D& next, + const deviceViewType1D& points, + const pFlagTypeDevice& flags); + +bool buildLists( + const cells& searchCell, + const deviceViewType3D& head, + const deviceViewType1D& next, + const deviceViewType1D& points, + const pFlagTypeDevice& flags); + +} \ No newline at end of file diff --git a/src/Interaction/contactSearch/cells.hpp b/src/Interaction/contactSearch/methods/cellBased/cells.hpp similarity index 62% rename from src/Interaction/contactSearch/cells.hpp rename to src/Interaction/contactSearch/methods/cellBased/cells.hpp index c77b1a69..c4b50813 100644 --- a/src/Interaction/contactSearch/cells.hpp +++ b/src/Interaction/contactSearch/methods/cellBased/cells.hpp @@ -28,58 +28,40 @@ Licence: namespace pFlow { -template class cells { -public: - - using CellType = triple; - -protected: +private: // - domain - box domain_{realx3(0.0), realx3(1.0)}; + box domainBox_{realx3(0.0), realx3(1.0)}; // - cell size - realx3 cellSize_{1,1,1}; - - CellType numCells_{1,1,1}; + real celldx_{1}; + int32x3 numCells_{1,1,1}; // - protected methods INLINE_FUNCTION_H void calculate() { - numCells_ = (domain_.maxPoint()-domain_.minPoint())/cellSize_ + realx3(1.0); - numCells_ = max( numCells_ , CellType(static_cast(1)) ); + numCells_ = (domainBox_.maxPoint()-domainBox_.minPoint())/celldx_ + realx3(1.0); + numCells_ = max( numCells_ , int32x3(1) ); } public: INLINE_FUNCTION_HD - cells() - {} + cells() = default; INLINE_FUNCTION_H cells(const box& domain, real cellSize) : - domain_(domain), - cellSize_(cellSize) + domainBox_(domain), + celldx_(cellSize) { 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; @@ -100,43 +82,36 @@ public: INLINE_FUNCTION_H void setCellSize(real cellSize) { - cellSize_ = cellSize; - calculate(); - } - - INLINE_FUNCTION_H - void setCellSize(realx3 cellSize) - { - cellSize_ = cellSize; + celldx_ = cellSize; calculate(); } INLINE_FUNCTION_HD - realx3 cellSize()const + real cellSize()const { - return cellSize_; + return celldx_; } INLINE_FUNCTION_HD - const CellType& numCells()const + const int32x3& numCells()const { return numCells_; } INLINE_FUNCTION_HD - indexType nx()const + int32 nx()const { return numCells_.x(); } INLINE_FUNCTION_HD - indexType ny()const + int32 ny()const { return numCells_.y(); } INLINE_FUNCTION_HD - indexType nz()const + int32 nz()const { return numCells_.z(); } @@ -149,22 +124,21 @@ public: static_cast(numCells_.z()); } - const auto& domain()const + const auto& domainBox()const { - return domain_; + return domainBox_; } INLINE_FUNCTION_HD - CellType pointIndex(const realx3& p)const + int32x3 pointIndex(const realx3& p)const { - return CellType( (p - domain_.minPoint())/cellSize_ ); + return int32x3( (p - domainBox_.minPoint())/celldx_ ); } INLINE_FUNCTION_HD - bool pointIndexInDomain(const realx3 p, CellType& index)const + bool pointIndexInDomain(const realx3 p, int32x3& index)const { - if( !domain_.isInside(p) ) return false; - + if(!inDomain(p))return false; index = this->pointIndex(p); return true; } @@ -172,11 +146,11 @@ public: INLINE_FUNCTION_HD bool inDomain(const realx3& p)const { - return domain_.isInside(p); + return domainBox_.isInside(p); } INLINE_FUNCTION_HD - bool isInRange(const CellType& cell)const + bool inCellRange(const int32x3& cell)const { if(cell.x()<0)return false; if(cell.y()<0)return false; @@ -188,7 +162,7 @@ public: } INLINE_FUNCTION_HD - bool isInRange(indexType i, indexType j, indexType k)const + bool inCellRange(int32 i, int32 j, int32 k)const { if(i<0)return false; if(j<0)return false; @@ -199,22 +173,7 @@ public: return true; } - INLINE_FUNCTION_HD - void extendBox( - const CellType& p1, - const CellType& p2, - const CellType& p3, - indexType extent, - CellType& minP, - CellType& maxP)const - { - minP = min( min( p1, p2), p3)-extent; - maxP = max( max( p1, p2), p3)+extent; - - minP = bound(minP); - maxP = bound(maxP); - } - + INLINE_FUNCTION_HD void extendBox( const realx3& p1, @@ -224,17 +183,17 @@ public: realx3& minP, realx3& maxP)const { - minP = min(min(p1,p2),p3) - extent*cellSize_ ; - maxP = max(max(p1,p2),p3) + extent*cellSize_ ; + minP = min(min(p1,p2),p3) - extent*celldx_ ; + maxP = max(max(p1,p2),p3) + extent*celldx_ ; minP = bound(minP); maxP = bound(maxP); } INLINE_FUNCTION_HD - CellType bound(CellType p)const + int32x3 bound(int32x3 p)const { - return CellType( + return int32x3( min( numCells_.x()-1, max(0,p.x())), min( numCells_.y()-1, max(0,p.y())), min( numCells_.z()-1, max(0,p.z())) @@ -245,9 +204,9 @@ public: realx3 bound(realx3 p)const { return realx3( - min( domain_.maxPoint().x(), max(domain_.minPoint().x(),p.x())), - min( domain_.maxPoint().y(), max(domain_.minPoint().y(),p.y())), - min( domain_.maxPoint().z(), max(domain_.minPoint().z(),p.z())) + min( domainBox_.maxPoint().x(), max(domainBox_.minPoint().x(),p.x())), + min( domainBox_.maxPoint().y(), max(domainBox_.minPoint().y(),p.y())), + min( domainBox_.maxPoint().z(), max(domainBox_.minPoint().z(),p.z())) ); } }; diff --git a/src/Interaction/contactSearch/methods/mapperNBS.hpp b/src/Interaction/contactSearch/methods/mapperNBS.hpp deleted file mode 100644 index 41b47068..00000000 --- a/src/Interaction/contactSearch/methods/mapperNBS.hpp +++ /dev/null @@ -1,389 +0,0 @@ -/*------------------------------- 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 __mapperNBS_hpp__ -#define __mapperNBS_hpp__ - -#include "cells.hpp" -#include "contactSearchFunctions.hpp" -#include "baseAlgorithms.hpp" -#include "ViewAlgorithms.hpp" - -namespace pFlow -{ - -template -class mapperNBS -: - public cells -{ -public: - - using IdType = int32; - - using IndexType = int32; - - using Cells = cells; - - using CellType = typename Cells::CellType; - - using execution_space = executionSpace; - - using memory_space = typename execution_space::memory_space; - - using HeadType = ViewType3D; - - using NextType = ViewType1D; - - class cellIterator - { - private: - HeadType head_; - - NextType next_; - - public: - - cellIterator(ViewType3D head, ViewType1D next) - : - head_(head), - next_(next) - {} - - INLINE_FUNCTION_HD - Cells cellsSize()const { - return Cells(head_.extent(0), head_.extent(1), head_.extent(2));} - - INLINE_FUNCTION_HD - int32 start(IndexType i, IndexType j, IndexType k)const { - return head_(i,j,k); } - - INLINE_FUNCTION_HD - int32 getNext(int32 n)const { - if(n<0) return n; - return next_(n); } - }; - -protected: - - int32 capacity_ = 1; - - ViewType3D head_; - - ViewType1D next_; - - bool nextOwner_ = true; - - // borrowed ownership - ViewType1D pointPosition_; - - using rangePolicyType = - Kokkos::RangePolicy< - Kokkos::IndexType, - Kokkos::Schedule, - execution_space>; - - INLINE_FUNCTION_H - void nullifyHead() - { - fill( - head_, - range(0,this->nx()), - range(0,this->ny()), - range(0,this->nz()), - static_cast(-1) - ); - } - - void nullifyNext(range nextRng) - { - if(!nextOwner_)return; - fill( - next_, - nextRng, - static_cast(-1) - ); - } - - void nullify() - { - nullifyHead(); - - nullifyNext(range(0,capacity_)); - } - - void nullify(range nextRng) - { - nullifyHead(); - - nullifyNext(nextRng); - } - - - void checkAllocateNext(int newCap) - { - if( capacity_ < newCap) - { - capacity_ = newCap; - if(!nextOwner_)return; - reallocNoInit(next_, capacity_); - } - } - - void allocateHead() - { - reallocNoInit(head_, this->nx(), this->ny(), this->nz()); - } - - - -public: - - TypeInfoNV("mapperNBS"); - - INLINE_FUNCTION_HD - mapperNBS(){} - - mapperNBS( - const box& domain, - real cellSize, - const ViewType1D& position, - bool nextOwner = true) - : - Cells(domain, cellSize), - pointPosition_(position), - head_( - "mapperNBS::head_", - this->nx(), - this->ny(), - this->nz() - ), - next_("mapperNBS::next_",1), //,position.size()), - nextOwner_(nextOwner) - { - checkAllocateNext(pointPosition_.size()); - } - - mapperNBS( - const box& domain, - int32 nx, - int32 ny, - int32 nz, - const ViewType1D& position, - bool nextOwner = true) - : - Cells(domain, nx, ny, nz), - pointPosition_(position), - head_("mapperNBS::head_",nx,ny,nz), - next_("mapperNBS::next_",1), - nextOwner_(nextOwner) - { - checkAllocateNext(pointPosition_.size()); - } - - - INLINE_FUNCTION_HD - mapperNBS(const mapperNBS&) = default; - - INLINE_FUNCTION_HD - mapperNBS& operator = (const mapperNBS&) = default; - - INLINE_FUNCTION_HD - ~mapperNBS()=default; - - //// - Methods - INLINE_FUNCTION_HD - auto capacity()const - { - return capacity_; - } - - cellIterator getCellIterator()const - { - return cellIterator(head_, next_); - } - - bool particlesCapcityChanged(int32 newCap) - { - checkAllocateNext(newCap); - return true; - } - - INLINE_FUNCTION_HD - auto& head() - { - return head_; - } - - INLINE_FUNCTION_HD - auto& next() - { - return next_; - } - - INLINE_FUNCTION_HD - const auto& head()const - { - return head_; - } - - INLINE_FUNCTION_HD - const auto& next()const - { - return next_; - } - - INLINE_FUNCTION_HD - auto& pointPosition() - { - return pointPosition_; - } - - INLINE_FUNCTION_H - void setNext(ViewType1D& next) - { - if(!nextOwner_) - { - next_ = next; - capacity_ = next.size(); - } - } - - - - // - build based on all points in active range - INLINE_FUNCTION_H - void build(range activeRange) - { - checkAllocateNext(activeRange.second); - nullify(activeRange); - - Cells cellIndex = static_cast(*this); - auto points = pointPosition_; - auto next = next_; - auto head = head_; - - rangePolicyType rPolicy(activeRange.first, activeRange.second); - - Kokkos::parallel_for( - "mapperNBS::build", - rPolicy, - LAMBDA_HD(int32 i){ - CellType ind = cellIndex.pointIndex(points[i]); - int32 old = Kokkos::atomic_exchange(&head(ind.x(), ind.y(), ind.z()), i); - next[i] = old; - }); - Kokkos::fence(); - } - - - template - INLINE_FUNCTION_H - void build(range activeRange, IncludeFunction incld) - { - checkAllocateNext(activeRange.second); - nullify(activeRange); - - Cells cellIndex = static_cast(*this); - auto points = pointPosition_; - auto next = next_; - auto head = head_; - - rangePolicyType rPolicy(activeRange.first, activeRange.second); - - Kokkos::parallel_for( - "mapperNBS::build_Include", - rPolicy, - LAMBDA_HD(int32 i){ - if( incld(i) ) - { - CellType ind = cellIndex.pointIndex(points[i]); - auto old = Kokkos::atomic_exchange(&head(ind.x(), ind.y(), ind.z()), i); - next[i] = old; - } - }); - Kokkos::fence(); - - } - - - 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_; - - rangePolicyType rPolicy(activeRange.first, activeRange.second); - - Kokkos::parallel_for( - "mapperNBS::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_; - - rangePolicyType rPolicy(activeRange.first, activeRange.second); - - Kokkos::parallel_for( - "mapperNBS::buildCheckInDomain_Include", - 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(); - } - -}; - -} // pFlow - -#endif // __mapperNBS_hpp__ \ No newline at end of file diff --git a/src/Interaction/contactSearch/methods/multiGridNBS.hpp b/src/Interaction/contactSearch/methods/multiGridNBS.hpp deleted file mode 100644 index dbce390b..00000000 --- a/src/Interaction/contactSearch/methods/multiGridNBS.hpp +++ /dev/null @@ -1,213 +0,0 @@ -/*------------------------------- 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 __multiGridNBS_hpp__ -#define __multiGridNBS_hpp__ - -#include "NBSLevels.hpp" - -namespace pFlow -{ - - -template -class multiGridNBS -{ -public: - - using NBSLevelsType = NBSLevels; - - using cellIterator = typename NBSLevelsType::cellIterator; - - using IdType = typename NBSLevelsType::IdType; - - using IndexType = typename NBSLevelsType::IndexType; - - using Cells = typename NBSLevelsType::Cells; - - using CellType = typename Cells::CellType; - - using execution_space = typename NBSLevelsType::execution_space; - - using memory_space = typename NBSLevelsType::memory_space; - - -protected: - - real sizeRatio_ = 1.0; - - int32 updateFrequency_= 1; - - int32 currentIter_ = 0; - - bool performedSearch_ = false; - - NBSLevelsType NBSLevels_; - -private: - - bool performSearch() - { - if(currentIter_ % updateFrequency_ == 0) - { - currentIter_++; - return true; - - }else - { - currentIter_++; - return false; - } - } - -public: - - TypeInfoNV("multiGridNBS"); - - multiGridNBS( - const dictionary& dict, - const box& domain, - real minSize, - real maxSize, - const ViewType1D& position, - const ViewType1D& diam) - : - sizeRatio_( - max( - dict.getVal("sizeRatio"), - 1.0 - )), - updateFrequency_( - max( - dict.getVal("updateFrequency"), - 1 - )), - NBSLevels_( - domain, - minSize, - maxSize, - sizeRatio_, - position, - diam) - {} - - INLINE_FUNCTION_HD - multiGridNBS(const multiGridNBS&) = default; - - INLINE_FUNCTION_HD - multiGridNBS& operator = (const multiGridNBS&) = default; - - INLINE_FUNCTION_HD - ~multiGridNBS()=default; - - //// - Methods - - bool enterBoadSearch()const - { - return currentIter_%updateFrequency_==0; - } - - bool performedSearch()const - { - return performedSearch_; - } - - int32 numLevels()const - { - return NBSLevels_.numLevels(); - } - - auto getCellsLevels()const - { - Vector cellsLvl("cells", numLevels(), numLevels(), RESERVE()); - - for(int32 lvl=0; lvl - bool broadSearch(PairsContainer& pairs, range activeRange, bool force=false) - { - - if(force) currentIter_ = 0; - performedSearch_ = false; - - if( !performSearch() ) return true; - - - NBSLevels_.build(activeRange); - - NBSLevels_.findPairs(pairs); - - - performedSearch_ = true; - return true; - } - - // - Perform the broad search to find pairs, - // ignore particles with incld(i) = true, - // with force = true, perform broad search regardless of - // updateFrequency_ value - template - bool broadSearch(PairsContainer& pairs, range activeRange, IncludeFunction incld, bool force = false) - { - if(force) currentIter_ = 0; - performedSearch_ = false; - - if( !performSearch() ) return true; - - NBSLevels_.build(activeRange, incld); - - NBSLevels_.findPairs(pairs); - - performedSearch_ = true; - return true; - } - -}; - -} - -#endif diff --git a/src/Interaction/contactSearch/methods/particleWallContactSearchs.cpp b/src/Interaction/contactSearch/methods/particleWallContactSearchs.cpp new file mode 100644 index 00000000..ee414f3b --- /dev/null +++ b/src/Interaction/contactSearch/methods/particleWallContactSearchs.cpp @@ -0,0 +1,78 @@ +/*------------------------------- 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::particleWallContactSearchs::particleWallContactSearchs +( + const dictionary &dict, + const box &domain, + real minSize, + real maxSize, + const ViewType1D &position, + const pFlagTypeDevice &flags, + const ViewType1D &diam +) +: + domainBox_(domain), + updateInterval_ + ( + max(dict.getValOrSet("updateInterval", 1),1u) + ) +{ + +} + +template +bool pFlow::particleWallContactSearchs::broadSearch + ( + uint32 iter, + real t, + real dt, + csPairContainerType& ppPairs, + csPairContainerType& pwPairs, + const deviceViewType1D& pointPos, + const pFlagTypeDevice& flags, + const deviceViewType1D& diameter, + bool force + ) + { + + performedSearch_ = false; + if( !performSearch(iter, force) ) return true; + + if(!getMethod().impl_broadSearch( + ppPairs, + pwPairs, + pointPos, + flags, + diameter)) + { + fatalErrorInFunction<< + "Error in performing particle-particle broadSearch in method"<< + getMethod().typeName()< +class particleWallContactSearchs +{ +public: + + using MethodType = method; + + using IndexType = uint32; + + using execution_space = DefaultExecutionSpace; + + using memory_space = typename execution_space::memory_space; + +private: + + // friend + friend MethodType; + + /// @brief box enclosing the simulation domain (local to processor) + box domainBox_; + + /*/// @brief box enclosing the area for contact search (region with points) + box searchBox_;*/ + + /// @brief update interval in terms of iteration numebr + uint32 updateInterval_= 1; + + /// @brief last iteration number which contact search has been performed + uint32 lastUpdated_ = 0; + + /// @brief performed search? + bool performedSearch_ = false; + +protected: + + inline + auto& getMethod() + { + return static_cast(*this); + } + + inline + const auto& getMethod()const + { + return static_cast(*this); + } + +public: + + particleWallContactSearchs( + const dictionary& dict, + const box& domain, + real minSize, + real maxSize, + const ViewType1D& position, + const pFlagTypeDevice &flags, + const ViewType1D& diam + ); + + bool broadSearch + ( + uint32 iter, + real t, + real dt, + csPairContainerType& ppPairs, + csPairContainerType& pwPairs, + const deviceViewType1D& pointPos, + const pFlagTypeDevice& flags, + const deviceViewType1D& diameter, + bool force = false + ); + + bool performedSearch()const + { + return performedSearch_; + } + + bool performSearch(uint32 iter, bool force = false)const + { + if((iter-lastUpdated_) % updateInterval_ == 0 || iter == 0 || force ) + { + return true; + } + return false; + } + +}; + + +} // pFlow + +#include "particleWallContactSearchs.cpp" + +#endif //__particleWallContactSearchs_hpp__ \ No newline at end of file diff --git a/src/Interaction/contactSearch/wallMappings/cellMapping.hpp b/src/Interaction/contactSearch/wallMappings/cellMapping.hpp deleted file mode 100644 index 5a10c248..00000000 --- a/src/Interaction/contactSearch/wallMappings/cellMapping.hpp +++ /dev/null @@ -1,150 +0,0 @@ -/*------------------------------- 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 __cellMapping_hpp__ -#define __cellMapping_hpp__ - -#include "cellsWallLevel0.hpp" -#include "dictionary.hpp" - - -namespace pFlow -{ - -template< - typename executionSpace - > -class cellMapping -{ -public: - - using cellsWallLevel0Type = cellsWallLevel0; - - using IdType = typename cellsWallLevel0Type::IdType; - - using IndexType = typename cellsWallLevel0Type::IndexType; - - using Cells = typename cellsWallLevel0Type::Cells; - - using CellType = typename Cells::CellType; - - using execution_space = typename cellsWallLevel0Type::execution_space; - - using memory_space = typename cellsWallLevel0Type::memory_space; - - using iBoxType = iBox; - - -protected: - - // - update frequency - int32 updateFrequency_=1; - - real cellExtent_; - - int32 currentIter_ = 0; - - /// a broad search has been occured during last pass? - bool performedSearch_ = false; - - cellsWallLevel0Type cellsWallLevle_; - -private: - - bool performSearch() - { - if(currentIter_ % updateFrequency_ == 0) - { - currentIter_++; - return true; - - }else - { - currentIter_++; - return false; - } - } - -public: - - TypeInfoNV("cellMapping"); - - cellMapping( - const dictionary& dict, - int32 numLevels, - const Vector& ppCells, - int32 numPoints, - int32 numElements, - const ViewType1D& points, - const ViewType1D& vertices - ) - : - updateFrequency_( - max( - dict.getValOrSet( - "updateFrequency", - 1), - 1)), - cellExtent_( - max( - dict.getValOrSet( - "cellExtent", - 0.5), - 0.5)), - cellsWallLevle_( - ppCells[0], - cellExtent_, - numPoints, - numElements, - points, - vertices - ) - {} - - - bool enterBoadSearch()const - { - return currentIter_%updateFrequency_==0; - } - - bool performedSearch()const - { - return performedSearch_; - } - - template - bool broadSearch(PairsContainer& pairs, particleMapType& particleMap, bool force=false) - { - if(force) currentIter_ = 0; - performedSearch_= false; - if(!performSearch())return true; - - cellsWallLevle_.broadSearch(pairs, particleMap); - - performedSearch_ = true; - return true; - } - -}; // cellMapping - -} // pFlow - - -#endif diff --git a/src/Interaction/contactSearch/wallMappings/cellsWallLevel0.hpp b/src/Interaction/contactSearch/wallMappings/cellsWallLevel0.hpp deleted file mode 100644 index 65034507..00000000 --- a/src/Interaction/contactSearch/wallMappings/cellsWallLevel0.hpp +++ /dev/null @@ -1,285 +0,0 @@ -/*------------------------------- 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 __cellsWallLevel0_hpp__ -#define __cellsWallLevel0_hpp__ - -#include "types.hpp" -#include "KokkosTypes.hpp" -#include "cells.hpp" -#include "iBox.hpp" - - - -namespace pFlow -{ - -template< - typename executionSpace - > -class cellsWallLevel0 -: - public cells -{ -public: - - using IdType = int32; - - using IndexType = int32; - - using Cells = cells; - - using CellType = typename Cells::CellType; - - using execution_space = executionSpace; - - using memory_space = typename execution_space::memory_space; - - using iBoxType = iBox; - - class TagFindCellRange2{}; - -protected: - - // - box extent - real cellExtent_ = 0.5; - - // - number of triangle elements - int32 numElements_ = 0; - - // - number of points - int32 numPoints_ = 0; - - // - ref to vectices (borrowed) - ViewType1D vertices_; - - // - ref to points in the trisurface (borrowed) - ViewType1D points_; - - // cell range of element/triangle bounding box - ViewType1D elementBox_; - - - using tpPWContactSearch = Kokkos::TeamPolicy< - execution_space, - Kokkos::Schedule, - Kokkos::IndexType - >; - - using rpFindCellRange2Type = - Kokkos::RangePolicy>; - - - FUNCTION_H - void allocateArrays() - { - reallocNoInit( elementBox_, numElements_); - } - -public: - - TypeInfoNV("cellsWallLevel0"); - - INLINE_FUNCTION_HD - cellsWallLevel0(){} - - FUNCTION_H - cellsWallLevel0( - const Cells& ppCells, - real cellExtent, - int32 numPoints, - int32 numElements, - const ViewType1D& points, - const ViewType1D& vertices - ) - : - Cells(ppCells), - cellExtent_( max(cellExtent, 0.5 ) ), - numElements_(numElements), - numPoints_(numPoints), - vertices_(vertices), - points_(points) - { - - allocateArrays(); - } - - - // - host call - // reset triangle elements if they have changed - bool resetElements( - int32 numElements, - int32 numPoints, - ViewType1D& points, - ViewType1D& vertices ) - { - - numElements_ = numElements; - numPoints_ = numPoints; - points_ = points; - vertices_ = vertices; - - allocateArrays(); - - return true; - } - - INLINE_FUNCTION_HD - iBoxType elementBox(int32 i)const - { - return elementBox_[i]; - } - - INLINE_FUNCTION_HD - int32 numElements()const - { - return numElements_; - } - - - - template - bool broadSearch(PairsContainer& pairs, particleMapType& particleMap) - { - - // map walls onto the cells - this->build(); - - this->particleWallFindPairs(pairs, particleMap); - - return true; - } - - bool build() - { - Kokkos::parallel_for( - "cellsSimple::findcellrange2", - rpFindCellRange2Type(0,numElements_), - *this); - Kokkos::fence(); - return true; - } - - template - bool particleWallFindPairs(PairsContainer& pairs, particleMapType& particleMap) - { - - int32 getFull = 1; - - while (getFull) - { - - getFull = findPairsElementRangeCount(pairs, particleMap.getCellIterator(0)); - - if(getFull) - { - // - resize the container - // note that getFull now shows the number of failed insertions. - uint32 len = max(getFull, 50); - auto oldCap = pairs.capacity(); - pairs.increaseCapacityBy(len); - - INFORMATION<<"Contact pair container capacity increased from "<< - oldCap << " to " - << pairs.capacity() <<" in cellsWallLevel0."< - int32 findPairsElementRangeCount(PairsContainer& pairs, CellIteratorType cellIter) - { - int32 getFull =0; - - const auto pwPairs = pairs; - const auto elementBox = elementBox_; - - Kokkos::parallel_reduce( - "cellsSimple::findPairsElementRangeModified2", - tpPWContactSearch(numElements_, Kokkos::AUTO), - LAMBDA_HD( - const typename tpPWContactSearch::member_type & teamMember, - int32& valueToUpdate){ - - const int32 iTri = teamMember.league_rank(); - - const auto triBox = elementBox[iTri]; - - int32 getFull2 = 0; - - auto bExtent = boxExtent(triBox); - int32 numCellBox = bExtent.x()*bExtent.y()*bExtent.z(); - - Kokkos::parallel_reduce( - Kokkos::TeamThreadRange( teamMember, numCellBox ), - [&] ( const int32 linIndex, int32 &innerUpdate ) - { - - CellType cell; - indexToCell(linIndex, triBox, cell); - - int32 n = cellIter.start(cell.x(),cell.y(),cell.z()); - - while( n>-1) - { - // id is wall id the pair is (particle id, wall id) - if( pairs.insert(static_cast(n), iTri) < 0 ) - innerUpdate++; - n = cellIter.getNext(n); - } - - }, - getFull2 - ); - - if ( teamMember.team_rank() == 0 ) valueToUpdate += getFull2; - }, - getFull - ); - - return getFull; - } - - INLINE_FUNCTION_HD - void operator()(TagFindCellRange2, int32 i) const - { - auto v = vertices_[i]; - auto p1 = points_[v.x()]; - auto p2 = points_[v.y()]; - auto p3 = points_[v.z()]; - - realx3 minP, maxP; - - this->extendBox(p1, p2, p3, cellExtent_, minP, maxP); - elementBox_[i] = iBoxType(this->pointIndex(minP), this->pointIndex(maxP)); - - } - -}; // cellsWallLevel0 - -} // pFlow - - -#endif // __cellsWallLevel0_hpp__ diff --git a/src/Interaction/contactSearch/wallMappings/cellsWallLevels.hpp b/src/Interaction/contactSearch/wallMappings/cellsWallLevels.hpp deleted file mode 100644 index 9f2c80ec..00000000 --- a/src/Interaction/contactSearch/wallMappings/cellsWallLevels.hpp +++ /dev/null @@ -1,152 +0,0 @@ -/*------------------------------- 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 __cellsWallLevels_hpp__ -#define __cellsWallLevels_hpp__ - -#include "cellsWallLevel0.hpp" - -namespace pFlow -{ - -template< - typename executionSpace - > -class cellsWallLevels -{ -public: - - using cellsWallLevel0Type = cellsWallLevel0; - - using IdType = typename cellsWallLevel0Type::IdType; - - using IndexType = typename cellsWallLevel0Type::IndexType; - - using Cells = typename cellsWallLevel0Type::Cells; - - using CellType = typename Cells::CellType; - - using execution_space = typename cellsWallLevel0Type::execution_space; - - using memory_space = typename cellsWallLevel0Type::memory_space; - - using iBoxType = iBox; - -protected: - - int32 numLevles_=1; - - - Vector cellsWallLevels_; - -public: - - TypeInfoNV("cellsWallLevels"); - - FUNCTION_H - cellsWallLevels( - int32 numLevels, - const Vector& cellsLevels, - real cellExtent, - int32 numPoints, - int32 numElements, - const ViewType1D& points, - const ViewType1D& vertices - ) - : - numLevles_(numLevels), - cellsWallLevels_("cellsWallLevels",numLevels, numLevels, RESERVE()) - { - - - - for(int32 lvl=0; lvl - bool broadSearch(PairsContainer& pairs, particleMapType& particleMap) - { - - // map walls onto the cells - for(int32 lvl=0; lvlparticleWallFindPairs(pairs, particleMap); - - return true; - } - - template - bool particleWallFindPairs(PairsContainer& pairs, particleMapType& particleMap) - { - - int32 getFull = 1; - - while (getFull) - { - getFull = 0; - for(int32 lvl=0; lvl -class multiGridMapping -{ -public: - - using CellsWallLevelType = cellsWallLevels; - - using IdType = typename CellsWallLevelType::IdType; - - using IndexType = typename CellsWallLevelType::IndexType; - - using Cells = typename CellsWallLevelType::Cells; - - using CellType = typename Cells::CellType; - - using execution_space = typename CellsWallLevelType::execution_space; - - using memory_space = typename CellsWallLevelType::memory_space; - - using iBoxType = iBox; - - -protected: - - // - update frequency - int32 updateFrequency_=1; - - real cellExtent_; - - int32 currentIter_ = 0; - - /// a broad search has been occured during last pass? - bool performedSearch_ = false; - - CellsWallLevelType cellsWallLevle_; - -private: - - bool performSearch() - { - if(currentIter_ % updateFrequency_ == 0) - { - currentIter_++; - return true; - - }else - { - currentIter_++; - return false; - } - } - -public: - - TypeInfoNV("multiGridMapping"); - - multiGridMapping( - const dictionary& dict, - int32 numLevels, - const Vector& ppCells, - int32 numPoints, - int32 numElements, - const ViewType1D& points, - const ViewType1D& vertices - ) - : - updateFrequency_( - max( - dict.getVal("updateFrequency"), - 1)), - cellExtent_( - max( - dict.getVal("cellExtent"), - 0.5)), - cellsWallLevle_( - numLevels, - ppCells, - cellExtent_, - numPoints, - numElements, - points, - vertices - ) - { - - REPORT(3)<<"Multi-grid wall mapping with "<< - yellowText(numLevels)<<" levels has been created."< - bool broadSearch(PairsContainer& pairs, particleMapType& particleMap, bool force=false) - { - if(force) currentIter_ = 0; - performedSearch_= false; - if(!performSearch())return true; - - - cellsWallLevle_.broadSearch(pairs, particleMap); - - - performedSearch_ = true; - return true; - } - -}; // multiGridMapping - -} // pFlow - - -#endif diff --git a/src/Interaction/interaction/interaction.cpp b/src/Interaction/interaction/interaction.cpp index 8d368c29..84786617 100644 --- a/src/Interaction/interaction/interaction.cpp +++ b/src/Interaction/interaction/interaction.cpp @@ -19,7 +19,9 @@ Licence: -----------------------------------------------------------------------------*/ #include "interaction.hpp" - +#include "particles.hpp" +#include "vocabs.hpp" +#include "geometry.hpp" pFlow::interaction::interaction ( @@ -28,26 +30,16 @@ pFlow::interaction::interaction const geometry& geom ) : - demInteraction(control, control.caseSetup().path()+interactionFile__), - interactionBase(prtcl, geom), - fileDict_(control.caseSetup().emplaceObject( - objectFile( - interactionFile__, - "", - objectFile::READ_ALWAYS, - objectFile::WRITE_NEVER), - interactionFile__, - true )) + property(interactionFile__, &control.caseSetup()), + observer + ( + &prtcl.dynPointStruct(), + msg_ + ), + demComponent("interaction", control), + particles_(prtcl), + geometry_(geom) { - this->subscribe(prtcl.pStruct()); - - contactSearch_ = contactSearch::create( - fileDict_.subDict("contactSearch"), - this->control().domain(), - prtcl, - geom, - timers() - ); } @@ -79,14 +71,15 @@ pFlow::uniquePtr pFlow::interaction::create clType); - REPORT(1)<< "Selecting interaction model..."< contactSearch_ = nullptr; + static inline + const message msg_ = message::ITEM_REARRANGE; public: @@ -65,11 +65,10 @@ public: const particles& prtcl, const geometry& geom ); + ~interaction() override = default; - - virtual ~interaction() = default; - - create_vCtor( + create_vCtor + ( interaction, systemControl, ( @@ -78,21 +77,18 @@ public: const geometry& geom ), (control, prtcl, geom) - ); + ); - auto& contactSearchPtr() + inline + const auto& Particles()const { - return contactSearch_; + return particles_; } - auto& contactSearchRef() + inline + const auto& Geometry()const { - return contactSearch_(); - } - - const auto& fileDict()const - { - return fileDict_; + return geometry_; } static diff --git a/src/Interaction/sphereInteraction/boundaries/boundarySphereInteraction/boundarySphereInteraction.cpp b/src/Interaction/sphereInteraction/boundaries/boundarySphereInteraction/boundarySphereInteraction.cpp new file mode 100644 index 00000000..0f2f64fb --- /dev/null +++ b/src/Interaction/sphereInteraction/boundaries/boundarySphereInteraction/boundarySphereInteraction.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. + +-----------------------------------------------------------------------------*/ + + +template +pFlow::boundarySphereInteraction::boundarySphereInteraction( + const boundaryBase &boundary, + const sphereParticles &sphPrtcls, + const GeometryMotionModel &geomMotion) + : generalBoundary(boundary, sphPrtcls.pStruct(), "", ""), + geometryMotion_(geomMotion), + sphParticles_(sphPrtcls) +{ + ppPairs_ = makeUnique(1); + pwPairs_ = makeUnique(1); +} + +template +pFlow::uniquePtr> +pFlow::boundarySphereInteraction::create( + const boundaryBase &boundary, + const sphereParticles &sphPrtcls, + const GeometryMotionModel &geomMotion) +{ + word cfTypeName = ContactForceModel::TYPENAME(); + word gmTypeName = MotionModel::TYPENAME(); + word bType = boundary.type(); + + word boundaryTypeName = angleBracketsNames3( + "boundarySphereInteraction", + bType, + cfTypeName, + gmTypeName); + + word altBTypeName = angleBracketsNames2( + "boundarySphereInteraction", + cfTypeName, + gmTypeName); + + if (boundaryBasevCtorSelector_.search(boundaryTypeName)) + { + REPORT(2) << "Creating boundry type " << Green_Text(boundaryTypeName) << + " for boundary " << boundary.name() << " . . ." << END_REPORT; + return boundaryBasevCtorSelector_[boundaryTypeName]( + boundary, + sphPrtcls, + geomMotion); + } + else if(boundaryBasevCtorSelector_[altBTypeName]) + { + // if boundary condition is not implemented, the default is used + + REPORT(2) << "Creating boundry type " << Green_Text(altBTypeName) << + " for boundary " << boundary.name() << " . . ." << END_REPORT; + return boundaryBasevCtorSelector_[altBTypeName]( + boundary, + sphPrtcls, + geomMotion); + } + else + { + printKeys + ( + fatalError << "Ctor Selector "<< boundaryTypeName<< + " and "<< altBTypeName << " do not exist. \n" + <<"Avaiable ones are: \n\n" + , + boundaryBasevCtorSelector_ + ); + fatalExit; + } + + return nullptr; +} diff --git a/src/Interaction/sphereInteraction/boundaries/boundarySphereInteraction/boundarySphereInteraction.hpp b/src/Interaction/sphereInteraction/boundaries/boundarySphereInteraction/boundarySphereInteraction.hpp new file mode 100644 index 00000000..b511ac6c --- /dev/null +++ b/src/Interaction/sphereInteraction/boundaries/boundarySphereInteraction/boundarySphereInteraction.hpp @@ -0,0 +1,168 @@ +/*------------------------------- 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 __boundarySphereInteraction_hpp__ +#define __boundarySphereInteraction_hpp__ + +#include "virtualConstructor.hpp" +#include "generalBoundary.hpp" +#include "unsortedContactList.hpp" +#include "sphereParticles.hpp" + +namespace pFlow +{ + +template +class boundarySphereInteraction +: + public generalBoundary +{ +public: + + using BoundarySphereInteractionType + = boundarySphereInteraction; + + using GeometryMotionModel = geometryMotionModel; + + using ContactForceModel = contactForceModel; + + using MotionModel = typename geometryMotionModel::MotionModel; + + using ModelStorage = typename ContactForceModel::contactForceStorage; + + using IdType = uint32; + + using IndexType = uint32; + + using ContactListType = + unsortedContactList; + +private: + + const GeometryMotionModel& geometryMotion_; + + /// const reference to sphere particles + const sphereParticles& sphParticles_; + + uniquePtr ppPairs_; + + uniquePtr pwPairs_; + +public: + + TypeInfoTemplate12("boundarySphereInteraction", ContactForceModel, MotionModel); + + boundarySphereInteraction( + const boundaryBase& boundary, + const sphereParticles& sphPrtcls, + const GeometryMotionModel& geomMotion); + + create_vCtor + ( + BoundarySphereInteractionType, + boundaryBase, + ( + const boundaryBase& boundary, + const sphereParticles& sphPrtcls, + const GeometryMotionModel& geomMotion + ), + (boundary, sphPrtcls, geomMotion) + ); + + add_vCtor + ( + BoundarySphereInteractionType, + BoundarySphereInteractionType, + boundaryBase + ); + + ~boundarySphereInteraction()override=default; + + const auto& sphParticles()const + { + return sphParticles_; + } + + const auto& geometryMotion()const + { + return geometryMotion_; + } + + ContactListType& ppPairs() + { + return ppPairs_(); + } + + const ContactListType& ppPairs()const + { + return ppPairs_(); + } + + ContactListType& pwPairs() + { + return pwPairs_(); + } + + const ContactListType& pwPairs()const + { + return pwPairs_(); + } + + virtual + bool sphereSphereInteraction( + real dt, + const ContactForceModel& cfModel) + { + // for default boundary, no thing to be done + return true; + } + + bool hearChanges + ( + real t, + real dt, + uint32 iter, + const message& msg, + const anyList& varList + ) override + { + + notImplementedFunction; + return true; + } + + void fill(const std::any& val)override + { + notImplementedFunction; + } + + static + uniquePtr create( + const boundaryBase& boundary, + const sphereParticles& sphPrtcls, + const GeometryMotionModel& geomMotion + ); + +}; + +} + +#include "boundarySphereInteraction.cpp" + +#endif //__boundarySphereInteraction_hpp__ diff --git a/src/Interaction/sphereInteraction/boundaries/boundarySphereInteractionList.cpp b/src/Interaction/sphereInteraction/boundaries/boundarySphereInteractionList.cpp new file mode 100644 index 00000000..7bc37847 --- /dev/null +++ b/src/Interaction/sphereInteraction/boundaries/boundarySphereInteractionList.cpp @@ -0,0 +1,23 @@ + + +template +pFlow::boundarySphereInteractionList::boundarySphereInteractionList +( + const sphereParticles &sphPrtcls, + const gMModel &geomMotion +) +: + ListPtr>(6), + boundaries_(sphPrtcls.pStruct().boundaries()) +{ + + for(uint32 i=0; i<6; i++) + { + this->set( + i, + boundarySphereInteraction::create( + boundaries_[i], + sphPrtcls, + geomMotion)); + } +} \ No newline at end of file diff --git a/src/Interaction/sphereInteraction/boundaries/boundarySphereInteractionList.hpp b/src/Interaction/sphereInteraction/boundaries/boundarySphereInteractionList.hpp new file mode 100644 index 00000000..1a5086fa --- /dev/null +++ b/src/Interaction/sphereInteraction/boundaries/boundarySphereInteractionList.hpp @@ -0,0 +1,40 @@ +#ifndef __boundarySphereInteractionList_hpp__ +#define __boundarySphereInteractionList_hpp__ + + +#include "boundaryList.hpp" +#include "ListPtr.hpp" +#include "boundarySphereInteraction.hpp" + + +namespace pFlow +{ + + +template +class boundarySphereInteractionList +: + public ListPtr> +{ +private: + + const boundaryList& boundaries_; + +public: + + boundarySphereInteractionList( + const sphereParticles& sphPrtcls, + const geometryMotionModel& geomMotion + ); + + ~boundarySphereInteractionList()=default; + +}; + + + +} + +#include "boundarySphereInteractionList.cpp" + +#endif //__boundarySphereInteractionList_hpp__ \ No newline at end of file diff --git a/src/Interaction/sphereInteraction/boundaries/createBoundarySphereInteraction.hpp b/src/Interaction/sphereInteraction/boundaries/createBoundarySphereInteraction.hpp new file mode 100644 index 00000000..27494be2 --- /dev/null +++ b/src/Interaction/sphereInteraction/boundaries/createBoundarySphereInteraction.hpp @@ -0,0 +1,31 @@ +/*------------------------------- 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 "boundarySphereInteraction.hpp" +#include "periodicBoundarySphereInteraction.hpp" + +#define createBoundarySphereInteraction(ForceModel,GeomModel) \ + template class pFlow::boundarySphereInteraction< \ + ForceModel, \ + GeomModel>; \ + \ + template class pFlow::periodicBoundarySphereInteraction< \ + ForceModel, \ + GeomModel>; + diff --git a/src/Interaction/sphereInteraction/boundaries/periodicBoundarySphereInteraction/periodicBoundarySIKernels.hpp b/src/Interaction/sphereInteraction/boundaries/periodicBoundarySphereInteraction/periodicBoundarySIKernels.hpp new file mode 100644 index 00000000..60661b3a --- /dev/null +++ b/src/Interaction/sphereInteraction/boundaries/periodicBoundarySphereInteraction/periodicBoundarySIKernels.hpp @@ -0,0 +1,125 @@ + +namespace pFlow::periodicBoundarySIKernels +{ + +template +void sphereSphereInteraction +( + real dt, + const ContactListType& cntctList, + const ContactForceModel& forceModel, + const realx3& transferVec, + const deviceScatteredFieldAccess& thisPoints, + const deviceScatteredFieldAccess& mirrorPoints, + const deviceViewType1D& diam, + const deviceViewType1D& propId, + const deviceViewType1D& vel, + const deviceViewType1D& rVel, + const deviceViewType1D& cForce, + const deviceViewType1D& cTorque +) +{ + + using ValueType = typename ContactListType::ValueType; + uint32 ss = cntctList.size(); + uint32 lastItem = cntctList.loopCount(); + if(lastItem == 0u)return; + + Kokkos::parallel_for( + "pFlow::periodicBoundarySIKernels::sphereSphereInteraction", + deviceRPolicyDynamic(0,lastItem), + LAMBDA_HD(uint32 n) + { + + if(!cntctList.isValid(n))return; + + auto [i,j] = cntctList.getPair(n); + uint32 ind_i = thisPoints.index(i); + uint32 ind_j = mirrorPoints.index(j); + + real Ri = 0.5*diam[ind_i]; + real Rj = 0.5*diam[ind_j]; + realx3 xi = thisPoints.field()[ind_i]; + realx3 xj = mirrorPoints.field()[ind_j]+transferVec; + real dist = length(xj-xi); + real ovrlp = (Ri+Rj) - dist; + + if( ovrlp >0.0 ) + { + + /*auto Vi = thisVel[i]; + auto Vj = mirrorVel[j]; + auto wi = thisRVel[i]; + auto wj = mirrorRVel[j]; + auto Nij = (xj-xi)/dist; + auto Vr = Vi - Vj + cross((Ri*wi+Rj*wj), Nij);*/ + + auto Nij = (xj-xi)/dist; + auto wi = rVel[ind_i]; + auto wj = rVel[ind_j]; + auto Vr = vel[ind_i] - vel[ind_j] + cross((Ri*wi+Rj*wj), Nij); + + auto history = cntctList.getValue(n); + + int32 propId_i = propId[ind_i]; + int32 propId_j = propId[ind_j]; + + realx3 FCn, FCt, Mri, Mrj, Mij, Mji; + + // calculates contact force + forceModel.contactForce( + dt, i, j, + propId_i, propId_j, + Ri, Rj, + ovrlp, + Vr, Nij, + history, + FCn, FCt); + + forceModel.rollingFriction( + dt, i, j, + propId_i, propId_j, + Ri, Rj, + wi, wj, + Nij, + FCn, + Mri, Mrj); + + auto M = cross(Nij,FCt); + Mij = Ri*M+Mri; + Mji = Rj*M+Mrj; + + auto FC = FCn + FCt; + + + Kokkos::atomic_add(&cForce[ind_i].x_,FC.x_); + Kokkos::atomic_add(&cForce[ind_i].y_,FC.y_); + Kokkos::atomic_add(&cForce[ind_i].z_,FC.z_); + + Kokkos::atomic_add(&cForce[ind_j].x_,-FC.x_); + Kokkos::atomic_add(&cForce[ind_j].y_,-FC.y_); + Kokkos::atomic_add(&cForce[ind_j].z_,-FC.z_); + + Kokkos::atomic_add(&cTorque[ind_i].x_, Mij.x_); + Kokkos::atomic_add(&cTorque[ind_i].y_, Mij.y_); + Kokkos::atomic_add(&cTorque[ind_i].z_, Mij.z_); + + Kokkos::atomic_add(&cTorque[ind_j].x_, Mji.x_); + Kokkos::atomic_add(&cTorque[ind_j].y_, Mji.y_); + Kokkos::atomic_add(&cTorque[ind_j].z_, Mji.z_); + + + cntctList.setValue(n,history); + + } + else + { + cntctList.setValue(n, ValueType()); + } + + }); + Kokkos::fence(); +} + + +} //pFlow::periodicBoundarySIKernels \ No newline at end of file diff --git a/src/Interaction/sphereInteraction/boundaries/periodicBoundarySphereInteraction/periodicBoundarySphereInteraction.cpp b/src/Interaction/sphereInteraction/boundaries/periodicBoundarySphereInteraction/periodicBoundarySphereInteraction.cpp new file mode 100644 index 00000000..38a4336b --- /dev/null +++ b/src/Interaction/sphereInteraction/boundaries/periodicBoundarySphereInteraction/periodicBoundarySphereInteraction.cpp @@ -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. + +-----------------------------------------------------------------------------*/ + +#include "periodicBoundarySIKernels.hpp" + +template +pFlow::periodicBoundarySphereInteraction::periodicBoundarySphereInteraction( + const boundaryBase &boundary, + const sphereParticles &sphPrtcls, + const GeometryMotionModel &geomMotion) + : boundarySphereInteraction(boundary, sphPrtcls, geomMotion), + transferVec_(boundary.mirrorBoundary().displacementVectroToMirror()) +{ + if(boundary.thisBoundaryIndex()%2==1) + { + masterInteraction_ = true; + } + else + { + masterInteraction_ = false; + } +} + +template +bool pFlow::periodicBoundarySphereInteraction::sphereSphereInteraction +( + real dt, + const ContactForceModel &cfModel +) +{ + if(!masterInteraction_) return true; + + pFlow::periodicBoundarySIKernels::sphereSphereInteraction( + dt, + this->ppPairs(), + cfModel, + transferVec_, + this->boundary().thisPoints(), + this->mirrorBoundary().thisPoints(), + this->sphParticles().diameter().deviceViewAll(), + this->sphParticles().propertyId().deviceViewAll(), + this->sphParticles().velocity().deviceViewAll(), + this->sphParticles().rVelocity().deviceViewAll(), + this->sphParticles().contactForce().deviceViewAll(), + this->sphParticles().contactTorque().deviceViewAll()); + + return true; +} \ No newline at end of file diff --git a/src/Interaction/sphereInteraction/boundaries/periodicBoundarySphereInteraction/periodicBoundarySphereInteraction.hpp b/src/Interaction/sphereInteraction/boundaries/periodicBoundarySphereInteraction/periodicBoundarySphereInteraction.hpp new file mode 100644 index 00000000..e2887787 --- /dev/null +++ b/src/Interaction/sphereInteraction/boundaries/periodicBoundarySphereInteraction/periodicBoundarySphereInteraction.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 __periodicBoundarySphereInteraction_hpp__ +#define __periodicBoundarySphereInteraction_hpp__ + +#include "boundarySphereInteraction.hpp" + +namespace pFlow +{ + +template +class periodicBoundarySphereInteraction +: + public boundarySphereInteraction +{ +public: + + using PBSInteractionType = + periodicBoundarySphereInteraction; + + using BSInteractionType = + boundarySphereInteraction; + + using GeometryMotionModel = typename BSInteractionType::GeometryMotionModel; + + using ContactForceModel = typename BSInteractionType::ContactForceModel; + + using MotionModel = typename geometryMotionModel::MotionModel; + + using ModelStorage = typename ContactForceModel::contactForceStorage; + + using IdType = typename BSInteractionType::IdType; + + using IndexType = typename BSInteractionType::IndexType; + + using ContactListType = typename BSInteractionType::ContactListType; + +private: + + realx3 transferVec_; + + bool masterInteraction_; +public: + + TypeInfoTemplate22("boundarySphereInteraction", "periodic",ContactForceModel, MotionModel); + + + periodicBoundarySphereInteraction( + const boundaryBase& boundary, + const sphereParticles& sphPrtcls, + const GeometryMotionModel& geomMotion + ); + + add_vCtor + ( + BSInteractionType, + PBSInteractionType, + boundaryBase + ); + + ~periodicBoundarySphereInteraction()override = default; + + + + + bool sphereSphereInteraction( + real dt, + const ContactForceModel& cfModel)override; + +}; + +} + +#include "periodicBoundarySphereInteraction.cpp" + + +#endif //__periodicBoundarySphereInteraction_hpp__ \ No newline at end of file diff --git a/src/Interaction/sphereInteraction/sphereInteraction.cpp b/src/Interaction/sphereInteraction/sphereInteraction.cpp deleted file mode 100644 index 0dacee74..00000000 --- a/src/Interaction/sphereInteraction/sphereInteraction.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/*------------------------------- 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< - typename contactForceModel, - typename geometryMotionModel, - template class contactListType > -bool pFlow::sphereInteraction:: - createSphereInteraction() -{ - - realVector_D rhoD(this->densities()); - - auto modelDict = this->fileDict().subDict("model"); - - REPORT(1)<<"Createing contact force model . . ."<( - this->numMaterials(), - rhoD.deviceVector(), - modelDict ); - - - uint32 nPrtcl = sphParticles_.size(); - - ppContactList_ = makeUnique(nPrtcl+1); - - pwContactList_ = makeUnique(nPrtcl/4+1); - - return true; -} - - - -template< - typename contactForceModel, - typename geometryMotionModel, - template class contactListType > -bool pFlow::sphereInteraction:: - sphereSphereInteraction() -{ - - - - auto lastItem = ppContactList_().loopCount(); - - // create the kernel functor - pFlow::sphereInteractionKernels::ppInteractionFunctor - ppInteraction( - this->dt(), - this->forceModel_(), - ppContactList_(), // to be read - sphParticles_.diameter().deviceVectorAll(), - sphParticles_.propertyId().deviceVectorAll(), - sphParticles_.pointPosition().deviceVectorAll(), - sphParticles_.velocity().deviceVectorAll(), - sphParticles_.rVelocity().deviceVectorAll(), - sphParticles_.contactForce().deviceVectorAll(), - sphParticles_.contactTorque().deviceVectorAll() - ); - - Kokkos::parallel_for( - "", - rpPPInteraction(0,lastItem), - ppInteraction - ); - - Kokkos::fence(); - - return true; -} - - -template< - typename contactForceModel, - typename geometryMotionModel, - template class contactListType > -bool pFlow::sphereInteraction:: - sphereWallInteraction() -{ - - int32 lastItem = pwContactList_().loopCount(); - real t = this->currentTime(); - - pFlow::sphereInteractionKernels::pwInteractionFunctor - pwInteraction( - this->dt(), - this->forceModel_(), - pwContactList_(), - geometryMotion_.getTriangleAccessor(), - geometryMotion_.getModel(t) , - sphParticles_.diameter().deviceVectorAll() , - sphParticles_.propertyId().deviceVectorAll(), - sphParticles_.pointPosition().deviceVectorAll(), - sphParticles_.velocity().deviceVectorAll(), - sphParticles_.rVelocity().deviceVectorAll() , - sphParticles_.contactForce().deviceVectorAll(), - sphParticles_.contactTorque().deviceVectorAll() , - geometryMotion_.triMotionIndex().deviceVectorAll(), - geometryMotion_.propertyId().deviceVectorAll(), - geometryMotion_.contactForceWall().deviceVectorAll() - ); - - Kokkos::parallel_for( - "", - rpPWInteraction(0,lastItem), - pwInteraction - ); - - - Kokkos::fence(); - - return true; -} \ No newline at end of file diff --git a/src/Interaction/sphereInteraction/sphereInteraction.hpp b/src/Interaction/sphereInteraction/sphereInteraction.hpp deleted file mode 100644 index b256c452..00000000 --- a/src/Interaction/sphereInteraction/sphereInteraction.hpp +++ /dev/null @@ -1,226 +0,0 @@ -/*------------------------------- 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 __sphereInteraction_hpp__ -#define __sphereInteraction_hpp__ - -#include "interaction.hpp" -#include "sphereParticles.hpp" - -#include "sphereInteractionKernels.hpp" - -namespace pFlow -{ - -template< - typename contactForceModel, - typename geometryMotionModel, - template class contactListType> -class sphereInteraction -: - public interaction -{ -public: - - using GeometryMotionModel = geometryMotionModel; - - using ContactForceModel = contactForceModel; - - using MotionModel = typename geometryMotionModel::MotionModel; - - using ModelStorage = typename ContactForceModel::contactForceStorage; - - using IdType = typename interaction::IdType; - - using IndexType = typename interaction::IndexType; - - using ExecutionSpace = typename interaction::ExecutionSpace; - - using ContactListType = - contactListType; - - using PairsContainerType= typename contactSearch::PairContainerType; - -protected: - - /// const reference to geometry - const GeometryMotionModel& geometryMotion_; - - /// const reference to particles - const sphereParticles& sphParticles_; - - - /// contact force model - uniquePtr forceModel_ = nullptr; - - /// contact list for particle-particle interactoins (keeps the history) - uniquePtr ppContactList_ = nullptr; - - /// contact list for particle-wall interactions (keeps the history) - uniquePtr pwContactList_ = nullptr; - - /// timer for particle-particle interaction computations - Timer ppInteractionTimer_; - - /// timer for particle-wall interaction computations - Timer pwInteractionTimer_; - - bool createSphereInteraction(); - - bool managePPContactLists(); - - bool managePWContactLists(); - - /// range policy for p-p interaction execution - using rpPPInteraction = - Kokkos::RangePolicy, Kokkos::Schedule>; - - /// range policy for p-w interaction execution - using rpPWInteraction = rpPPInteraction; - -public: - - TypeInfoTemplate3("sphereInteraction", ContactForceModel, MotionModel, ContactListType); - - // constructor - - sphereInteraction( - systemControl& control, - const particles& prtcl, - const geometry& geom) - : - interaction(control, prtcl, geom), - geometryMotion_(dynamic_cast(geom)), - sphParticles_(dynamic_cast(prtcl)), - ppInteractionTimer_("sphere-sphere interaction", &this->timers()), - pwInteractionTimer_("sphere-wall interaction", &this->timers()) - { - if(!createSphereInteraction()) - { - fatalExit; - } - } - - add_vCtor - ( - interaction, - sphereInteraction, - systemControl - ); - - - bool beforeIteration() override - { - return true; - } - - - bool iterate() override - { - -//Info<<"before contact search"<contactSearch_) - { - - if( this->contactSearch_().ppEnterBroadSearch()) - { - //Info<<" before ppEnterBroadSearch"<contactSearch_().pwEnterBroadSearch()) - { - //Info<<" before pwEnterBroadSearch"<contactSearch_().ppPerformedBroadSearch()) - { - //Info<<" before afterBroadSearch"<contactSearch_().pwPerformedBroadSearch()) - { - //Info<<" before pwContactList_().afterBroadSearch()"< class cLT> +bool pFlow::sphereInteraction::createSphereInteraction() +{ + + realVector_D rhoD("densities", this->densities()); + + auto modelDict = this->subDict("model"); + + REPORT(1)<<"Createing contact force model . . ."<( + this->numMaterials(), + rhoD.deviceView(), + modelDict ); + + + uint32 nPrtcl = sphParticles_.size(); + + contactSearch_ = contactSearch::create( + subDict("contactSearch"), + sphParticles_.extendedDomain().domainBox(), + sphParticles_, + geometryMotion_, + timers()); + + ppContactList_ = makeUnique(nPrtcl+1); + + pwContactList_ = makeUnique(nPrtcl/5+1); + + + + return true; +} + + +template class cLT> +bool pFlow::sphereInteraction::sphereSphereInteraction() +{ + auto lastItem = ppContactList_().loopCount(); + + // create the kernel functor + pFlow::sphereInteractionKernels::ppInteractionFunctor + ppInteraction( + this->dt(), + this->forceModel_(), + ppContactList_(), // to be read + sphParticles_.diameter().deviceViewAll(), + sphParticles_.propertyId().deviceViewAll(), + sphParticles_.pointPosition().deviceViewAll(), + sphParticles_.velocity().deviceViewAll(), + sphParticles_.rVelocity().deviceViewAll(), + sphParticles_.contactForce().deviceViewAll(), + sphParticles_.contactTorque().deviceViewAll() + ); + + Kokkos::parallel_for( + "ppInteraction", + rpPPInteraction(0,lastItem), + ppInteraction + ); + + Kokkos::fence(); + + return true; +} + + +template class cLT> +bool pFlow::sphereInteraction::sphereWallInteraction() +{ + + uint32 lastItem = pwContactList_().loopCount(); + uint32 iter = this->currentIter(); + real t = this->currentTime(); + real dt = this->dt(); + + pFlow::sphereInteractionKernels::pwInteractionFunctor + pwInteraction( + dt, + this->forceModel_(), + pwContactList_(), + geometryMotion_.getTriangleAccessor(), + geometryMotion_.getModel(iter, t, dt) , + sphParticles_.diameter().deviceViewAll() , + sphParticles_.propertyId().deviceViewAll(), + sphParticles_.pointPosition().deviceViewAll(), + sphParticles_.velocity().deviceViewAll(), + sphParticles_.rVelocity().deviceViewAll() , + sphParticles_.contactForce().deviceViewAll(), + sphParticles_.contactTorque().deviceViewAll() , + geometryMotion_.triMotionIndex().deviceViewAll(), + geometryMotion_.propertyId().deviceViewAll(), + geometryMotion_.contactForceWall().deviceViewAll() + ); + + Kokkos::parallel_for( + "", + rpPWInteraction(0,lastItem), + pwInteraction + ); + + + Kokkos::fence(); + + return true; +} + + +template class cLT> +pFlow::sphereInteraction::sphereInteraction +( + systemControl& control, + const particles& prtcl, + const geometry& geom +) +: + interaction(control, prtcl, geom), + geometryMotion_(dynamic_cast(geom)), + sphParticles_(dynamic_cast(prtcl)), + boundaryInteraction_(sphParticles_,geometryMotion_), + ppInteractionTimer_("sphere-sphere interaction", &this->timers()), + pwInteractionTimer_("sphere-wall interaction", &this->timers()), + contactListMangementTimer_("contact-list management", &this->timers()), + boundaryInteractionTimer_("interaction for boundary", &this->timers()) +{ + + if(!createSphereInteraction()) + { + fatalExit; + } +} + +template class cLT> +bool pFlow::sphereInteraction::beforeIteration() +{ + return true; +} + +template class cLT> +bool pFlow::sphereInteraction::iterate() +{ + + auto iter = this->currentIter(); + auto t = this->currentTime(); + auto dt = this->dt(); + + //output<<"iter, t, dt "<< iter<<" "<< t << " "<forceModel_()); + } + boundaryInteractionTimer_.end(); + return true; +} + +template class cLT> +bool pFlow::sphereInteraction::afterIteration() +{ + return true; +} + +template class cLT> +bool pFlow::sphereInteraction::hearChanges +( + real t, + real dt, + uint32 iter, + const message& msg, + const anyList& varList +) +{ + if(msg.equivalentTo(message::ITEM_REARRANGE)) + { + notImplementedFunction; + } + return true; +} + diff --git a/src/Interaction/sphereInteraction/sphereInteraction/sphereInteraction.hpp b/src/Interaction/sphereInteraction/sphereInteraction/sphereInteraction.hpp new file mode 100644 index 00000000..4ccb9836 --- /dev/null +++ b/src/Interaction/sphereInteraction/sphereInteraction/sphereInteraction.hpp @@ -0,0 +1,166 @@ +/*------------------------------- 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 __sphereInteraction_hpp__ +#define __sphereInteraction_hpp__ + +#include "interaction.hpp" +#include "sphereParticles.hpp" +#include "boundarySphereInteractionList.hpp" +#include "sphereInteractionKernels.hpp" +//#include "unsortedContactList.hpp" + + + +namespace pFlow +{ + +template< + typename contactForceModel, + typename geometryMotionModel, + template class contactListType> +class sphereInteraction +: + public interaction +{ +public: + + using GeometryMotionModel = geometryMotionModel; + + using ContactForceModel = contactForceModel; + + using MotionModel = typename geometryMotionModel::MotionModel; + + using ModelStorage = typename ContactForceModel::contactForceStorage; + + using BoundaryListType = boundarySphereInteractionList; + + using IdType = uint32; + + using IndexType = uint32; + + using ContactListType = + contactListType; + + //using BoundaryContactListType = unsortedContactList; + + + +private: + + /// const reference to geometry + const GeometryMotionModel& geometryMotion_; + + /// const reference to particles + const sphereParticles& sphParticles_; + + /// particle-particle and particle-wall interactions at boundaries + BoundaryListType boundaryInteraction_; + + /// contact search object for pp and pw interactions + uniquePtr contactSearch_ = nullptr; + + /// contact force model + uniquePtr forceModel_ = nullptr; + + /// contact list for particle-particle interactoins (keeps the history) + uniquePtr ppContactList_ = nullptr; + + /// contact list for particle-wall interactions (keeps the history) + uniquePtr pwContactList_ = nullptr; + + + /// timer for particle-particle interaction computations + Timer ppInteractionTimer_; + + /// timer for particle-wall interaction computations + Timer pwInteractionTimer_; + + /// timer for managing contact lists (only inernal points) + Timer contactListMangementTimer_; + + /// timer for boundary interaction time + Timer boundaryInteractionTimer_; + + + + bool createSphereInteraction(); + + bool sphereSphereInteraction(); + + bool sphereWallInteraction(); + + //bool managePPContactLists(); + + //bool managePWContactLists(); + + /// range policy for p-p interaction execution + using rpPPInteraction = + Kokkos::RangePolicy, Kokkos::Schedule>; + + /// range policy for p-w interaction execution + using rpPWInteraction = rpPPInteraction; + +public: + + TypeInfoTemplate13("sphereInteraction", ContactForceModel, MotionModel, ContactListType); + + /// Constructor from components + sphereInteraction( + systemControl& control, + const particles& prtcl, + const geometry& geom); + + + /// Add virtual constructor + add_vCtor + ( + interaction, + sphereInteraction, + systemControl + ); + + /// This is called in time loop, before iterate. (overriden from demComponent) + bool beforeIteration() override; + + /// This is called in time loop. Perform the main calculations + /// when the component should evolve along time. (overriden from demComponent) + bool iterate() override; + + /// This is called in time loop, after iterate. (overriden from demComponent) + bool afterIteration() override; + + /// Check for changes in the point structures. (overriden from observer) + bool hearChanges( + real t, + real dt, + uint32 iter, + const message& msg, + const anyList& varList)override; + + +}; + + +} + +#include "sphereInteraction.cpp" + +#endif //__sphereInteraction_hpp__ diff --git a/src/Interaction/sphereInteraction/sphereInteractionKernels.hpp b/src/Interaction/sphereInteraction/sphereInteraction/sphereInteractionKernels.hpp similarity index 95% rename from src/Interaction/sphereInteraction/sphereInteractionKernels.hpp rename to src/Interaction/sphereInteraction/sphereInteraction/sphereInteractionKernels.hpp index cef5fa72..c581d598 100644 --- a/src/Interaction/sphereInteraction/sphereInteractionKernels.hpp +++ b/src/Interaction/sphereInteraction/sphereInteraction/sphereInteractionKernels.hpp @@ -42,7 +42,7 @@ struct ppInteractionFunctor ContactListType tobeFilled_; deviceViewType1D diam_; - deviceViewType1D propId_; + deviceViewType1D propId_; deviceViewType1D pos_; deviceViewType1D lVel_; deviceViewType1D rVel_; @@ -55,7 +55,7 @@ struct ppInteractionFunctor ContactForceModel forceModel, ContactListType tobeFilled, deviceViewType1D diam, - deviceViewType1D propId, + deviceViewType1D propId, deviceViewType1D pos, deviceViewType1D lVel, deviceViewType1D rVel, @@ -75,7 +75,7 @@ struct ppInteractionFunctor {} INLINE_FUNCTION_HD - void operator()(const int32 n)const + void operator()(const uint32 n)const { if(!tobeFilled_.isValid(n))return; @@ -181,14 +181,14 @@ struct pwInteractionFunctor MotionModel motionModel_; deviceViewType1D diam_; - deviceViewType1D propId_; + deviceViewType1D propId_; deviceViewType1D pos_; deviceViewType1D lVel_; deviceViewType1D rVel_; deviceViewType1D cForce_; deviceViewType1D cTorque_; - deviceViewType1D wTriMotionIndex_; - deviceViewType1D wPropId_; + deviceViewType1D wTriMotionIndex_; + deviceViewType1D wPropId_; deviceViewType1D wCForce_; @@ -199,14 +199,14 @@ struct pwInteractionFunctor TraingleAccessor triangles, MotionModel motionModel , deviceViewType1D diam , - deviceViewType1D propId, + deviceViewType1D propId, deviceViewType1D pos , deviceViewType1D lVel, deviceViewType1D rVel, deviceViewType1D cForce, deviceViewType1D cTorque , - deviceViewType1D wTriMotionIndex, - deviceViewType1D wPropId, + deviceViewType1D wTriMotionIndex, + deviceViewType1D wPropId, deviceViewType1D wCForce) : dt_(dt), diff --git a/src/Interaction/sphereInteraction/sphereTriSurfaceContact.hpp b/src/Interaction/sphereInteraction/sphereInteraction/sphereTriSurfaceContact.hpp similarity index 100% rename from src/Interaction/sphereInteraction/sphereTriSurfaceContact.hpp rename to src/Interaction/sphereInteraction/sphereInteraction/sphereTriSurfaceContact.hpp diff --git a/src/Interaction/sphereInteraction/triWall.hpp b/src/Interaction/sphereInteraction/sphereInteraction/triWall.hpp similarity index 100% rename from src/Interaction/sphereInteraction/triWall.hpp rename to src/Interaction/sphereInteraction/sphereInteraction/triWall.hpp diff --git a/src/Interaction/sphereInteraction/sphereInteractions.cpp b/src/Interaction/sphereInteraction/sphereInteractions.cpp deleted file mode 100644 index 569fa7ad..00000000 --- a/src/Interaction/sphereInteraction/sphereInteractions.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/*------------------------------- 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 "sphereInteraction.hpp" - -#include "geometryMotions.hpp" - -#include "contactForceModels.hpp" -#include "unsortedContactList.hpp" -#include "sortedContactList.hpp" - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedLinearNormalRolling, - pFlow::fixedGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedLinearNormalRolling, - pFlow::fixedGeometry, - pFlow::sortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedLinearNormalRolling, - pFlow::fixedGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedLinearNormalRolling, - pFlow::fixedGeometry, - pFlow::sortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedLinearNormalRolling, - pFlow::rotationAxisMotionGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedLinearNormalRolling, - pFlow::rotationAxisMotionGeometry, - pFlow::sortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedLinearNormalRolling, - pFlow::rotationAxisMotionGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedLinearNormalRolling, - pFlow::rotationAxisMotionGeometry, - pFlow::sortedContactList>; - - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedLinearNormalRolling, - pFlow::vibratingMotionGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedLinearNormalRolling, - pFlow::vibratingMotionGeometry, - pFlow::sortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedLinearNormalRolling, - pFlow::vibratingMotionGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedLinearNormalRolling, - pFlow::vibratingMotionGeometry, - pFlow::sortedContactList>; - - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedLinearNormalRolling, - pFlow::multiRotationAxisMotionGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedLinearNormalRolling, - pFlow::multiRotationAxisMotionGeometry, - pFlow::sortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedLinearNormalRolling, - pFlow::multiRotationAxisMotionGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedLinearNormalRolling, - pFlow::multiRotationAxisMotionGeometry, - pFlow::sortedContactList>; - -/// non-linear models - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedNonLinearNormalRolling, - pFlow::fixedGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedNonLinearNormalRolling, - pFlow::fixedGeometry, - pFlow::sortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedNonLinearNormalRolling, - pFlow::fixedGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedNonLinearNormalRolling, - pFlow::fixedGeometry, - pFlow::sortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedNonLinearNormalRolling, - pFlow::rotationAxisMotionGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedNonLinearNormalRolling, - pFlow::rotationAxisMotionGeometry, - pFlow::sortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedNonLinearNormalRolling, - pFlow::rotationAxisMotionGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedNonLinearNormalRolling, - pFlow::rotationAxisMotionGeometry, - pFlow::sortedContactList>; - - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedNonLinearNormalRolling, - pFlow::vibratingMotionGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedNonLinearNormalRolling, - pFlow::vibratingMotionGeometry, - pFlow::sortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedNonLinearNormalRolling, - pFlow::vibratingMotionGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedNonLinearNormalRolling, - pFlow::vibratingMotionGeometry, - pFlow::sortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedNonLinearNormalRolling, - pFlow::multiRotationAxisMotionGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedNonLinearNormalRolling, - pFlow::multiRotationAxisMotionGeometry, - pFlow::sortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedNonLinearNormalRolling, - pFlow::multiRotationAxisMotionGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedNonLinearNormalRolling, - pFlow::multiRotationAxisMotionGeometry, - pFlow::sortedContactList>; - - -// - nonLinearMod models -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedNonLinearModNormalRolling, - pFlow::fixedGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedNonLinearModNormalRolling, - pFlow::fixedGeometry, - pFlow::sortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedNonLinearModNormalRolling, - pFlow::fixedGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedNonLinearModNormalRolling, - pFlow::fixedGeometry, - pFlow::sortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedNonLinearModNormalRolling, - pFlow::rotationAxisMotionGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedNonLinearModNormalRolling, - pFlow::rotationAxisMotionGeometry, - pFlow::sortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedNonLinearModNormalRolling, - pFlow::rotationAxisMotionGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedNonLinearModNormalRolling, - pFlow::rotationAxisMotionGeometry, - pFlow::sortedContactList>; - - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedNonLinearModNormalRolling, - pFlow::vibratingMotionGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedNonLinearModNormalRolling, - pFlow::vibratingMotionGeometry, - pFlow::sortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedNonLinearModNormalRolling, - pFlow::vibratingMotionGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedNonLinearModNormalRolling, - pFlow::vibratingMotionGeometry, - pFlow::sortedContactList>; - - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedNonLinearModNormalRolling, - pFlow::multiRotationAxisMotionGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::limitedNonLinearModNormalRolling, - pFlow::multiRotationAxisMotionGeometry, - pFlow::sortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedNonLinearModNormalRolling, - pFlow::multiRotationAxisMotionGeometry, - pFlow::unsortedContactList>; - -template class pFlow::sphereInteraction< - pFlow::cfModels::nonLimitedNonLinearModNormalRolling, - pFlow::multiRotationAxisMotionGeometry, - pFlow::sortedContactList>; diff --git a/src/Interaction/sphereInteraction/sphereInteractionsLinearModels.cpp b/src/Interaction/sphereInteraction/sphereInteractionsLinearModels.cpp new file mode 100644 index 00000000..8c30776f --- /dev/null +++ b/src/Interaction/sphereInteraction/sphereInteractionsLinearModels.cpp @@ -0,0 +1,59 @@ +/*------------------------------- 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 "sphereInteraction.hpp" +#include "geometryMotions.hpp" +#include "contactForceModels.hpp" +#include "unsortedContactList.hpp" +#include "sortedContactList.hpp" +#include "createBoundarySphereInteraction.hpp" + + + +#define createInteraction(ForceModel,GeomModel) \ + \ + template class pFlow::sphereInteraction< \ + ForceModel, \ + GeomModel, \ + pFlow::unsortedContactList>; \ + \ + template class pFlow::sphereInteraction< \ + ForceModel, \ + GeomModel, \ + pFlow::sortedContactList>; \ + createBoundarySphereInteraction(ForceModel, GeomModel) + + +// stationaryGeometry +createInteraction(pFlow::cfModels::limitedLinearNormalRolling, pFlow::stationaryGeometry); +createInteraction(pFlow::cfModels::nonLimitedLinearNormalRolling,pFlow::stationaryGeometry); + +// rotationAxisMotionGeometry +createInteraction(pFlow::cfModels::limitedLinearNormalRolling, pFlow::rotationAxisMotionGeometry); +createInteraction(pFlow::cfModels::nonLimitedLinearNormalRolling,pFlow::rotationAxisMotionGeometry); + +// vibratingMotionGeometry +createInteraction(pFlow::cfModels::limitedLinearNormalRolling, pFlow::vibratingMotionGeometry); +createInteraction(pFlow::cfModels::nonLimitedLinearNormalRolling,pFlow::vibratingMotionGeometry); + +// multiRotationAxisMotionGeometry +//createInteraction(pFlow::cfModels::limitedLinearNormalRolling, pFlow::multiRotationAxisMotionGeometry); +//createInteraction(pFlow::cfModels::nonLimitedLinearNormalRolling,pFlow::multiRotationAxisMotionGeometry); + diff --git a/src/Interaction/sphereInteraction/sphereInteractionsNonLinearModModels.cpp b/src/Interaction/sphereInteraction/sphereInteractionsNonLinearModModels.cpp new file mode 100644 index 00000000..b96e5d98 --- /dev/null +++ b/src/Interaction/sphereInteraction/sphereInteractionsNonLinearModModels.cpp @@ -0,0 +1,58 @@ +/*------------------------------- 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 "sphereInteraction.hpp" +#include "geometryMotions.hpp" +#include "contactForceModels.hpp" +#include "unsortedContactList.hpp" +#include "sortedContactList.hpp" +#include "createBoundarySphereInteraction.hpp" + + + +#define createInteraction(ForceModel,GeomModel) \ + \ + template class pFlow::sphereInteraction< \ + ForceModel, \ + GeomModel, \ + pFlow::unsortedContactList>; \ + \ + template class pFlow::sphereInteraction< \ + ForceModel, \ + GeomModel, \ + pFlow::sortedContactList>; \ + createBoundarySphereInteraction(ForceModel, GeomModel) + + +// stationaryGeometry +createInteraction(pFlow::cfModels::limitedNonLinearModNormalRolling, pFlow::stationaryGeometry); +createInteraction(pFlow::cfModels::nonLimitedNonLinearModNormalRolling,pFlow::stationaryGeometry); + +// rotationAxisMotionGeometry +createInteraction(pFlow::cfModels::limitedNonLinearModNormalRolling, pFlow::rotationAxisMotionGeometry); +createInteraction(pFlow::cfModels::nonLimitedNonLinearModNormalRolling,pFlow::rotationAxisMotionGeometry); + +// vibratingMotionGeometry +createInteraction(pFlow::cfModels::limitedNonLinearModNormalRolling, pFlow::vibratingMotionGeometry); +createInteraction(pFlow::cfModels::nonLimitedNonLinearModNormalRolling,pFlow::vibratingMotionGeometry); + +// multiRotationAxisMotionGeometry +//createInteraction(pFlow::cfModels::limitedNonLinearModNormalRolling, pFlow::multiRotationAxisMotionGeometry); +//createInteraction(pFlow::cfModels::nonLimitedNonLinearModNormalRolling,pFlow::multiRotationAxisMotionGeometry); diff --git a/src/Interaction/sphereInteraction/sphereInteractionsNonLinearModels.cpp b/src/Interaction/sphereInteraction/sphereInteractionsNonLinearModels.cpp new file mode 100644 index 00000000..3e8e2707 --- /dev/null +++ b/src/Interaction/sphereInteraction/sphereInteractionsNonLinearModels.cpp @@ -0,0 +1,58 @@ +/*------------------------------- 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 "sphereInteraction.hpp" +#include "geometryMotions.hpp" +#include "contactForceModels.hpp" +#include "unsortedContactList.hpp" +#include "sortedContactList.hpp" +#include "createBoundarySphereInteraction.hpp" + + + +#define createInteraction(ForceModel,GeomModel) \ + \ + template class pFlow::sphereInteraction< \ + ForceModel, \ + GeomModel, \ + pFlow::unsortedContactList>; \ + \ + template class pFlow::sphereInteraction< \ + ForceModel, \ + GeomModel, \ + pFlow::sortedContactList>; \ + createBoundarySphereInteraction(ForceModel, GeomModel) + + +// stationaryGeometry +createInteraction(pFlow::cfModels::limitedNonLinearNormalRolling, pFlow::stationaryGeometry); +createInteraction(pFlow::cfModels::nonLimitedNonLinearNormalRolling,pFlow::stationaryGeometry); + +// rotationAxisMotionGeometry +createInteraction(pFlow::cfModels::limitedNonLinearNormalRolling, pFlow::rotationAxisMotionGeometry); +createInteraction(pFlow::cfModels::nonLimitedNonLinearNormalRolling,pFlow::rotationAxisMotionGeometry); + +// vibratingMotionGeometry +createInteraction(pFlow::cfModels::limitedNonLinearNormalRolling, pFlow::vibratingMotionGeometry); +createInteraction(pFlow::cfModels::nonLimitedNonLinearNormalRolling,pFlow::vibratingMotionGeometry); + +// multiRotationAxisMotionGeometry +//createInteraction(pFlow::cfModels::limitedNonLinearNormalRolling, pFlow::multiRotationAxisMotionGeometry); +//createInteraction(pFlow::cfModels::nonLimitedNonLinearNormalRolling,pFlow::multiRotationAxisMotionGeometry); diff --git a/src/MotionModel/CMakeLists.txt b/src/MotionModel/CMakeLists.txt index 9438c2ab..b0b084fd 100644 --- a/src/MotionModel/CMakeLists.txt +++ b/src/MotionModel/CMakeLists.txt @@ -1,13 +1,19 @@ list(APPEND SourceFiles -entities/rotatingAxis/rotatingAxis.cpp -entities/multiRotatingAxis/multiRotatingAxis.cpp entities/timeInterval/timeInterval.cpp -entities/vibrating/vibrating.cpp -fixedWall/fixedWall.cpp + +entities/rotatingAxis/rotatingAxis.cpp rotatingAxisMotion/rotatingAxisMotion.cpp -multiRotatingAxisMotion/multiRotatingAxisMotion.cpp + +entities/vibrating/vibrating.cpp vibratingMotion/vibratingMotion.cpp + +stationaryWall/stationaryWall.cpp +entities/stationary/stationary.cpp + +#entities/multiRotatingAxis/multiRotatingAxis.cpp +#multiRotatingAxisMotion/multiRotatingAxisMotion.cpp + ) set(link_libs Kokkos::kokkos phasicFlow) diff --git a/src/MotionModel/MotionModel/MotionModel.cpp b/src/MotionModel/MotionModel/MotionModel.cpp new file mode 100644 index 00000000..6a530eaa --- /dev/null +++ b/src/MotionModel/MotionModel/MotionModel.cpp @@ -0,0 +1,147 @@ +/*------------------------------- 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 +inline +bool pFlow::MotionModel::impl_nameToIndex(const word& name, uint32& indx)const +{ + if( auto i = componentNames_.findi(name); i == -1) + { + return false; + } + else + { + indx = static_cast(i); + return true; + } + +} + +template +inline +bool pFlow::MotionModel::impl_indexToName(uint32 i, word& name)const +{ + if(i < numComponents_ ) + { + name = componentNames_[i]; + return true; + } + else + { + return false; + } +} + +template +inline +bool pFlow::MotionModel::impl_readDictionary +( + const dictionary& dict +) +{ + + auto modelName = dict.getVal("motionModel"); + + if(modelName != getTypeName()) + { + fatalErrorInFunction<< + " motionModel should be "<< Yellow_Text(getTypeName())<< + ", but found "<< Yellow_Text(modelName)< components( + "Read::modelComponent", + compNames.size()+1, + 0, + RESERVE()); + + componentNames_.clear(); + + + for(auto& cName: compNames) + { + auto& compDict = motionInfo.subDict(cName); + + if(auto compPtr = makeUnique(compDict); compPtr) + { + components.push_back(compPtr()); + componentNames_.push_back(cName); + } + } + + if( !componentNames_.search("none") ) + { + components.push_back + ( + impl_noneComponent() + ); + componentNames_.push_back("none"); + } + + motionComponents_.assign(components); + numComponents_ = motionComponents_.size(); + + return true; +} + + +template +inline +bool pFlow::MotionModel::impl_writeDictionary +( + dictionary& dict +)const +{ + word modelName = getTypeName(); + + dict.add("motionModel", modelName ); + + auto modelDictName = modelName+"Info"; + + auto& motionInfo = dict.subDictOrCreate(modelDictName); + auto hostComponents = motionComponents_.hostView(); + + ForAll(i, motionComponents_) + { + + auto& axDict = motionInfo.subDictOrCreate(componentNames_[i]); + if( !hostComponents[i].write(axDict)) + { + fatalErrorInFunction<< + " error in writing axis "<< componentNames_[i] << " to dicrionary " + << motionInfo.globalName()< +pFlow::MotionModel::MotionModel() +: + motionComponents_("motionComponents") +{} \ No newline at end of file diff --git a/src/MotionModel/MotionModel/MotionModel.hpp b/src/MotionModel/MotionModel/MotionModel.hpp new file mode 100644 index 00000000..6dae3175 --- /dev/null +++ b/src/MotionModel/MotionModel/MotionModel.hpp @@ -0,0 +1,246 @@ +/*------------------------------- 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 __MotionModel_hpp__ +#define __MotionModel_hpp__ + + + +#include "VectorSingles.hpp" +#include "Vector.hpp" +#include "List.hpp" +#include "dictionary.hpp" + + +namespace pFlow +{ + +/** + * @brief Motion model abstract class (CRTP) for all the motion models +*/ +template +class MotionModel +{ +public: + + using ModelType = Model; + + using ModelComponent = Component; + + using ComponentVector_D = VectorSingle; + + /** Motion model class to be passed to computational units/kernels for + * transfing points and returning velocities at various positions + */ + class ModelInterface + { + private: + + deviceViewType1D components_; + + uint32 numComponents_=0; + + public: + + INLINE_FUNCTION_HD + ModelInterface + ( + deviceViewType1D Comps, + uint32 numComp + ): + components_(Comps), + numComponents_(numComp) + {} + + INLINE_FUNCTION_HD + ModelInterface(const ModelInterface&) = default; + + INLINE_FUNCTION_HD + ModelInterface& operator=(const ModelInterface&) = default; + + INLINE_FUNCTION_HD + ModelInterface(ModelInterface&&) noexcept = default; + + INLINE_FUNCTION_HD + ModelInterface& operator=(ModelInterface&&) noexcept= default; + + INLINE_FUNCTION_HD + ~ModelInterface()=default; + + INLINE_FUNCTION_HD + realx3 pointVelocity(uint32 n, const realx3& p)const + { + return components_[n].linVelocityPoint(p); + } + + INLINE_FUNCTION_HD + realx3 operator()(uint32 n, const realx3& p)const + { + return pointVelocity(n,p); + } + + INLINE_FUNCTION_HD + realx3 transferPoint(uint32 n, const realx3 p, real dt)const + { + return components_[n].transferPoint(p, dt); + } + + INLINE_FUNCTION_HD + uint32 size()const + { + return numComponents_; + } + }; + +private: + + // friends + friend ModelType; + + /// Number of axes components + uint32 numComponents_= 0; + + /// Vector to store motion components + ComponentVector_D motionComponents_; + + /// Names of compoenents + wordList componentNames_; + +protected: + + /// @brief obtain a reference to the actual motion model + inline + auto& getModel() + { + return static_cast(*this); + } + + /// @brief Obtain a const reference to the actual motion model + inline + const auto& getModel()const + { + return static_cast(*this); + } + + /// Return a none object for the motion model + inline + auto impl_noneComponent()const + { + return ModelType::noneComponent(); + } + + /// Name of the compoenent to index of the component + bool impl_nameToIndex(const word& name, uint32& idx)const; + + /// Component index to motion component name + bool impl_indexToName(uint32 i, word& name)const; + + /// const reference to the list of component names + inline + const wordList& impl_componentNames()const + { + return componentNames_; + } + + /// Return model interface + auto impl_getModelInterface(uint32 iter, real t, real dt)const + { + getModel().impl_setTime(iter, t, dt); + + return ModelInterface( + motionComponents_.deviceViewAll(), + numComponents_); + } + + /// Read from dictionary + bool impl_readDictionary(const dictionary& dict); + + /// Write to dictionary + bool impl_writeDictionary(dictionary& dict)const; + +public: + + // - Constructors + + /// Empty + MotionModel(); + + /// Copy constructor + MotionModel(const MotionModel&) = default; + + /// Move constructor + MotionModel(MotionModel&&) = default; + + /// Copy assignment + MotionModel& operator=(const MotionModel&) = default; + + /// No move assignment + MotionModel& operator=(MotionModel&&) = default; + + /// Destructor + ~MotionModel() = default; + + // - Methods + + /// name of the compoenent to index of the component + bool nameToIndex(const word& name, uint32& idx)const + { + return getModel().impl_nameToIndex(name, idx); + } + + /// Component index to motion component name + bool indexToName(uint32 idx, word& name)const + { + return getModel().impl_indexToName(idx, name); + } + + /// @brief Return a const reference to the list of compoenent names + /// @return + const wordList& componentNames()const + { + return getModel().impl_componentNames(); + } + + /// Is the wall assocciated to this motion component moving? + bool isMoving()const + { + return getModel().impl_isMoving(); + } + + /// Move the component itself + bool move(uint32 iter, real t, real dt) + { + return getModel().impl_move(iter, t, dt); + } + + /// Obtain an object to model interface + auto getModelInterface(uint32 iter, real t, real dt)const + { + return getModel().impl_getModelInterface(iter, t, dt); + } + +}; + +} // pFlow + +#include "MotionModel.cpp" + + +#endif //__MotionModel_hpp__ diff --git a/src/MotionModel/entities/multiRotatingAxis/multiRotatingAxis.hpp b/src/MotionModel/entities/multiRotatingAxis/multiRotatingAxis.hpp index 2f2d81de..c79e87c8 100644 --- a/src/MotionModel/entities/multiRotatingAxis/multiRotatingAxis.hpp +++ b/src/MotionModel/entities/multiRotatingAxis/multiRotatingAxis.hpp @@ -78,7 +78,7 @@ class multiRotatingAxis { protected: - /// This is either host/device pointer to all axes + /// This is device pointer to all axes multiRotatingAxis* axisList_; /// Index of parent axis @@ -170,7 +170,7 @@ public: /// Set the pointer to the list of all axes. /// This pointer is device pointer INLINE_FUNCTION_H - void setAxisList(multiRotatingAxis* axisList) + void setAxisListPtr(multiRotatingAxis* axisList) { axisList_ = axisList; } diff --git a/src/MotionModel/entities/rotatingAxis/rotatingAxis.cpp b/src/MotionModel/entities/rotatingAxis/rotatingAxis.cpp index dbb9206e..d5aa3ca2 100644 --- a/src/MotionModel/entities/rotatingAxis/rotatingAxis.cpp +++ b/src/MotionModel/entities/rotatingAxis/rotatingAxis.cpp @@ -28,7 +28,6 @@ pFlow::rotatingAxis::rotatingAxis const dictionary& dict ) { - if(!read(dict)) { fatalErrorInFunction<< @@ -73,7 +72,7 @@ bool pFlow::rotatingAxis::read if(!timeInterval::read(dict))return false; if(!line::read(dict)) return false; - real omega = dict.getValOrSet("omega", static_cast(0.0)); + real omega = dict.getValOrSet("omega", 0.0); setOmega(omega); return true; diff --git a/src/MotionModel/entities/rotatingAxis/rotatingAxis.hpp b/src/MotionModel/entities/rotatingAxis/rotatingAxis.hpp index ee37eba9..7d40f06e 100644 --- a/src/MotionModel/entities/rotatingAxis/rotatingAxis.hpp +++ b/src/MotionModel/entities/rotatingAxis/rotatingAxis.hpp @@ -24,13 +24,12 @@ Licence: #include "timeInterval.hpp" #include "line.hpp" +#include "rotatingAxisFwd.hpp" + namespace pFlow { class dictionary; -class rotatingAxis; - -#include "rotatingAxisFwd.hpp" /** * An axis which rotates around itself at specified speed @@ -64,7 +63,7 @@ class rotatingAxis public timeInterval, public line { -protected: +private: /// rotation speed real omega_ = 0; @@ -76,13 +75,15 @@ public: // - Constructor + TypeInfoNV("rotatingAxis"); + /// Empty constructor FUNCTION_HD - rotatingAxis(){} + rotatingAxis()=default; /// Construct from dictionary FUNCTION_H - rotatingAxis(const dictionary& dict); + explicit rotatingAxis(const dictionary& dict); /// Construct from components FUNCTION_HD @@ -92,9 +93,19 @@ public: FUNCTION_HD rotatingAxis(const rotatingAxis&) = default; + FUNCTION_HD + rotatingAxis(rotatingAxis&&) = default; + /// Copy asssignment rotatingAxis& operator=(const rotatingAxis&) = default; + /// Copy asssignment + rotatingAxis& operator=(rotatingAxis&&) = default; + + /// destructor + ~rotatingAxis()=default; + + /// Set omega FUNCTION_HD real setOmega(real omega); @@ -115,7 +126,10 @@ public: /// Linear tangential velocity at point p INLINE_FUNCTION_HD - realx3 linTangentialVelocityPoint(const realx3 &p)const; + realx3 linVelocityPoint(const realx3 &p)const; + + INLINE_FUNCTION_HD + realx3 transferPoint(const realx3 p, real dt)const; // - IO operation diff --git a/src/MotionModel/entities/rotatingAxis/rotatingAxisFwd.hpp b/src/MotionModel/entities/rotatingAxis/rotatingAxisFwd.hpp index 8cbfe593..140411c5 100755 --- a/src/MotionModel/entities/rotatingAxis/rotatingAxisFwd.hpp +++ b/src/MotionModel/entities/rotatingAxis/rotatingAxisFwd.hpp @@ -18,6 +18,11 @@ Licence: -----------------------------------------------------------------------------*/ +namespace pFlow +{ + +class rotatingAxis; + INLINE_FUNCTION_HD realx3 rotate(const realx3 &p, const line& ln, real theta); @@ -25,10 +30,10 @@ INLINE_FUNCTION_HD realx3 rotate(const realx3& p, const rotatingAxis& ax, real dt); INLINE_FUNCTION_HD -void rotate(realx3* p, size_t n, const line& ln, real theta); +void rotate(realx3* p, uint32 n, const line& ln, real theta); INLINE_FUNCTION_HD -void rotate(realx3* p, size_t n, const rotatingAxis& ax, real dt); - +void rotate(realx3* p, uint32 n, const rotatingAxis& ax, real dt); +} diff --git a/src/MotionModel/entities/rotatingAxis/rotatingAxisI.hpp b/src/MotionModel/entities/rotatingAxis/rotatingAxisI.hpp index c7563020..10a730cc 100755 --- a/src/MotionModel/entities/rotatingAxis/rotatingAxisI.hpp +++ b/src/MotionModel/entities/rotatingAxis/rotatingAxisI.hpp @@ -1,3 +1,4 @@ +#include "rotatingAxis.hpp" /*------------------------------- phasicFlow --------------------------------- O C enter of O O E ngineering and @@ -19,7 +20,7 @@ Licence: -----------------------------------------------------------------------------*/ INLINE_FUNCTION_HD -pFlow::realx3 pFlow::rotatingAxis::linTangentialVelocityPoint(const realx3 &p)const +pFlow::realx3 pFlow::rotatingAxis::linVelocityPoint(const realx3 &p)const { if(!inTimeRange()) return {0,0,0}; @@ -28,6 +29,12 @@ pFlow::realx3 pFlow::rotatingAxis::linTangentialVelocityPoint(const realx3 &p)co return cross(omega_*unitVector(),L); } +INLINE_FUNCTION_HD +pFlow::realx3 pFlow::rotatingAxis::transferPoint(const realx3 p, real dt)const +{ + return rotate(p, *this, dt); +} + INLINE_FUNCTION_HD pFlow::realx3 pFlow::rotate(const realx3& p, const rotatingAxis& ax, real dt) { @@ -97,7 +104,7 @@ pFlow::realx3 pFlow::rotate(const realx3 &p, const line& ln, real theta) } INLINE_FUNCTION_HD -void pFlow::rotate(realx3* p, size_t n, const line& ln, real theta) +void pFlow::rotate(realx3* p, uint32 n, const line& ln, real theta) { realx3 nv = ln.unitVector(); real cos_tet = cos(theta); @@ -110,7 +117,7 @@ void pFlow::rotate(realx3* p, size_t n, const line& ln, real theta) // (a(v2+w2) - u( bv + cw - ux - vy - wz)) (1-cos_tet) + x cos_tet + (- cv + bw - wy + vz) sin_tet realx3 res; - for(label i=0; i>(iIstream& is, stationary& obj) +{ + + return is; +} + +} + + +#endif diff --git a/src/MotionModel/entities/vibrating/vibrating.hpp b/src/MotionModel/entities/vibrating/vibrating.hpp index 4ece54a2..62241dfa 100644 --- a/src/MotionModel/entities/vibrating/vibrating.hpp +++ b/src/MotionModel/entities/vibrating/vibrating.hpp @@ -67,7 +67,7 @@ class vibrating public timeInterval { -protected: +private: // rotation speed realx3 angularFreq_{0,0,0}; @@ -94,11 +94,13 @@ protected: public: + TypeInfoNV("vibrating"); + FUNCTION_HD - vibrating(){} + vibrating()=default; FUNCTION_H - vibrating(const dictionary& dict); + explicit vibrating(const dictionary& dict); FUNCTION_HD @@ -115,16 +117,16 @@ public: } INLINE_FUNCTION_HD - realx3 linTangentialVelocityPoint(const realx3 &p)const + realx3 linVelocityPoint(const realx3 &)const { return velocity_; } INLINE_FUNCTION_HD - realx3 transferPoint(const realx3& p, real dt) + realx3 transferPoint(const realx3& p, real dt)const { if(!inTimeRange()) return p; - return p + static_cast(0.5)*dt*(velocity0_+velocity_); + return p + static_cast(0.5*dt)*(velocity0_+velocity_); } // - IO operation diff --git a/src/MotionModel/fixedWall/fixedWall.cpp b/src/MotionModel/fixedWall/fixedWall.cpp deleted file mode 100644 index 6c3dba2e..00000000 --- a/src/MotionModel/fixedWall/fixedWall.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/*------------------------------- 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 "fixedWall.hpp" -#include "dictionary.hpp" -#include "vocabs.hpp" - -bool pFlow::fixedWall::readDictionary -( - const dictionary& dict -) -{ - - auto motionModel = dict.getVal("motionModel"); - - if(motionModel != "fixedWall") - { - fatalErrorInFunction<< - " motionModel should be fixedWall, but found " << motionModel <("motionModel"); - - if(motionModel != "rotatingAxisMotion") - { - fatalErrorInFunction<< - " motionModel should be rotatingAxisMotion, but found " - << motionModel <(axDict); axPtr) - { - axis_.push_back(axPtr()); - axisName_.push_back(aName); - } - else - { - fatalErrorInFunction<< - "could not read rotating axis from "<< axDict.globalName()<impl_writeDictionary(newDict) || + !newDict.write(os)) + { + fatalErrorInFunction<< + " error in writing to dictionary "<< newDict.globalName()< { -public: - - /** Motion model class to be passed to computational units/kernels for - * transfing points and returning velocities at various positions - */ - class Model - { - protected: - - deviceViewType1D axis_; - int32 numAxis_=0; - - public: - - INLINE_FUNCTION_HD - Model(deviceViewType1D axis, int32 numAxis): - axis_(axis), - numAxis_(numAxis) - {} - - INLINE_FUNCTION_HD - Model(const Model&) = default; - - - INLINE_FUNCTION_HD - Model& operator=(const Model&) = default; - - - INLINE_FUNCTION_HD - realx3 pointVelocity(int32 n, const realx3& p)const - { - return axis_[n].linTangentialVelocityPoint(p); - } - - INLINE_FUNCTION_HD - realx3 operator()(int32 n, const realx3& p)const - { - return pointVelocity(n,p); - } - - INLINE_FUNCTION_HD - realx3 transferPoint(int32 n, const realx3 p, real dt)const - { - return rotate(p, axis_[n], dt); - } - - INLINE_FUNCTION_HD int32 numComponents()const - { - return numAxis_; - } - }; - protected: - using axisVector_HD = VectorDual; + friend MotionModel; - /// Vector to store axes - axisVector_HD axis_; + /// is the geometry attached to this component moving + bool impl_isMoving()const + { + return true; + } + + /// move the component itself + bool impl_move(uint32, real, real)const + { + return true; + } + + void impl_setTime(uint32 iter, real t, real dt)const; - /// Names of axes - wordList axisName_; - - /// Number of axes components - label numAxis_= 0; - - /// Read from dictionary - bool readDictionary(const dictionary& dict); - - /// Write to dictionary - bool writeDictionary(dictionary& dict)const; - public: - - /// Type info - TypeInfoNV("rotatingAxisMotion"); - // - Constructors - - /// Empty - FUNCTION_H - rotatingAxisMotion(); + TypeInfo("rotatingAxisMotion"); - /// Construct with dictionary - FUNCTION_H - rotatingAxisMotion(const dictionary& dict); + rotatingAxisMotion(const objectFile& objf, repository* owner); - /// Copy constructor - FUNCTION_H - rotatingAxisMotion(const rotatingAxisMotion&) = default; + rotatingAxisMotion( + const objectFile& objf, + const dictionary& dict, + repository* owner); - /// No move constructor - rotatingAxisMotion(rotatingAxisMotion&&) = delete; - /// Copy assignment - FUNCTION_H - rotatingAxisMotion& operator=(const rotatingAxisMotion&) = default; - - /// No move assignment - rotatingAxisMotion& operator=(rotatingAxisMotion&&) = delete; - - /// Destructor - FUNCTION_H - ~rotatingAxisMotion() = default; - - // - Methods - /// Return the motion model at time t - Model getModel(real t) - { - for(int32 i= 0; i("begin") - ), - end_ - ( - dict.subDict("selectRangeInfo").getValOrSet("end", pStruct.size()) - ), - stride_ - ( - dict.subDict("selectRangeInfo").getValOrSet("stride", 1) - ) + fileDictionary(objf, dict, owner) { - begin_ = max(begin_,1); - end_ = min(end_, static_cast(pStruct.size())); - stride_ = max(stride_,1); - - selectAllPointsInRange(); + if(!impl_readDictionary(*this) ) + { + fatalErrorInFunction; + fatalExit; + } +} + +bool pFlow::stationaryWall::write +( + iOstream &os, + const IOPattern &iop +) const +{ + // a global dictionary + dictionary newDict(fileDictionary::dictionary::name(), true); + if( iop.thisProcWriteData() ) + { + if( !this->impl_writeDictionary(newDict) || + !newDict.write(os)) + { + fatalErrorInFunction<< + " error in writing to dictionary "<< newDict.globalName()< +{ +protected: + + friend MotionModel; + + bool impl_isMoving()const + { + return false; + } + + bool impl_move(uint32, real, real)const + { + return true; + } + + void impl_setTime(uint32 ,real ,real )const + {} + +public: + + TypeInfo("stationaryWall"); + + stationaryWall(const objectFile& objf, repository* owner); + + stationaryWall( + const objectFile& objf, + const dictionary& dict, + repository* owner); + + + bool write(iOstream& os, const IOPattern& iop)const override; + + static + auto noneComponent() + { + return stationary(); + } +}; + +} // pFlow + + +#endif // __stationaryWall_hpp__ \ No newline at end of file diff --git a/src/MotionModel/vibratingMotion/vibratingMotion.cpp b/src/MotionModel/vibratingMotion/vibratingMotion.cpp index 1cc472a8..896a35e0 100644 --- a/src/MotionModel/vibratingMotion/vibratingMotion.cpp +++ b/src/MotionModel/vibratingMotion/vibratingMotion.cpp @@ -1,167 +1,66 @@ -/*------------------------------- 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 "vibratingMotion.hpp" -#include "dictionary.hpp" -#include "vocabs.hpp" - -bool pFlow::vibratingMotion::readDictionary +void pFlow::vibratingMotion::impl_setTime ( - const dictionary& dict -) -{ - - auto motionModel = dict.getVal("motionModel"); - - if(motionModel != "vibratingMotion") - { - fatalErrorInFunction<< - " motionModel should be vibratingMotion, but found " - << motionModel <(compDict); compPtr) - { - components_.push_back(compPtr()); - componentName_.push_back(cName); - } - else - { - fatalErrorInFunction<< - "could not read vibrating motion from "<< compDict.globalName()< { -public: - - /** Motion model class to be passed to computational units/kernels for - * transfing points and returning velocities at various positions - */ - class Model - { - protected: - - deviceViewType1D components_; - int32 numComponents_=0; - - public: - - INLINE_FUNCTION_HD - Model(deviceViewType1D comps, int32 numComps): - components_(comps), - numComponents_(numComps) - {} - - INLINE_FUNCTION_HD - Model(const Model&) = default; - - - INLINE_FUNCTION_HD - Model& operator=(const Model&) = default; - - - INLINE_FUNCTION_HD - realx3 pointVelocity(int32 n, const realx3& p)const - { - return components_[n].linTangentialVelocityPoint(p); - } - - INLINE_FUNCTION_HD - realx3 operator()(int32 n, const realx3& p)const - { - return pointVelocity(n,p); - } - - INLINE_FUNCTION_HD - realx3 transferPoint(int32 n, const realx3 p, real dt)const - { - return components_[n].transferPoint(p, dt); - } - - INLINE_FUNCTION_HD int32 numComponents()const - { - return numComponents_; - } - }; protected: - - using axisVector_HD = VectorDual; - - /// Vibrating motion components - axisVector_HD components_; - /// Names of components - wordList componentName_; + friend MotionModel; - /// Number of components - label numComponents_= 0; + bool impl_isMoving()const + { + return true; + } - /// Read from a dictionary - bool readDictionary(const dictionary& dict); + /// move the component itself + bool impl_move(uint32, real, real)const + { + return true; + } - /// Write to a dictionary - bool writeDictionary(dictionary& dict)const; + void impl_setTime(uint32 iter, real t, real dt)const; public: /// Type info - TypeInfoNV("vibratingMotion"); + TypeInfo("vibratingMotion"); + + vibratingMotion(const objectFile& objf, repository* owner); - /// Empty - FUNCTION_H - vibratingMotion(); - - /// Construct with dictionary - FUNCTION_H - vibratingMotion(const dictionary& dict); - - /// Copy constructor - FUNCTION_H - vibratingMotion(const vibratingMotion&) = default; - - /// No move - vibratingMotion(vibratingMotion&&) = delete; - - /// Copy assignment - FUNCTION_H - vibratingMotion& operator=(const vibratingMotion&) = default; - - /// No Move assignment - vibratingMotion& operator=(vibratingMotion&&) = delete; + vibratingMotion( + const objectFile& objf, + const dictionary& dict, + repository* owner); /// Destructor - FUNCTION_H - ~vibratingMotion() = default; + ~vibratingMotion()override = default; - /// Return motion model at time t - Model getModel(real t) - { - for(int32 i= 0; i -bool pFlow::Insertion::readInsertionDict -( - const dictionary& dict -) -{ - if(!insertion::readInsertionDict(dict)) return false; - - regions_.clear(); - - if( !this->isActive() ) - { - return true; - } - wordList regionDicNames = dict.dictionaryKeywords(); - - for(auto& name:regionDicNames) - { - REPORT(2)<<"reading insertion region "<< greenText(name)< bool pFlow::Insertion::writeInsertionDict @@ -50,7 +26,8 @@ bool pFlow::Insertion::writeInsertionDict dictionary& dict )const { - if( !insertion::writeInsertionDict(dict) ) return false; + + if(!insertion::writeInsertionDict(dict))return false; if( !this->isActive() ) return true; @@ -60,6 +37,8 @@ bool pFlow::Insertion::writeInsertionDict if( !regions_[i].write(rgnDict) ) { + fatalErrorInFunction<< + "Error in writing to dictionary "<::writeInsertionDict return true; } +template +bool +pFlow::Insertion::readInsertionDict() +{ + regions_.clear(); + + if( !this->isActive() ) + { + return true; + } + + wordList regionDicNames = this->dictionaryKeywords(); + + for(const auto& name:regionDicNames) + { + REPORT(2)<<"reading insertion region "<< Green_Text(name)<>( + name, + *this, + shapes_)); + } + + return true; + +} + template pFlow::Insertion::Insertion( particles& prtcl, @@ -75,11 +81,14 @@ pFlow::Insertion::Insertion( insertion(prtcl), shapes_(shapes) { - - + if(!readInsertionDict()) + { + fatalErrorInFunction; + fatalExit; + } } -template +/*template pFlow::Insertion::Insertion( fileSystem file, particles& prtcl, @@ -95,13 +104,14 @@ pFlow::Insertion::Insertion( file< bool pFlow::Insertion::insertParticles ( - real currentTime, + uint32 iter, + real t, real dt ) { @@ -112,21 +122,21 @@ bool pFlow::Insertion::insertParticles { bool insertionOccured = false; auto& rgn = regions_[i]; - if( rgn.insertionTime(currentTime, dt) ) + if( rgn.insertionTime(iter, t, dt) ) { realx3Vector pos; wordVector shapes; - if( rgn.insertParticles(currentTime, dt, shapes, pos, insertionOccured) ) + if( rgn.insertParticles(iter, t, dt, shapes, pos, insertionOccured) ) { if(insertionOccured) { - REPORT(0)<<"\nParticle insertion from "<< greenText(rgn.name())<::insertParticles return false; } REPORT(1)<<"Total number of particles inserted from this region is "<< - cyanText(rgn.totalInserted())<<'\n'<::insertParticles { if(insertionOccured) { - yWARNING<< "\n fewer number of particles are inserted from region "<< rgn.name() << - " than expected. You may stop the simulation to change settings."<::insertParticles } -template +/*template bool pFlow::Insertion::read ( iIstream& is @@ -217,4 +233,4 @@ bool pFlow::Insertion::write } return true; -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/src/Particles/Insertion/Insertion/Insertion.hpp b/src/Particles/Insertion/Insertion/Insertion.hpp index 09841253..ddeb9c56 100644 --- a/src/Particles/Insertion/Insertion/Insertion.hpp +++ b/src/Particles/Insertion/Insertion/Insertion.hpp @@ -2,30 +2,28 @@ O C enter of O O E ngineering and O O M ultiscale modeling of - OOOOOOO F luid flow + 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 + 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 + 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 __Insertion_hpp__ #define __Insertion_hpp__ - -#include "insertion.hpp" -#include "ListPtr.hpp" #include "InsertionRegion.hpp" +#include "ListPtr.hpp" +#include "insertion.hpp" #include "particles.hpp" namespace pFlow @@ -34,57 +32,55 @@ namespace pFlow /** * This class manages all the insertion regions for particles insertion * in the simulation. - * + * * Any number of insertion regions can be defined in a simulation. The - * data for particle insertion is provided in particleInsertion file, which - * looks like this. A list of insertion regions (class insertionRegion) can be defined in this file. - * For more information see file insertionRegion.hpp. + * data for particle insertion is provided in particleInsertion file, which + * looks like this. A list of insertion regions (class insertionRegion) can be +defined in this file. + * For more information see file insertionRegion.hpp. * \verbatim active yes; region1 { - // the data for insertionRegion + // the data for insertionRegion } region2 { - // Data for insertionRegion + // Data for insertionRegion } \endverbatim */ template -class Insertion -: - public insertion +class Insertion : public insertion { +private: + + const ShapeType& shapes_; + + // - insertion regions + ListPtr> regions_; + + bool readInsertionDict(); + protected: - const ShapeType& shapes_; - - // - insertion regions - ListPtr> regions_; - - - bool readInsertionDict(const dictionary& dict); - - bool writeInsertionDict(dictionary& dict)const; + bool writeInsertionDict(dictionary& dict)const override; public: - TypeInfoTemplateNV("Insertion",ShapeType); + TypeInfoTemplateNV11("Insertion", ShapeType); Insertion(particles& prtcl, const ShapeType& shapes); - Insertion(fileSystem file, particles& prtcl, const ShapeType& shapes); + // Insertion(fileSystem file, particles& prtcl, const ShapeType& shapes); + bool insertParticles(uint32 iter, real t, real dt); - bool insertParticles(real currentTime, real dt); - - virtual bool read(iIstream& is) override; - - virtual bool write(iOstream& os)const override; + /*virtual bool read(iIstream& is) override; + virtual bool write(iOstream& os)const override;*/ }; } diff --git a/src/Particles/Insertion/InsertionRegion/InsertionRegion.cpp b/src/Particles/Insertion/InsertionRegion/InsertionRegion.cpp index 57404bf7..4434f64b 100644 --- a/src/Particles/Insertion/InsertionRegion/InsertionRegion.cpp +++ b/src/Particles/Insertion/InsertionRegion/InsertionRegion.cpp @@ -39,77 +39,211 @@ bool pFlow::InsertionRegion::checkForContact template pFlow::InsertionRegion::InsertionRegion ( - const dictionary& dict, + const word& name, + const insertion& instn, const ShapeType& shapes ) : - insertionRegion(dict), + insertionRegion(name, instn), shapes_(shapes) -{ - -} +{} template bool pFlow::InsertionRegion::insertParticles ( - real currentTime, + uint32 iter, + real t, real dt, - wordVector& names, - realx3Vector& pos, + wordVector& names, + realx3Vector& positions, bool& insertionOccured ) { insertionOccured = false; - if(!insertionTime( currentTime, dt)) return true; + if(!insertionTime(iter, t, dt)) return true; - size_t newNum = numberToBeInserted(currentTime); - + uint32 newNum = numberToBeInserted(iter, t, dt); if(newNum == 0) return true; - names.reserve(max(newNum,names.capacity())); - pos.reserve(max(newNum,pos.capacity())); - names.clear(); - pos.clear(); - - realVector diams(newNum, RESERVE()); - - mixture_->getNextShapeNameN(newNum, names); - - if(!shapes_.shapeToDiameter(names,diams)) + // get the internal box + auto internalBox = pStruct().internalDomainBox(); + if( !(internalBox.minPoint() < internalBox.maxPoint())) { - fatalErrorInFunction<< - " error occured in insertion region "<< name() << - " while converting shapes to diameter. \n"; + WARNING<<"Minimum point of internal point is not lower than "<< + "the maximum point \n"<< + "minimum point: "<< internalBox.minPoint()<< + "\nmaximum point:"< + ( + selector(), + Insertion().diameterName() + ); } + + auto collCheck = collisionCheck( + {minP, maxP}, + maxDiam, + allPositions, + allDiameters); - fatalErrorInFunction<< - " Cannot insert "<< newNum << " new particles from region "<< name()<<". \n" - " pFlow could position only "<< n<< " particles in this region. \n"; - addToNumInserted(n); - insertionOccured = false; - return false; + uint32 numInserted = 0; -} \ No newline at end of file + uint32 idx; + word name = mix.getNextShapeName(); + shapes_.shapeNameToIndex(name, idx); + real d = shapes_.boundingDiameter(idx); + + for(uint32 i=0; i< 100*newNum ; ++i) + { + realx3 p = pReg.peek(); + // check if point is inside internal box + if(!internalBox.isInside(p))continue; + + if( collCheck.checkPoint( p, d) ) + { + names.push_back(name); + positions.push_back(p); + numInserted++; + if( numInserted == newNum ) break; + + // add this new particle to collision check set + allDiameters.push_back(d); + allPositions.push_back(p); + collCheck.mapLastAddedParticle(); + + // obtain next shape name and diameter + name = mix.getNextShapeName(); + shapes_.shapeNameToIndex(name, idx); + d = shapes_.boundingDiameter(idx); + } + + } + + insertionOccured = true; + addToNumInserted(numInserted); + return numInserted == newNum; +} + + + +/*if(!checkForCollision) + { + realVector diams("diams", newNum, 0, RESERVE()); + + uint32 idx; + word name = mix.getNextShapeName(); + shapes_.shapeNameToIndex(name, idx); + real d = shapes_.boundingDiameter(idx); + + for(uint32 i=0; i< 100*newNum ; ++i) + { + realx3 p = pReg.peek(); + // check if point is inside internal box + if(!internalBox.isInside(p))continue; + + if( !checkForContact(positions, diams, p, d) ) + { + names.push_back(name); + positions.push_back(p); + diams.push_back(d); + numInserted++; + + if( numInserted == newNum ) break; + + name = mix.getNextShapeName(); + shapes_.shapeNameToIndex(name, idx); + d = shapes_.boundingDiameter(idx); + } + } + } + else + { + real maxDiam = shapes_.maxBoundingSphere(); + auto minP = pReg.minPoint() - maxDiam; + auto maxP = pReg.maxPoint() + maxDiam; + auto bDict = dictionary("boxInfo"); + bDict.add("min", minP); + bDict.add("max", maxP); + auto selector = pStructSelector::create( + "box", + pStruct(), + bDict); + + auto allPositions = selector().selectedPointPositions(); + auto allDiameters = selectedFieldVals(selector(), "diameter"); + auto collCheck = collisionCheck( + {minP, maxP}, + maxDiam, + allPositions, + allDiameters); + + uint32 idx; + word name = mix.getNextShapeName(); + shapes_.shapeNameToIndex(name, idx); + real d = shapes_.boundingDiameter(idx); + + for(uint32 i=0; i< 100*newNum ; ++i) + { + realx3 p = pReg.peek(); + // check if point is inside internal box + if(!internalBox.isInside(p))continue; + + if( collCheck.checkPoint( p, d) ) + { + names.push_back(name); + positions.push_back(p); + numInserted++; + if( numInserted == newNum ) break; + + // add this new particle to collision check set + allDiameters.push_back(d); + allPositions.push_back(p); + collCheck.mapLastAddedParticle(); + + // obtain next shape name and diameter + name = mix.getNextShapeName(); + shapes_.shapeNameToIndex(name, idx); + d = shapes_.boundingDiameter(idx); + } + + } + }*/ \ No newline at end of file diff --git a/src/Particles/Insertion/InsertionRegion/InsertionRegion.hpp b/src/Particles/Insertion/InsertionRegion/InsertionRegion.hpp index 3830d311..526dde6b 100644 --- a/src/Particles/Insertion/InsertionRegion/InsertionRegion.hpp +++ b/src/Particles/Insertion/InsertionRegion/InsertionRegion.hpp @@ -2,17 +2,17 @@ O C enter of O O E ngineering and O O M ultiscale modeling of - OOOOOOO F luid flow + 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 + 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 + 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. @@ -21,93 +21,77 @@ Licence: #ifndef __InsertionRegion_hpp__ #define __InsertionRegion_hpp__ - #include "insertionRegion.hpp" #include "dictionary.hpp" +#include "pointStructure.hpp" +#include "insertion.hpp" +#include "collisionCheck.hpp" +#include "pStructSelector.hpp" +#include "fieldSelector.hpp" + + namespace pFlow { /** * This manages insertion of particles from a region based on the ShapeType - * + * */ template -class InsertionRegion -: - public insertionRegion +class InsertionRegion + : public insertionRegion { -protected: +private: /// Ref to Shapes - const ShapeType& shapes_; + const ShapeType& shapes_; - static bool checkForContact( - const realx3Vector& pos, - const realVector& diams, - const realx3& p, - const real& d); + static bool checkForContact( + const realx3Vector& pos, + const realVector& diams, + const realx3& p, + const real& d + ); public: /// Type info - TypeInfoTemplateNV("insertionRegion", ShapeType); + TypeInfoTemplateNV11("insertionRegion", ShapeType); // - Constructors - /// Construct from dictionary - InsertionRegion(const dictionary& dict, const ShapeType& shapes); + /// Construct from dictionary + InsertionRegion( + const word& name, + const insertion& instn, + const ShapeType& shapes + ); - /// Copy - InsertionRegion(const InsertionRegion& ) = default; - - /// Move - InsertionRegion(InsertionRegion&&) = default; - - /// Copy assignment - InsertionRegion& operator=(const InsertionRegion& ) = default; - - /// Copy assignment - InsertionRegion& operator=(InsertionRegion&&) = default; - - /// Clone - auto clone()const - { - return makeUnique>(*this); - } - - /// Clone ptr - auto clonePtr()const - { - return new InsertionRegion(*this); - } + ~InsertionRegion() = default; // - Methods - - /// Insert particles at currentTime - /// Check if currentTime is the right moment for - /// particle insertion. Fill the vectors name, pos and signal - /// if particle insertion occured or not. - bool insertParticles - ( - real currentTime, - real dt, - wordVector& names, - realx3Vector& pos, - bool& insertionOccured - ); - //bool read(const dictionary& dict); + /// Insert particles at current time t + /// Check if currentTime is the right moment for + /// particle insertion. Fill the vectors name, pos and signal + /// if particle insertion occured or not. + bool insertParticles( + uint32 iter, + real t, + real dt, + wordVector& names, + realx3Vector& pos, + bool& insertionOccured + ); - //bool write(dictionary& dict)const; + // bool read(const dictionary& dict); + // bool write(dictionary& dict)const; }; - - } // pFlow - #include "InsertionRegion.cpp" #endif diff --git a/src/Particles/Insertion/collisionCheck/collisionCheck.cpp b/src/Particles/Insertion/collisionCheck/collisionCheck.cpp new file mode 100644 index 00000000..5cb7b470 --- /dev/null +++ b/src/Particles/Insertion/collisionCheck/collisionCheck.cpp @@ -0,0 +1,104 @@ +#include "collisionCheck.hpp" + +bool +pFlow::collisionCheck::build() +{ + fill(head_, static_cast(-1)); + fill(next_, static_cast(-1)); + + for (auto i = 0uL; i < position_.size(); i++) + { + if(!searchBox_.isInside(position_[i])) + { + fatalErrorInFunction<< + "Point "<< position_[i]<< "is not in search box"<(i); + } + + return true; +} + +pFlow::collisionCheck::collisionCheck( + box sBox, + real dx, + const realx3Vector& pos, + const realVector& diam +) + : searchBox_(sBox), + dx_(dx), + nCells_((sBox.maxPoint() - sBox.minPoint()) / dx + realx3(1.0)), + position_(pos), + diameters_(diam), + next_("next", pos.size()), + head_("head", nCells_.x(), nCells_.y(), nCells_.z()) +{ + if(!build()) + { + fatalExit; + } +} + +bool +pFlow::collisionCheck::checkPoint(const realx3& p, const real d) const +{ + + if(!searchBox_.isInside(p)) return false; + + const auto ind = pointIndex(p); + const auto startInd = max(ind - 1 ,int32x3(0)); + const auto endInd = min( ind+1 ,nCells_-1); + + for(int32 i=startInd.x(); i<=endInd.x(); i++) + { + for(int32 j=startInd.y(); j<=endInd.y(); j++) + { + for(int32 k=startInd.z(); k<=endInd.z(); k++) + { + uint32 n = head_(i, j, k); + + while( n != -1) + { + if( ((position_[n]-p).length() - 0.5*(diameters_[n]+d )) <= 0.0 ) + { + return false; + } + n = next_[n]; + } + } + } + } + + return true; +} + +bool +pFlow::collisionCheck::mapLastAddedParticle() +{ + size_t n = position_.size()-1; + if( next_.size() != n ) + { + fatalErrorInFunction<< + "size mismatch of next and position"<(n); + + return true; +} diff --git a/src/Particles/Insertion/collisionCheck/collisionCheck.hpp b/src/Particles/Insertion/collisionCheck/collisionCheck.hpp new file mode 100644 index 00000000..f0a6b267 --- /dev/null +++ b/src/Particles/Insertion/collisionCheck/collisionCheck.hpp @@ -0,0 +1,54 @@ + +#ifndef __collisionCheck_hpp__ +#define __collisionCheck_hpp__ + +#include "Vectors.hpp" +#include "VectorSingles.hpp" +#include "box.hpp" + + +namespace pFlow +{ + +class collisionCheck +{ +private: + + box searchBox_; + + real dx_; + + int32x3 nCells_; + + const realx3Vector& position_; + + const realVector& diameters_; + + uint32Vector next_; + + ViewType3D head_; + + int32x3 pointIndex(const realx3& p)const + { + return int32x3( (p - searchBox_.minPoint())/dx_ ); + } + + bool build(); + +public: + + collisionCheck( + box sBox, + real dx, + const realx3Vector& pos, + const realVector& diam + ); + + bool checkPoint(const realx3& p, const real d)const; + + bool mapLastAddedParticle(); +}; + +} + +#endif //__collisionCheck_hpp__ \ No newline at end of file diff --git a/src/Particles/Insertion/insertion/insertion.cpp b/src/Particles/Insertion/insertion/insertion.cpp index 18b53d2c..d8d0881d 100644 --- a/src/Particles/Insertion/insertion/insertion.cpp +++ b/src/Particles/Insertion/insertion/insertion.cpp @@ -2,73 +2,152 @@ O C enter of O O E ngineering and O O M ultiscale modeling of - OOOOOOO F luid flow + 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 + 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 + 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 "particles.hpp" -#include "dictionary.hpp" #include "insertion.hpp" +#include "particles.hpp" #include "streams.hpp" +#include "systemControl.hpp" +#include "vocabs.hpp" -bool pFlow::insertion::readInsertionDict -( - const dictionary& dict -) +pFlow::insertion::insertion(particles& prtcl) + : fileDictionary( + objectFile( + insertionFile__, + "", + objectFile::READ_IF_PRESENT, + objectFile::WRITE_ALWAYS + ), + &prtcl.time() + ), + particles_(prtcl) { - - active_ = dict.getVal("active"); - - if(active_) - REPORT(1)<< "Particle insertion mechanism is "<< - yellowText("active")<<" in the simulation."<("active"); + + if (active_) { - fatalErrorInFunction<< - " error in writing active to dictionary "<("checkForCollision"); + + REPORT(1) << "Particle insertion mechanism is " << Yellow_Text("active") + << " in the simulation." << END_REPORT; + } + else + { + REPORT(1) << "Particle insertion mechanism is " + << Yellow_Text("not active") << " in the simulation." + << END_REPORT; + } + return true; +} + +bool +pFlow::insertion::writeInsertionDict(dictionary& dict) const +{ + if (!dict.add("active", active_)) + { + fatalErrorInFunction <<"Error in writing active to dictionary " + < +bool +setOneEntry(const twoPartEntry& tpEntry, anyList& varList) +{ + if (getTypeName() != tpEntry.firstPart()) + return false; - name_ = dict.name(); - type_ = dict.getVal("type"); - - pRegion_ = peakableRegion::create(type_, dict.subDict(type_+"Info")); - - mixture_ = makeUnique(dict.subDict("mixture")); + T val = tpEntry.secondPartVal(); + varList.emplaceBack(tpEntry.keyword(), val); - addToNumInserted(mixture_().totalInserted()); + return true; +} - if( !dict.containsDictionay("setFields")) +bool +readOneEtrty(const dataEntry& entry, anyList& varList) +{ + twoPartEntry stField(entry); + + if (!(setOneEntry(stField, varList) || + setOneEntry(stField, varList) || + setOneEntry(stField, varList) || + setOneEntry(stField, varList) || + setOneEntry(stField, varList) || + setOneEntry(stField, varList) || + setOneEntry(stField, varList) || + setOneEntry(stField, varList) || + setOneEntry(stField, varList))) { - output<<"\n insertion region "<< name_ << " does not contain setFields dictionary." - " An empty dictoiinary is created for it. \n"; - setFields_ = makeUnique( dictionary("setFields") ); + fatalErrorInFunction << "un-supported data type " << stField.firstPart() + << endl; + return false; } - else + return true; +} +} + +bool +pFlow::insertionRegion::readInsertionRegion(const dictionary& dict) +{ + type_ = dict.getVal("regionType"); + + rate_ = dict.getVal("rate"); + + pRegion_ = peakableRegion::create(type_, dict.subDict(type_ + "Info")); + + mixture_ = makeUnique( + dict.subDict("mixture"), + insertion_.Particles().getShapes().shapeNameList() + ); + + numInserted_ = mixture_().totalInserted(); + + if (dict.containsDictionay("setFields")) { - setFields_ = makeUnique( dict.subDict("setFields") ); + setFieldDict_ = + makeUnique("setFields", dict, dict.subDict("setFields")); } - for(auto& sfEntry:setFields_()) + if (setFieldDict_) { - if(!sfEntry.checkForTypeAndValueAll()) + if (!readSetFieldDict()) { - fatalErrorInFunction<< - " error in setFields dictionary "<< dict.globalName()<clone(): nullptr), - mixture_( src.mixture_? src.mixture_->clone(): nullptr), - setFields_( src.setFields_? src.setFields_->clone(): nullptr) -{} - -pFlow::insertionRegion& pFlow::insertionRegion::operator= -( - const insertionRegion& src -) +const pFlow::pointStructure& +pFlow::insertionRegion::pStruct() const { - - if(&src == this)return *this; - timeFlowControl::operator=(src); - - name_ = src.name_; - type_ = src.type_; - pRegion_ = (src.pRegion_? src.pRegion_->clone(): nullptr); - mixture_ = (src.mixture_? src.mixture_->clone(): nullptr); - setFields_ = (src.setFields_? src.setFields_->clone(): nullptr); - - return *this; + return Insertion().pStruct(); } +pFlow::uint32 +pFlow::insertionRegion::numberToBeInserted(uint32 iter, real t, real dt) +{ + if (!tControl_.isInRange(iter, t, dt)) + return 0u; + if (tControl_.isTimeStep()) + { + return static_cast( + (iter - tControl_.startIter() + tControl_.iInterval()) * dt * rate_ - + numInserted_ + ); + } + else + { + return static_cast( + (t - tControl_.startTime() + tControl_.rInterval()) * rate_ - + numInserted_ + ); + } +} diff --git a/src/Particles/Insertion/insertionRegion/insertionRegion.hpp b/src/Particles/Insertion/insertionRegion/insertionRegion.hpp index d0f6ea5d..9b4a73db 100644 --- a/src/Particles/Insertion/insertionRegion/insertionRegion.hpp +++ b/src/Particles/Insertion/insertionRegion/insertionRegion.hpp @@ -2,17 +2,17 @@ O C enter of O O E ngineering and O O M ultiscale modeling of - OOOOOOO F luid flow + 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 + 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 + 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. @@ -21,52 +21,55 @@ Licence: #ifndef __insertionRegion_hpp__ #define __insertionRegion_hpp__ -#include "timeFlowControl.hpp" +#include "anyList.hpp" +#include "baseTimeControl.hpp" +#include "peakableRegion.hpp" #include "shapeMixture.hpp" -#include "peakableRegions.hpp" -#include "setFieldList.hpp" namespace pFlow { class dictionary; +class insertion; +class pointStructure; /** * This class defines all the necessary enteties for defining an insertion - * region. - * - * Insertion region information are supplied through a dictionary in a file. + * region. + * + * Insertion region information are supplied through a dictionary in a file. * For example: \verbatim { - type cylinderRegion; // type of insertion region - rate 15000; // insertion rate (particles/s) - startTime 0; // (s) - endTime 0.5; // (s) - interval 0.025; // (s) + type cylinderRegion; // type of insertion region + rate 15000; // insertion rate (particles/s) + startTime 0; // (s) + endTime 0.5; // (s) + interval 0.025; // (s) - cylinderRegionInfo - { - radius 0.09; // radius of cylinder (m) - p1 (0.0 0.0 0.10); // (m,m,m) - p2 (0.0 0.0 0.11); // (m,m,m) - } - - setFields - { - velocity realx3 (0.0 0.0 -0.6); // initial velocity of inserted particles - } - - mixture - { - lightSphere 1; // mixture composition of inserted particles - } + cylinderRegionInfo + { + radius 0.09; // radius of cylinder (m) + p1 (0.0 0.0 0.10); // (m,m,m) + p2 (0.0 0.0 0.11); // (m,m,m) + } + + setFields + { + velocity realx3 (0.0 0.0 -0.6); // initial velocity of inserted +particles + } + + mixture + { + lightSphere 1; // mixture composition of inserted particles + } } \endverbatim - * + * * More information on the above dictionary entries can be found in * the table below. - * - * + * + * * | Parameter | Type | Description | Optional [default value] | * |----| :---: | ---- | ---- | * | type | word | type of the insertion region with name ### | No | @@ -75,31 +78,51 @@ class dictionary; * | endTime | real | end of insertion (s) | No | * | interval | real | time interval between successive insertions (s) | No | * | ###Info | dictionary | data for insertion region | No | - * | setFields | dictionary | set field for inserted particles (s) | Yes [empty dictionray] | + * | setFields | dictionary | set field for inserted particles (s) | Yes [empty +dictionray] | * | mixture | dictionary | mixture of particles to be inserted (s) | No | - * + * */ class insertionRegion -: - public timeFlowControl { -protected: +private: - /// name of the region - word name_; + /// name of this region + const word name_; + + /// insertion region dictionary + const dictionary& dict_; + + /// ref to insertion + const insertion& insertion_; + + /// @brief time control for insertion events + baseTimeControl tControl_; + + /// rate of insertion + real rate_; + + /// number of inserted particles + uint32 numInserted_ = 0; /// type of insertion region - word type_; + word type_; /// peakable region of points - uniquePtr pRegion_ = nullptr; + uniquePtr pRegion_ = nullptr; - /// mixture of shapes - uniquePtr mixture_ = nullptr; + /// mixture of shapes + uniquePtr mixture_ = nullptr; - /// setFields for insertion region - uniquePtr setFields_ = nullptr; + /// @brief dictionary for set field + uniquePtr setFieldDict_ = nullptr; + /// list of (filedName type value) for the fields + anyList setFieldList_; + +private: + + // - private methods /// read from dictionary bool readInsertionRegion(const dictionary& dict); @@ -107,6 +130,7 @@ protected: /// write to dictionary bool writeInsertionRegion(dictionary& dict) const; + bool readSetFieldDict(); public: @@ -115,58 +139,87 @@ public: // - Constructors - /// Construct from a dictionary - insertionRegion(const dictionary& dict); + /// Construct from a dictionary + insertionRegion(const word& name, const insertion& instn); - /// Copy - insertionRegion(const insertionRegion& src); + /// Destructor + ~insertionRegion() = default; - /// Move - insertionRegion(insertionRegion&&) = default; + // - Methods - /// Copy assignment - insertionRegion& operator=(const insertionRegion&); + /// Const ref to name of the region + const auto& name() const + { + return name_; + } - /// Move assignment - insertionRegion& operator=(insertionRegion&&) = default; + /// return type of insertion region + const auto& type() const + { + return type_; + } - /// Destructor - ~insertionRegion() = default; + const auto& dict()const + { + return dict_; + } + const auto& Insertion() const + { + return insertion_; + } - // - Methods + const pointStructure& pStruct()const; - /// Const ref to setFields - const auto& setFields()const - { - return setFields_(); - } + inline bool insertionTime(uint32 iter, real t, real dt) const + { + return tControl_.timeEvent(iter, t, dt); + } - /// Const ref to name of the region - const auto& name()const - { - return name_; - } + uint32 numberToBeInserted(uint32 iter, real t, real dt); + inline uint32 addToNumInserted(uint32 newInserted) + { + return numInserted_ += newInserted; + } + + inline uint32 totalInserted() const + { + return numInserted_; + } + + auto& mixture() + { + return mixture_(); + } + + auto& pRegion() + { + return pRegion_(); + } + + const auto& setFieldList() const + { + return setFieldList_; + } // - IO operation - /// read from dictionary - bool read(const dictionary& dict) - { - if(!timeFlowControl::read(dict))return false; + /// read from dictionary + /*bool read(const dictionary& dict) + { + if (!timeFlowControl::read(dict)) + return false; - return readInsertionRegion(dict); - } + return readInsertionRegion(dict); + }*/ - /// write to dictionary - bool write(dictionary& dict)const - { - if(!timeFlowControl::write(dict)) return false; - - return writeInsertionRegion(dict); - } + /// write to dictionary + bool write(dictionary& dict) const + { + return writeInsertionRegion(dict); + } }; -} //pFlow +} // pFlow #endif //__insertionRegion_hpp__ diff --git a/src/Particles/Insertion/insertionRegion/timeFlowControl.cpp b/src/Particles/Insertion/insertionRegion/timeFlowControl.cpp deleted file mode 100644 index d92241aa..00000000 --- a/src/Particles/Insertion/insertionRegion/timeFlowControl.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/*------------------------------- 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 "timeFlowControl.hpp" -#include "dictionary.hpp" - -size_t pFlow::timeFlowControl::numberToBeInserted(real currentTime) -{ - if(currentTimeendTime_) return 0; - - return static_cast - ( - (currentTime - startTime_ + interval_)*rate_ - numInserted_ - ); -} - -bool pFlow::timeFlowControl::readTimeFlowControl -( - const dictionary& dict -) -{ - rate_ = dict.getVal("rate"); - startTime_ = dict.getVal("startTime"); - endTime_ = dict.getVal("endTime"); - interval_ = dict.getVal("interval"); - numInserted_=0; - return true; -} - -bool pFlow::timeFlowControl::writeTimeFlowControl -( - dictionary& dict -) const -{ - if(!dict.add("rate", rate_)) return false; - if(!dict.add("startTime", startTime_)) return false; - if(!dict.add("endTime", endTime_)) return false; - if(!dict.add("interval", interval_)) return false; - - return true; -} - - -pFlow::timeFlowControl::timeFlowControl -( - const dictionary& dict -) -{ - - if(!readTimeFlowControl(dict)) - { - fatalExit; - } - -} - -bool pFlow::timeFlowControl::insertionTime( real currentTime, real dt) -{ - if(currentTime < startTime_) return false; - - if(currentTime > endTime_) return false; - if( mod(abs(currentTime-startTime_),interval_)/dt < 1 ) return true; - - return false; -} \ No newline at end of file diff --git a/src/Particles/Insertion/insertionRegion/timeFlowControl.hpp b/src/Particles/Insertion/insertionRegion/timeFlowControl.hpp deleted file mode 100644 index 5ac963dd..00000000 --- a/src/Particles/Insertion/insertionRegion/timeFlowControl.hpp +++ /dev/null @@ -1,101 +0,0 @@ -/*------------------------------- 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 __timeFlowControl_hpp__ -#define __timeFlowControl_hpp__ - -#include "types.hpp" -#include "streams.hpp" - -namespace pFlow -{ - -class dictionary; - -/** - * Time control for particle insertion - */ -class timeFlowControl -{ -protected: - - /// start time of insertion - real startTime_; - - /// end time of insertion - real endTime_; - - /// time interval between each insertion - real interval_; - - /// rate of insertion - real rate_; - - /// number of inserted particles - size_t numInserted_ = 0; - - - /// Read dictionary - bool readTimeFlowControl(const dictionary& dict); - - /// Write to dictionary - bool writeTimeFlowControl(dictionary& dict) const; - - /// Return number of particles to be inserted at time currentTime - size_t numberToBeInserted(real currentTime); - - /// Add to numInserted - inline - size_t addToNumInserted(size_t newInserted) - { - return numInserted_ += newInserted; - } - -public: - - /// Construct from dictionary - timeFlowControl(const dictionary& dict); - - /// Is currentTime the insertion moment? - bool insertionTime( real currentTime, real dt); - - /// Total number inserted so far - size_t totalInserted()const - { - return numInserted_; - } - - /// Read from dictionary - bool read(const dictionary& dict) - { - return readTimeFlowControl(dict); - } - - /// Write to dictionary - bool write(dictionary& dict)const - { - return writeTimeFlowControl(dict); - } - -}; - -} - -#endif //__timeFlowControl_hpp__ diff --git a/src/Particles/Insertion/shapeMixture/shapeMixture.cpp b/src/Particles/Insertion/shapeMixture/shapeMixture.cpp index 041f71dc..1038af15 100755 --- a/src/Particles/Insertion/shapeMixture/shapeMixture.cpp +++ b/src/Particles/Insertion/shapeMixture/shapeMixture.cpp @@ -2,150 +2,167 @@ O C enter of O O E ngineering and O O M ultiscale modeling of - OOOOOOO F luid flow + 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 + 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 + 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 "shapeMixture.hpp" #include "dictionary.hpp" - -pFlow::shapeMixture::shapeMixture -( - const dictionary & dict +pFlow::shapeMixture::shapeMixture( + const dictionary& dict, + const wordList& validNames ) { - if( !read(dict)) + if (!read(dict)) { fatalExit; } + + for (const auto& rN : names_) + { + bool found = false; + for (const auto& vN : validNames) + { + if (rN == vN) + { + found = true; + break; + } + } + + if (!found) + { + fatalErrorInFunction + << "Shape name " << rN << " provided in mixture dictionary " + << dict.globalName() << " is invalid. \n Valid names are " + << validNames << endl; + } + } } -pFlow::word pFlow::shapeMixture::getNextShapeName() +pFlow::word +pFlow::shapeMixture::getNextShapeName() { - ForAll(i, names_) { - if(current_[i]< number_[i]) + if (current_[i] < number_[i]) { current_[i]++; numberInserted_[i]++; return names_[i]; } } - + fill(current_, static_cast(0)); return getNextShapeName(); } -void pFlow::shapeMixture::getNextShapeNameN -( - size_t n, - wordVector& names -) +void +pFlow::shapeMixture::getNextShapeNameN(size_t n, wordVector& names) { names.clear(); - - for(label i=0; i(nm); - if( num <= 0 ) - { - fatalErrorInFunction<< - " number inserte in front of "<< nm << " is invalid: "<< num<(nm); + if (num <= 0) + { + fatalErrorInFunction << " number inserte in front of " << nm + << " is invalid: " << num << endl + << " in dictionary " << dict.globalName() + << endl; + return false; + } + number_.push_back(num); + } - if(containNumberIneserted) - { - numberInserted_ = dict.getVal("numberInserted"); - } - else - { - numberInserted_ = uint32Vector(size(), static_cast(0)); - } + if (containNumberIneserted) + { + numberInserted_ = dict.getVal("numberInserted"); + } + else + { + numberInserted_ = + uint32Vector(numberInserted_.name(), size(), static_cast(0)); + } - if(numberInserted_.size() != names_.size() ) - { - fatalErrorInFunction<< - " number of elements in numberInserted ("<(*this); } - /// Polymorphic copy - shapeMixture* clonePtr()const - { - return new shapeMixture(*this); - } - - /// Destructor ~shapeMixture() = default; diff --git a/src/Particles/SphereParticles/sphereParticles/sphereParticles.cpp b/src/Particles/SphereParticles/sphereParticles/sphereParticles.cpp index f1d71012..55eb3660 100644 --- a/src/Particles/SphereParticles/sphereParticles/sphereParticles.cpp +++ b/src/Particles/SphereParticles/sphereParticles/sphereParticles.cpp @@ -19,10 +19,13 @@ Licence: -----------------------------------------------------------------------------*/ #include "sphereParticles.hpp" -#include "setFieldList.hpp" +#include "systemControl.hpp" +#include "vocabs.hpp" #include "sphereParticlesKernels.hpp" -pFlow::uniquePtr> + +//#include "setFieldList.hpp" +/*pFlow::uniquePtr> pFlow::sphereParticles::getFieldObjectList()const { auto objListPtr = particles::getFieldObjectList(); @@ -78,10 +81,10 @@ bool pFlow::sphereParticles::initializeParticles() static_cast(shapeName_.size())); return insertSphereParticles(shapeName_, indices, false); -} +}*/ -bool pFlow::sphereParticles::beforeIteration() +/*bool pFlow::sphereParticles::beforeIteration() { particles::beforeIteration(); @@ -98,45 +101,19 @@ bool pFlow::sphereParticles::beforeIteration() intPredictTimer_.end(); return true; -} +}*/ -bool pFlow::sphereParticles::iterate() -{ - - accelerationTimer_.start(); - //INFO<<"before accelerationTimer_ "<dt(), accelertion_); - - rVelIntegration_().correct(this->dt(), rVelocity_, rAcceleration_); - - intCorrectTimer_.end(); - - return true; -} -bool pFlow::sphereParticles::afterIteration() + +/*bool pFlow::sphereParticles::afterIteration() { return true; -} +}*/ -bool pFlow::sphereParticles::insertSphereParticles( +/*bool pFlow::sphereParticles::insertSphereParticles( const wordVector& names, const int32IndexContainer& indices, bool setId @@ -219,86 +196,213 @@ bool pFlow::sphereParticles::insertSphereParticles( return true; +}*/ + +bool pFlow::sphereParticles::initializeParticles() +{ + + using exeSpace = typename realPointField_D::execution_space; + using policy = Kokkos::RangePolicy< + exeSpace, + Kokkos::IndexType>; + + auto [minIndex, maxIndex] = minMax(shapeIndex().internal()); + + if( !spheres_.indexValid(maxIndex) ) + { + fatalErrorInFunction<< + "the maximum value of shapeIndex is "<< maxIndex << + " which is not valid."<(shapeNames.size()); + + propIds.clear(); + propIds.reserve(numNew); + + diams.clear(); + diams.reserve(numNew); + + m.clear(); + m.reserve(numNew); + + Is.clear(); + Is.reserve(numNew); + + shIndex.clear(); + shIndex.reserve(numNew); + + + for(const auto& name:shapeNames) + { + uint32 indx; + if(spheres_.shapeNameToIndex(name,indx)) + { + shIndex.push_back(indx); + Is.push_back( spheres_.Inertia(indx)); + m.push_back(spheres_.mass(indx)); + diams.push_back(spheres_.boundingDiameter(indx)); + propIds.push_back( spheres_.propertyId(indx)); + } + else + { + fatalErrorInFunction<<"Shape name "<< name << + "does not exist. The list is "<( - objectFile( - sphereShapeFile__, - "", - objectFile::READ_ALWAYS, - objectFile::WRITE_NEVER - ) - ) + dynPointStruct(), + 0u + ), + diameter_ + ( + objectFile( + "diameter", + "", + objectFile::READ_NEVER, + objectFile::WRITE_NEVER), + dynPointStruct(), + 0.00000000001 + ), + mass_ + ( + objectFile( + "mass", + "", + objectFile::READ_NEVER, + objectFile::WRITE_NEVER), + dynPointStruct(), + 0.0000000001 + ), + I_ + ( + objectFile + ( + "I", + "", + objectFile::READ_NEVER, + objectFile::WRITE_NEVER ), - I_( - this->time().emplaceObject( - objectFile( - "I", - "", - objectFile::READ_NEVER, - objectFile::WRITE_ALWAYS - ), - pStruct(), - static_cast(0.0000000001) - ) - ), - rVelocity_( - this->time().emplaceObject( - objectFile( - "rVelocity", - "", - objectFile::READ_IF_PRESENT, - objectFile::WRITE_ALWAYS - ), - pStruct(), - zero3 - ) - ), - rAcceleration_( - this->time().emplaceObject( - objectFile( - "rAcceleration", - "", - objectFile::READ_IF_PRESENT, - objectFile::WRITE_ALWAYS - ), - pStruct(), - zero3 - ) + dynPointStruct(), + static_cast(0.0000000001) + ), + rVelocity_ + ( + objectFile + ( + "rVelocity", + "", + objectFile::READ_IF_PRESENT, + objectFile::WRITE_ALWAYS ), + dynPointStruct(), + zero3 + ), + rAcceleration_ + ( + objectFile( + "rAcceleration", + "", + objectFile::READ_IF_PRESENT, + objectFile::WRITE_ALWAYS + ), + dynPointStruct(), + zero3 + ), accelerationTimer_( "Acceleration", &this->timers() ), intPredictTimer_( "Integration-predict", &this->timers() ), intCorrectTimer_( "Integration-correct", &this->timers() ) - { - - REPORT(1)<<"Creating integration method "<integrationMethod()) - << " for rotational velocity."<("integrationMethod"); + REPORT(1)<<"Creating integration method "<time().integration(), - this->pStruct(), - this->integrationMethod()); + dynPointStruct(), + intMethod, + rVelocity_.field() + ); if( !rVelIntegration_ ) { @@ -307,37 +411,17 @@ pFlow::sphereParticles::sphereParticles( fatalExit; } - if(rVelIntegration_->needSetInitialVals()) - { - - auto [minInd, maxInd] = pStruct().activeRange(); - int32IndexContainer indexHD(minInd, maxInd); - - auto n = indexHD.size(); - auto index = indexHD.indicesHost(); - - realx3Vector rvel(n,RESERVE()); - const auto hrVel = rVelocity_.hostVector(); - - for(auto i=0; isetInitialVals(indexHD, rvel); - - } - + WARNING<<"setFields for rVelIntegration_"<needSetInitialVals()) @@ -350,7 +434,7 @@ bool pFlow::sphereParticles::update(const eventMessage& msg) auto index = indexHD.indicesHost(); realx3Vector rvel(n,RESERVE()); - const auto hrVel = rVelocity_.hostVector(); + const auto hrVel = rVelocity_.hostView(); for(auto i=0; idt(); + dynPointStruct().predict(dt, accelertion()); + rVelIntegration_().predict(dt,rVelocity_, rAcceleration_); + intPredictTimer_.end(); + + return true; +} + +bool pFlow::sphereParticles::iterate() +{ + + particles::iterate(); + accelerationTimer_.start(); + pFlow::sphereParticlesKernels::acceleration( + control().g(), + mass().deviceViewAll(), + contactForce().deviceViewAll(), + I().deviceViewAll(), + contactTorque().deviceViewAll(), + dynPointStruct().activePointsMaskDevice(), + accelertion().deviceViewAll(), + rAcceleration().deviceViewAll() + ); + accelerationTimer_.end(); + + intCorrectTimer_.start(); + + if(!dynPointStruct().correct(dt(), accelertion())) + { + return false; + } + if(!rVelIntegration_().correct( + dt(), + rVelocity_, + rAcceleration_)) + { + return false; + } + + intCorrectTimer_.end(); + + return true; +} + +bool pFlow::sphereParticles::insertParticles +( + const realx3Vector &position, + const wordVector &shapesNames, + const anyList &setVarList +) +{ + anyList newVarList(setVarList); + + realVector mass("mass"); + realVector I("I"); + realVector diameter("diameter"); + uint32Vector propId("propId"); + uint32Vector shapeIdx("shapeIdx"); + + if(!getParticlesInfoFromShape( + shapesNames, + propId, + diameter, + mass, + I, + shapeIdx)) + { + return false; + } + + newVarList.emplaceBack( + mass_.name()+"Vector", + std::move(mass)); + + newVarList.emplaceBack( + I_.name()+"Vector", + std::move(I)); + + newVarList.emplaceBack( + diameter_.name()+"Vector", + std::move(diameter)); + + newVarList.emplaceBack( + propertyId_.name()+"Vector", + std::move(propId)); + + newVarList.emplaceBack( + shapeIndex().name()+"Vector", + std::move(shapeIdx)); + + if(!dynPointStruct().insertPoints(position, newVarList)) + { + return false; + } + + return true; +} + +pFlow::word pFlow::sphereParticles::shapeTypeName()const +{ + return "sphere"; +} + +const pFlow::shape &pFlow::sphereParticles::getShapes() const +{ + return spheres_; +} + +void pFlow::sphereParticles::boundingSphereMinMax +( + real & minDiam, + real& maxDiam +)const +{ + minDiam = spheres_.minBoundingSphere(); + maxDiam = spheres_.maxBoundingSphere(); +} diff --git a/src/Particles/SphereParticles/sphereParticles/sphereParticles.hpp b/src/Particles/SphereParticles/sphereParticles/sphereParticles.hpp index db9ad178..fc0aa82c 100644 --- a/src/Particles/SphereParticles/sphereParticles/sphereParticles.hpp +++ b/src/Particles/SphereParticles/sphereParticles/sphereParticles.hpp @@ -2,188 +2,217 @@ O C enter of O O E ngineering and O O M ultiscale modeling of - OOOOOOO F luid flow + 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 + 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 + 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. -----------------------------------------------------------------------------*/ -/** +/** * @class pFlow::sphereParticles - * - * @brief Class for managing spherical particles - * + * + * @brief Class for managing spherical particles + * * This is a top-level class that contains the essential components for * defining spherical prticles in a DEM simulation. */ #ifndef __sphereParticles_hpp__ -#define __sphereParticles_hpp__ +#define __sphereParticles_hpp__ -#include "systemControl.hpp" -#include "particles.hpp" -#include "sphereShape.hpp" -#include "property.hpp" #include "indexContainer.hpp" - - +#include "particles.hpp" +#include "property.hpp" +#include "sphereShape.hpp" +#include "systemControl.hpp" namespace pFlow { -class sphereParticles -: - public particles +class sphereParticles : public particles { -protected: +public: - /// reference to material properties - const property& property_; + using ShapeType = sphereShape; - /// reference to shapes - sphereShape& shapes_; +private: - /// pointField of inertial of particles - realPointField_D& I_; + /// reference to shapes + ShapeType spheres_; - /// pointField of rotational Velocity of particles on device - realx3PointField_D& rVelocity_; + /// property id on device + uint32PointField_D propertyId_; - /// pointField of rotational acceleration of particles on device - realx3PointField_D& rAcceleration_; + /// diameter / boundig sphere size of particles on device + realPointField_D diameter_; - /// rotational velocity integrator - uniquePtr rVelIntegration_ = nullptr; + /// mass of particles field + realPointField_D mass_; - /// timer for acceleration computations - Timer accelerationTimer_; + /// pointField of inertial of particles + realPointField_D I_; + + /// pointField of rotational Velocity of particles on device + realx3PointField_D rVelocity_; + + /// pointField of rotational acceleration of particles on device + realx3PointField_D rAcceleration_; + + /// rotational velocity integrator + uniquePtr rVelIntegration_ = nullptr; + + /// timer for acceleration computations + Timer accelerationTimer_; /// timer for integration computations (prediction step) - Timer intPredictTimer_; + Timer intPredictTimer_; /// timer for integration computations (correction step) - Timer intCorrectTimer_; + Timer intCorrectTimer_; - bool diameterMassInertiaPropId(const word& shName, real& diam, real& mass, real& I, int8& propIdx); + +private: bool initializeParticles(); + bool getParticlesInfoFromShape( + const wordVector& shapeNames, + uint32Vector& propIds, + realVector& diams, + realVector& m, + realVector& Is, + uint32Vector& shIndex + ); + /*bool initializeParticles(); + bool insertSphereParticles( - const wordVector& names, - const int32IndexContainer& indices, - bool setId = true); + const wordVector& names, + const int32IndexContainer& indices, + bool setId = true); virtual uniquePtr> getFieldObjectList()const override; + */ public: - /// construct from systemControl and property - sphereParticles(systemControl &control, const property& prop); + /// construct from systemControl and property + sphereParticles(systemControl& control, const property& prop); - /// no copy constructor - sphereParticles(const sphereParticles&) = delete; - - /// move constructor - sphereParticles(sphereParticles&&) = default; - - /// no copy-assignement - sphereParticles& operator=(const sphereParticles&) = delete; - - /// move-assignement - sphereParticles& operator=(sphereParticles&&) = default; - - virtual ~sphereParticles()=default; + ~sphereParticles() override = default; /** * Insert new particles in position with specified shapes - * - * This function is involked by inserted object to insert new set of particles - * into the simulation. - * \param position position of new particles + * + * This function is involked by inserted object to insert new set of + * particles into the simulation. \param position position of new particles * \param shape shape of new particles * \param setField initial value of the selected fields for new particles */ - bool insertParticles + /*bool insertParticles ( - const realx3Vector& position, - const wordVector& shapes, - const setFieldList& setField - ) override ; + const realx3Vector& position, + const wordVector& shapes, + const setFieldList& setField + ) override ;*/ - /// const reference to shapes object - const auto& shapes()const + /// const reference to shapes object + const auto& spheres() const { - return shapes_; + return spheres_; } /// const reference to inertia pointField - const auto& I()const + const auto& I() const { return I_; } - /// reference to inertia pointField + /// reference to inertia pointField auto& I() { return I_; } - - const realx3Vector_D rVelocity()const - { + + const auto& rVelocity() const + { return rVelocity_; } - const realVector_D& boundingSphere()const override + auto& rVelocity() { - return this->diameter(); + return rVelocity_; } - word shapeTypeName() const override + bool hearChanges( + real t, + real dt, + uint32 iter, + const message& msg, + const anyList& varList + ) override { - return "sphere"; + notImplementedFunction; + return false; } - void boundingSphereMinMax( - real& minDiam, - real& maxDiam )const override + const uint32PointField_D& propertyId() const override { - shapes_.diameterMinMax(minDiam, maxDiam); + return propertyId_; } - bool update(const eventMessage& msg) override; - - + const realPointField_D& diameter() const override + { + return diameter_; + } + + const realPointField_D& mass() const override + { + return mass_; + } + + /// before iteration step + bool beforeIteration() override; + + /// iterate particles + bool iterate() override; + + bool insertParticles( + const realx3Vector& position, + const wordVector& shapesNames, + const anyList& setVarList + ) override; + realx3PointField_D& rAcceleration() override { return rAcceleration_; } - + const realx3PointField_D& rAcceleration() const override { return rAcceleration_; } - /// before iteration step - bool beforeIteration() override; + const realPointField_D& boundingSphere() const override + { + return diameter(); + } - /// iterate particles - bool iterate() override; + word shapeTypeName() const override; - /// after iteration step - bool afterIteration() override; - + const shape& getShapes() const override; - -}; //sphereParticles + void boundingSphereMinMax(real& minDiam, real& maxDiam) const override; + +}; // sphereParticles } // pFlow diff --git a/src/Particles/SphereParticles/sphereParticles/sphereParticlesKernels.cpp b/src/Particles/SphereParticles/sphereParticles/sphereParticlesKernels.cpp new file mode 100644 index 00000000..5e2def60 --- /dev/null +++ b/src/Particles/SphereParticles/sphereParticles/sphereParticlesKernels.cpp @@ -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. +-----------------------------------------------------------------------------*/ + +#include "sphereParticlesKernels.hpp" + +using policy = Kokkos::RangePolicy< + pFlow::DefaultExecutionSpace, + Kokkos::Schedule, + Kokkos::IndexType>; + +void pFlow::sphereParticlesKernels::addMassDiamInertiaProp +( + deviceViewType1D shapeIndex, + deviceViewType1D mass, + deviceViewType1D diameter, + deviceViewType1D I, + deviceViewType1D propertyId, + pFlagTypeDevice incld, + deviceViewType1D src_mass, + deviceViewType1D src_diameter, + deviceViewType1D src_I, + deviceViewType1D src_propertyId +) +{ + auto aRange = incld.activeRange(); + + Kokkos::parallel_for( + "particles::initInertia", + policy(aRange.start(), aRange.end()), + LAMBDA_HD(uint32 i) + { + if(incld(i)) + { + uint32 index = shapeIndex[i]; + I[i] = src_I[index]; + diameter[i] = src_diameter[index]; + mass[i] = src_mass[index]; + propertyId[i] = src_propertyId[index]; + } + }); + +} + +void pFlow::sphereParticlesKernels::acceleration +( + const realx3& g, + const deviceViewType1D& mass, + const deviceViewType1D& force, + const deviceViewType1D& I, + const deviceViewType1D& torque, + const pFlagTypeDevice& incld, + deviceViewType1D lAcc, + deviceViewType1D rAcc +) +{ + + auto activeRange = incld.activeRange(); + if(incld.isAllActive()) + { + Kokkos::parallel_for( + "pFlow::sphereParticlesKernels::acceleration", + policy(activeRange.start(), activeRange.end()), + LAMBDA_HD(uint32 i){ + lAcc[i] = force[i]/mass[i] + g; + rAcc[i] = torque[i]/I[i]; + }); + } + else + { + Kokkos::parallel_for( + "pFlow::sphereParticlesKernels::acceleration", + policy(activeRange.start(), activeRange.end()), + LAMBDA_HD(uint32 i){ + if(incld(i)) + { + lAcc[i] = force[i]/mass[i] + g; + rAcc[i] = torque[i]/I[i]; + } + }); + + } + + Kokkos::fence(); +} diff --git a/src/Particles/SphereParticles/sphereParticles/sphereParticlesKernels.hpp b/src/Particles/SphereParticles/sphereParticles/sphereParticlesKernels.hpp index 2edeff2b..628b1c49 100644 --- a/src/Particles/SphereParticles/sphereParticles/sphereParticlesKernels.hpp +++ b/src/Particles/SphereParticles/sphereParticles/sphereParticlesKernels.hpp @@ -21,56 +21,36 @@ Licence: #ifndef __sphereParticlesKernels_hpp__ #define __sphereParticlesKernels_hpp__ +#include "types.hpp" +#include "pointFlag.hpp" + namespace pFlow::sphereParticlesKernels { -using rpAcceleration = Kokkos::RangePolicy< - DefaultExecutionSpace, - Kokkos::Schedule, - Kokkos::IndexType - >; - -template -void acceleration( - realx3 g, - deviceViewType1D mass, - deviceViewType1D force, +void addMassDiamInertiaProp( + deviceViewType1D shapeIndex, + deviceViewType1D mass, + deviceViewType1D diameter, deviceViewType1D I, - deviceViewType1D torque, - IncludeFunctionType incld, - deviceViewType1D lAcc, - deviceViewType1D rAcc - ) -{ + deviceViewType1D propertyId, + pFlagTypeDevice incld, + deviceViewType1D src_mass, + deviceViewType1D src_diameter, + deviceViewType1D src_I, + deviceViewType1D src_propertyId +); - auto activeRange = incld.activeRange(); - if(incld.allActive()) - { - Kokkos::parallel_for( - "pFlow::sphereParticlesKernels::acceleration", - rpAcceleration(activeRange.first, activeRange.second), - LAMBDA_HD(int32 i){ - lAcc[i] = force[i]/mass[i] + g; - rAcc[i] = torque[i]/I[i]; - }); - } - else - { - Kokkos::parallel_for( - "pFlow::sphereParticlesKernels::acceleration", - rpAcceleration(activeRange.first, activeRange.second), - LAMBDA_HD(int32 i){ - if(incld(i)) - { - lAcc[i] = force[i]/mass[i] + g; - rAcc[i] = torque[i]/I[i]; - } - }); +void acceleration( + const realx3& g, + const deviceViewType1D& mass, + const deviceViewType1D& force, + const deviceViewType1D& I, + const deviceViewType1D& torque, + const pFlagTypeDevice& incld, + deviceViewType1D lAcc, + deviceViewType1D rAcc +); - } - - Kokkos::fence(); -} } diff --git a/src/Particles/SphereParticles/sphereShape/sphereShape.cpp b/src/Particles/SphereParticles/sphereShape/sphereShape.cpp index 7723f039..fac52d3c 100644 --- a/src/Particles/SphereParticles/sphereShape/sphereShape.cpp +++ b/src/Particles/SphereParticles/sphereShape/sphereShape.cpp @@ -19,186 +19,182 @@ Licence: -----------------------------------------------------------------------------*/ #include "sphereShape.hpp" -#include "dictionary.hpp" -#include "vocabs.hpp" -#include "streams.hpp" -bool pFlow::sphereShape::insertNames -( - const wordVector& names -) +bool pFlow::sphereShape::readFromDictionary3() { - names_.clear(); - uint32 i=0; - for(const auto& nm:names) - { - if(!names_.insertIf(nm, i)) - { - fatalErrorInFunction<< - " repeated name in the list of sphere names: " << names; - return false; - } - i++; - } - names_.rehash(0); - - numShapes_ = names_.size(); - - return true; -} + diameters_ = getVal("diameters"); -bool pFlow::sphereShape::readDictionary -( - const dictionary& dict -) -{ - diameters_ = dict.getVal("diameters"); - materials_ = dict.getVal("materials"); - auto names = dict.getVal("names"); - - if(diameters_.size() != materials_.size() ) + if(diameters_.size() != numShapes() ) { - fatalErrorInFunction<< - " number of elements in diameters and properties are not the same in "<< dict.globalName()< names_; +protected: - size_t numShapes_; - - - bool insertNames(const wordVector& names); - - bool readDictionary(const dictionary& dict); - - bool writeDictionary(dictionary& dict)const; + bool writeToDict(dictionary& dict)const override; public: // - type info - TypeInfoNV("sphereShape"); + TypeInfo("shape"); + sphereShape( + const word& fileName, + repository* owner, + const property& prop); - sphereShape(){} - - sphereShape( - const realVector& diameter, - const wordVector& property, - const wordVector& name - ); - - sphereShape(const sphereShape&) = default; - - sphereShape(sphereShape&&) = default; - - sphereShape& operator=(const sphereShape&) = default; - - sphereShape& operator=(sphereShape&&) = default; - - auto clone()const - { - return makeUnique(*this); - } - - sphereShape* clonePtr()const - { - return new sphereShape(*this); - } - - ~sphereShape() = default; + + ~sphereShape() override = default; //// - Methods - const auto& names()const{ - return names_; - } - const auto& diameters()const{ - return diameters_; - } + real maxBoundingSphere()const override; - const auto& materials()const{ - return materials_; - } + real minBoundingSphere()const override; - const auto diameter(label i)const{ - return diameters_[i]; - } + bool boundingDiameter(uint32 index, real& bDiam)const override; - const auto material(label i)const{ - return materials_[i]; - } + real boundingDiameter(uint32 index)const override; + realVector boundingDiameter()const override; - // name to index - bool nameToIndex(const word& name, uint32& index)const - { - if(auto[iter, found] = names_.findIf(name); found ) - { - index = iter->second; - return true; - } - else - { - index = 0; - return false; - } - } + bool mass(uint32 index, real& m)const override; - uint32 nameToIndex(const word& name)const - { - return names_.at(name); - } + real mass(uint32 index) const override; - bool indexToName(uint32 i, word& name)const - { - for(auto& nm: names_) - { - if(nm.second == i) - { - name = nm.first; - return true; - } - } - name = ""; - return false; - } + realVector mass()const override; - bool shapeToDiameter(wordVector& names, realVector& diams)const; + realVector density() const override; - void diameterMinMax(real& minD, real& maxD)const - { - minD = min(diameters_); - maxD = max(diameters_); - } + bool Inertia(uint32 index, real& I)const override; - //// - IO operatoin + real Inertia(uint32 index)const override; - // - read from stream/file - bool read(iIstream& is); + realVector Inertia()const override; + + bool Inertia_xx(uint32 index, real& Ixx)const override; - // - write to stream/file - bool write(iOstream& os)const; + real Inertial_xx(uint32 index)const override; + + bool Inertia_yy(uint32 index, real& Iyy)const override; - // - read from dictionary - bool read(const dictionary& dict) - { - return readDictionary(dict); - } + real Inertial_yy(uint32 index)const override; - // - write to dictionary - bool write(dictionary& dict)const - { - return writeDictionary(dict); - } + bool Inertia_zz(uint32 index, real& Izz)const override; + real Inertial_zz(uint32 index)const override; }; diff --git a/src/Particles/dynamicPointStructure/dynamicPointStructure.cpp b/src/Particles/dynamicPointStructure/dynamicPointStructure.cpp index 16e5b849..c57475ec 100644 --- a/src/Particles/dynamicPointStructure/dynamicPointStructure.cpp +++ b/src/Particles/dynamicPointStructure/dynamicPointStructure.cpp @@ -19,57 +19,40 @@ Licence: -----------------------------------------------------------------------------*/ #include "dynamicPointStructure.hpp" - +#include "systemControl.hpp" pFlow::dynamicPointStructure::dynamicPointStructure ( - Time& time, - const word& integrationMethod + systemControl& control ) : - time_(time), - integrationMethod_(integrationMethod), - pStruct_( - time_.emplaceObject( - objectFile( - pointStructureFile__, - "", - objectFile::READ_ALWAYS, - objectFile::WRITE_ALWAYS - ) - ) - ), - velocity_( - time_.emplaceObject( - objectFile( - "velocity", - "", - objectFile::READ_ALWAYS, - objectFile::WRITE_ALWAYS - ), - pStruct(), - zero3 - ) - ) - + pointStructure(control), + velocity_ + ( + objectFile( + "velocity", + "", + objectFile::READ_ALWAYS, + objectFile::WRITE_ALWAYS + ), + *this, + zero3 + ), + integrationMethod_ + ( + control.settingsDict().getVal("integrationMethod") + ) { - - this->subscribe(pStruct()); - REPORT(1)<< "Creating integration method "<< - greenText(integrationMethod_)<<" for dynamicPointStructure."<needSetInitialVals()) return; - - - - auto [minInd, maxInd] = pStruct().activeRange(); - int32IndexContainer indexHD(minInd, maxInd); - - auto n = indexHD.size(); - auto index = indexHD.indicesHost(); - - realx3Vector pos(n,RESERVE()); - realx3Vector vel(n,RESERVE()); - const auto hVel = velocity().hostVector(); - const auto hPos = pStruct().pointPosition().hostVector(); - - for(auto i=0; isetInitialVals(indexHD, pos); - - REPORT(2)<< "Initializing the required vectors for velocity integratoin\n "<setInitialVals(indexHD, vel); } -bool pFlow::dynamicPointStructure::predict -( - real dt, - realx3PointField_D& acceleration -) -{ - auto& pos = pStruct().pointPosition(); - if(!integrationPos_().predict(dt, pos.VectorField(), velocity_.VectorField() ))return false; - if(!integrationVel_().predict(dt, velocity_.VectorField(), acceleration.VectorField()))return false; +bool pFlow::dynamicPointStructure::beforeIteration() +{ + return pointStructure::beforeIteration(); + /*real dt = this->dt(); + + auto& acc = time().lookupObject("acceleration"); + return predict(dt, acc);*/ +} + +bool pFlow::dynamicPointStructure::iterate() +{ + return pointStructure::iterate(); + + /*real dt = this->dt(); + + auto& acc = time().lookupObject("acceleration"); + return correct(dt, acc);*/ +} + +bool pFlow::dynamicPointStructure::predict( + real dt, + realx3PointField_D &acceleration) +{ + + if(!integrationPos_().predict(dt, pointPosition(), velocity_ ))return false; + if(!integrationVel_().predict(dt, velocity_, acceleration))return false; return true; } @@ -137,82 +115,11 @@ bool pFlow::dynamicPointStructure::correct realx3PointField_D& acceleration ) { - auto& pos = pStruct().pointPosition(); + //auto& pos = pStruct().pointPosition(); - if(!integrationPos_().correct(dt, pos.VectorField(), velocity_.VectorField() ))return false; + if(!integrationPos_().correct(dt, pointPosition(), velocity_) )return false; - if(!integrationVel_().correct(dt, velocity_.VectorField(), acceleration.VectorField()))return false; + if(!integrationVel_().correct(dt, velocity_, acceleration))return false; return true; } - -/*FUNCTION_H -pFlow::uniquePtr pFlow::dynamicPointStructure::insertPoints -( - const realx3Vector& pos, - const List& exclusionList -) -{ - auto newIndicesPtr = pointStructure::insertPoints(pos, exclusionList); - - // no new point is inserted - if( !newIndicesPtr ) return newIndicesPtr; - - if(!integrationPos_().needSetInitialVals()) return newIndicesPtr; - - auto hVel = velocity_.hostVector(); - auto n = newIndicesPtr().size(); - auto index = newIndicesPtr().indicesHost(); - - realx3Vector velVec(n, RESERVE()); - for(auto i=0; isetInitialVals(newIndicesPtr(), pos ); - integrationVel_->setInitialVals(newIndicesPtr(), velVec ); - - return newIndicesPtr; - -}*/ - - -bool pFlow::dynamicPointStructure::update( - const eventMessage& msg) -{ - if( msg.isInsert()) - { - - if(!integrationPos_->needSetInitialVals())return true; - - const auto indexHD = pStruct().insertedPointIndex(); - - - auto n = indexHD.size(); - - if(n==0) return true; - - auto index = indexHD.indicesHost(); - - realx3Vector pos(n,RESERVE()); - realx3Vector vel(n,RESERVE()); - const auto hVel = velocity().hostVector(); - const auto hPos = pStruct().pointPosition().hostVector(); - - for(auto i=0; isetInitialVals(indexHD, pos); - - integrationVel_->setInitialVals(indexHD, vel); - - } - - return true; -} \ No newline at end of file diff --git a/src/Particles/dynamicPointStructure/dynamicPointStructure.hpp b/src/Particles/dynamicPointStructure/dynamicPointStructure.hpp index 843a3c46..0e6a9fcd 100644 --- a/src/Particles/dynamicPointStructure/dynamicPointStructure.hpp +++ b/src/Particles/dynamicPointStructure/dynamicPointStructure.hpp @@ -30,98 +30,69 @@ Licence: namespace pFlow { +class systemControl; + class dynamicPointStructure : - //public pointStructure -public eventObserver + public pointStructure { -protected: +private: - Time& time_; + realx3PointField_D velocity_; - word integrationMethod_; + uniquePtr integrationPos_ = nullptr; - pointStructure& pStruct_; + uniquePtr integrationVel_ = nullptr; - realx3PointField_D& velocity_; - - uniquePtr integrationPos_; - - uniquePtr integrationVel_; + /// @brief integration method for velocity and position + word integrationMethod_; public: TypeInfo("dynamicPointStructure"); - dynamicPointStructure(Time& time, const word& integrationMethod); - - dynamicPointStructure(const dynamicPointStructure& ps) = default; + explicit dynamicPointStructure(systemControl& control); + dynamicPointStructure(const dynamicPointStructure& ps) = delete; - // - no move construct + // - no move construct dynamicPointStructure(dynamicPointStructure&&) = delete; - // - copy assignment - // - // should be changed, may causs undefined behavior - ////////////////////////////////////////////////////////////// - dynamicPointStructure& operator=(const dynamicPointStructure&) = default; + /// + dynamicPointStructure& operator=(const dynamicPointStructure&) = delete; // - no move assignment dynamicPointStructure& operator=(dynamicPointStructure&&) = delete; // - destructor - virtual ~dynamicPointStructure() = default; + ~dynamicPointStructure() override = default; - inline pointStructure& pStruct() - { - return pStruct_; - } - - inline const pointStructure& pStruct() const - { - return pStruct_; - } - - inline const realx3PointField_D& velocity()const + inline + const realx3PointField_D& velocity()const { return velocity_; } - inline auto velocityHostAll() + inline + realx3PointField_D& velocity() { - return velocity_.hostVectorAll(); + return velocity_; } - inline auto pointPositionHostAll() - { - return pStruct_.pointPositionHostAll(); - } - - auto markDeleteOutOfBox(const box& domain) - { - return pStruct_.markDeleteOutOfBox(domain); - } + /// In the time loop before iterate + bool beforeIteration() override; + /// @brief This is called in time loop. Perform the main calculations + /// when the component should evolve along time. + bool iterate() override; + + /// prediction step (if any), is called in beforeIteration bool predict(real dt, realx3PointField_D& acceleration); + /// correction step, is called in iterate bool correct(real dt, realx3PointField_D& acceleration); - - // - update data structure by inserting/setting new points - // Notifies all the fields in the registered list of data structure - // and exclude the fields that re in the exclusionList - // retrun nullptr if it fails - /*FUNCTION_H - virtual uniquePtr insertPoints( - const realx3Vector& pos, - const List& exclusionList={nullptr} - )override;*/ - - bool update(const eventMessage& msg) override; - - }; } diff --git a/src/Particles/particles/particleIdHandler/particleIdHandler.cpp b/src/Particles/particles/particleIdHandler/particleIdHandler.cpp new file mode 100644 index 00000000..5288e156 --- /dev/null +++ b/src/Particles/particles/particleIdHandler/particleIdHandler.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 "particleIdHandler.hpp" + +pFlow::particleIdHandler::particleIdHandler(pointStructure& pStruct) +: + uint32PointField_D + ( + objectFile + ( + "id", + "", + objectFile::READ_IF_PRESENT, + objectFile::WRITE_ALWAYS + ), + pStruct, + static_cast(-1), + static_cast(-1) + ) +{ + +} + +bool +pFlow::particleIdHandler::hearChanges( + real t, + real dt, + uint32 iter, + const message& msg, + const anyList& varList +) +{ + if(msg.equivalentTo(message::ITEM_INSERT)) + { + const word eventName = message::eventName(message::ITEM_INSERT); + + const auto& indices = varList.getObject( + eventName); + + uint32 numNew = indices.size(); + if(numNew == 0u)return true; + + auto idRange = getIdRange(numNew); + uint32Vector newId("newId",numNew,numNew,RESERVE()); + fillSequence(newId, idRange.first); + + return this->field().insertSetElement(indices, newId); + } + else + { + return uint32PointField_D::hearChanges(t,dt,iter, msg,varList); + } +} + +pFlow::uniquePtr +pFlow::particleIdHandler::create(pointStructure& pStruct) +{ + word idHType = angleBracketsNames( + "particleIdHandler", + pFlowProcessors().localRunTypeName()); + + + if( pointStructurevCtorSelector_.search(idHType) ) + { + REPORT(1)<<"Creating particle id handler "<< + Green_Text(idHType)< getIdRange(uint32 nNewParticles)=0; + + virtual + bool initialIdCheck()=0; + + // heat change for possible insertion of particles + // overrdie from internalField + bool hearChanges + ( + real t, + real dt, + uint32 iter, + const message& msg, + const anyList& varList + ) override; + + static + uniquePtr create( + pointStructure& pStruct); + +}; + +} + +#endif diff --git a/src/Particles/particles/particles.cpp b/src/Particles/particles/particles.cpp index d5c3bb45..b6a389ab 100644 --- a/src/Particles/particles/particles.cpp +++ b/src/Particles/particles/particles.cpp @@ -2,201 +2,111 @@ O C enter of O O E ngineering and O O M ultiscale modeling of - OOOOOOO F luid flow + 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 + 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 + 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 "particles.hpp" - -pFlow::particles::particles -( - systemControl& control, - const word& integrationMethod -) -: - demParticles(control), - time_(control.time()), - integrationMethod_(integrationMethod), - /*dynPointStruct_( - time_.emplaceObject( - objectFile( - pointStructureFile__, - "", - objectFile::READ_ALWAYS, - objectFile::WRITE_ALWAYS - ), - control.time(), - integrationMethod - ) - ),*/ - dynPointStruct_( - control.time(), - integrationMethod), - shapeName_( - control.time().emplaceObject( - objectFile( - "shapeName", - "", - objectFile::READ_ALWAYS, - objectFile::WRITE_ALWAYS, - false - ), - pStruct(), - word("NO_NAME_SHAPE") - ) - ), - id_( - control.time().emplaceObject( - objectFile( - "id", - "", - objectFile::READ_IF_PRESENT, - objectFile::WRITE_ALWAYS - ), - pStruct(), - static_cast(-1) - ) - ), - propertyId_( - control.time().emplaceObject( - objectFile( - "propertyId", - "", - objectFile::READ_NEVER, - objectFile::WRITE_NEVER - ), - pStruct(), - static_cast(0) - ) - ), - diameter_( - control.time().emplaceObject( - objectFile( - "diameter", - "", - objectFile::READ_NEVER, - objectFile::WRITE_ALWAYS - ), - pStruct(), - static_cast(0.00000000001) - ) - ), - mass_( - control.time().emplaceObject( - objectFile( - "mass", - "", - objectFile::READ_NEVER, - objectFile::WRITE_ALWAYS - ), - pStruct(), - static_cast(0.0000000001) - ) - ), - accelertion_( - control.time().emplaceObject( - objectFile( - "accelertion", - "", - objectFile::READ_IF_PRESENT, - objectFile::WRITE_ALWAYS - ), - pStruct(), - zero3 - ) - ), - contactForce_( - control.time().emplaceObject( - objectFile( - "contactForce", - "", - objectFile::READ_IF_PRESENT, - objectFile::WRITE_ALWAYS - ), - pStruct(), - zero3 - ) - ), - contactTorque_( - control.time().emplaceObject( - objectFile( - "contactTorque", - "", - objectFile::READ_IF_PRESENT, - objectFile::WRITE_ALWAYS - ), - pStruct(), - zero3 - ) - ), - idHandler_(id_) +pFlow::particles::particles(systemControl& control) + : observer(defaultMessage_), + demComponent("particles", control), + dynPointStruct_(control), + /*id_( + objectFile( + "id", + "", + objectFile::READ_IF_PRESENT, + objectFile::WRITE_ALWAYS + ), + dynPointStruct_, + static_cast(-1), + static_cast(-1) + ),*/ + shapeIndex_( + objectFile( + "shapeIndex", + "", + objectFile::READ_ALWAYS, + objectFile::WRITE_ALWAYS + ), + dynPointStruct_, + 0 + ), + accelertion_( + objectFile( + "accelertion", + "", + objectFile::READ_IF_PRESENT, + objectFile::WRITE_ALWAYS + ), + dynPointStruct_, + zero3 + ), + contactForce_( + objectFile( + "contactForce", + "", + objectFile::READ_IF_PRESENT, + objectFile::WRITE_ALWAYS + ), + dynPointStruct_, + zero3 + ), + contactTorque_( + objectFile( + "contactTorque", + "", + objectFile::READ_IF_PRESENT, + objectFile::WRITE_ALWAYS + ), + dynPointStruct_, + zero3 + ), + idHandler_(particleIdHandler::create(dynPointStruct_)) { - - this->subscribe(pStruct()); + this->addToSubscriber(dynPointStruct_); + idHandler_().initialIdCheck(); } -bool pFlow::particles::beforeIteration() +bool +pFlow::particles::beforeIteration() { - auto domain = this->control().domain(); + zeroForce(); + zeroTorque(); - auto numMarked = dynPointStruct_.markDeleteOutOfBox(domain); - - if(time_.sortTime()) - { - real min_dx, max_dx; - boundingSphereMinMax(min_dx, max_dx); - Timer t; - t.start(); - REPORT(0)<<"Performing morton sorting on particles ...."<zeroForce(); - this->zeroTorque(); - - return true; + return dynPointStruct_.beforeIteration(); } -pFlow::uniquePtr> -pFlow::particles::getFieldObjectList()const +bool +pFlow::particles::iterate() { - auto objListPtr = makeUnique>(); - objListPtr().push_back( - static_cast(&id_) ); - - objListPtr().push_back( - static_cast(&propertyId_) ); - - objListPtr().push_back( - static_cast(&diameter_) ); - - objListPtr().push_back( - static_cast(&mass_) ); - - objListPtr().push_back( - static_cast(&shapeName_) ); - - return objListPtr; + return dynPointStruct_.iterate(); +} + +bool +pFlow::particles::afterIteration() +{ + return dynPointStruct_.afterIteration(); +} + +void +pFlow::particles::boundingSphereMinMax(real& minDiam, real& maxDiam) const +{ + auto& shp = getShapes(); + + minDiam = shp.minBoundingSphere(); + maxDiam = shp.maxBoundingSphere(); } diff --git a/src/Particles/particles/particles.hpp b/src/Particles/particles/particles.hpp index 7b207c50..a06c5c3c 100644 --- a/src/Particles/particles/particles.hpp +++ b/src/Particles/particles/particles.hpp @@ -1,79 +1,63 @@ -/*------------------------------- phasicFlow --------------------------------- - O C enter of - O O E ngineering and - O O M ultiscale modeling of - OOOOOOO F luid flow +/*------------------------------- 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. + 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 __particles_hpp__ #define __particles_hpp__ +#include "demComponent.hpp" #include "dynamicPointStructure.hpp" #include "particleIdHandler.hpp" -#include "demParticles.hpp" +#include "shape.hpp" + namespace pFlow { -class setFieldList; - class particles -: - public eventObserver, - public demParticles + : public observer + , public demComponent { +private: + + /// dynamic point structure for particles center mass + dynamicPointStructure dynPointStruct_; + + /// shape index of each particle + uint32PointField_D shapeIndex_; + + /// acceleration on device + realx3PointField_D accelertion_; + + /// contact force field + realx3PointField_D contactForce_; + + /// contact torque field + realx3PointField_D contactTorque_; + + /// handling new ids for new particles + uniquePtr idHandler_ = nullptr; + + /// messages for this objects + static inline const message defaultMessage_{ message::DEFAULT }; + protected: - - // owner repository - Time& time_; - - const word integrationMethod_; - - // dynamic point structure for particles - dynamicPointStructure dynPointStruct_; - - // - name of shapes - this is managed by particles - wordPointField& shapeName_; - - // id of particles on host - int32PointField_HD& id_; - - // property id on device - int8PointField_D& propertyId_; - - // diameter / boundig sphere size of particles on device - realPointField_D& diameter_; - - // mass on device - realPointField_D& mass_; - - // - acceleration on device - realx3PointField_D& accelertion_; - - - realx3PointField_D& contactForce_; - - - realx3PointField_D& contactTorque_; - - - // - object handling particle id - particleIdHandler idHandler_; - - virtual uniquePtr> getFieldObjectList()const; void zeroForce() { @@ -85,193 +69,150 @@ protected: contactTorque_.fill(zero3); } -public: - - // type info - TypeInfo("particles"); - - particles(systemControl& control, const word& integrationMethod); - - inline const auto& time()const { - return time_; - } - - inline auto& time() { - return time_; - } - - inline auto integrationMethod()const - { - return integrationMethod_; - } - - inline const auto& dynPointStruct()const - { - return dynPointStruct_; - } - inline auto& dynPointStruct() { return dynPointStruct_; } - inline const auto& pStruct()const{ - return dynPointStruct_.pStruct(); - } - - inline auto& pStruct(){ - return dynPointStruct_.pStruct(); - } - - inline auto size()const{ - return pStruct().size(); - } - - inline auto capacity() const{ - return pStruct().capacity(); - } - - inline auto activePointsMaskD()const{ - return pStruct().activePointsMaskD(); - } - - inline auto numActive()const + inline auto& pointPosition() { - return pStruct().numActive(); + return dynPointStruct_.pointPosition(); + } + + inline auto& idHandler() + { + return idHandler_(); } - inline bool allActive()const{ - return pStruct().allActive(); - } - - inline auto activeRange()const{ - return pStruct().activeRange(); - } - - inline auto activePointsMaskH()const{ - return pStruct().activePointsMaskH(); - } - - inline const auto& pointPosition()const{ - return pStruct().pointPosition(); - } - - inline const auto& position()const + inline auto& shapeIndex() { - return pStruct().pointPosition(); + return shapeIndex_; } - inline const auto& pointVelocity()const{ - return dynPointStruct().velocity(); +public: + + // type info + TypeInfo("particles"); + + explicit particles(systemControl& control); + + inline const auto& dynPointStruct() const + { + return dynPointStruct_; } - inline const auto& velocity()const{ - return dynPointStruct().velocity(); + inline const pointStructure& pStruct() const + { + return dynPointStruct_; } - inline const auto& id()const{ - return id_; + inline const auto& simDomain() const + { + return dynPointStruct_.simDomain(); } - inline auto& id(){ - return id_; + inline const auto& thisDomain() const + { + return dynPointStruct_.thisDomain(); } - inline const auto& diameter()const{ - return diameter_; + inline const auto& extendedDomain() const + { + return dynPointStruct_.extendedDomain(); } - inline auto& diameter(){ - return diameter_; + inline auto size() const + { + return dynPointStruct_.size(); } - inline const auto& mass()const{ - return mass_; + inline auto capacity() const + { + return dynPointStruct_.capacity(); } - inline auto& mass() { - return mass_; + inline auto numActive() const + { + return dynPointStruct_.numActive(); } - inline const auto& accelertion()const{ + inline bool isAllActive() const + { + return dynPointStruct_.isAllActive(); + } + + inline const auto& pointPosition() const + { + return dynPointStruct_.pointPosition(); + } + + inline const auto& velocity() const + { + return dynPointStruct_.velocity(); + } + + inline const auto& accelertion() const + { return accelertion_; } - inline auto& accelertion(){ + inline auto& accelertion() + { return accelertion_; } - inline - realx3PointField_D& contactForce() + inline auto& contactForce() { return contactForce_; } - inline - const realx3PointField_D& contactForce() const + inline const auto& contactForce() const { return contactForce_; } - inline - realx3PointField_D& contactTorque() + inline auto& contactTorque() { return contactTorque_; } - inline - const realx3PointField_D& contactTorque() const + inline const auto& contactTorque() const { return contactTorque_; } - inline const auto& propertyId()const{ - return propertyId_; - } + bool beforeIteration() override; - inline auto& propertyId(){ - return propertyId_; - } + bool iterate() override; - inline const auto& shapeName()const{ - return shapeName_; - } + bool afterIteration() override; - inline auto& shapName(){ - return shapeName_; - } + virtual bool insertParticles( + const realx3Vector& position, + const wordVector& shapesNames, + const anyList& setVarList + ) = 0; - bool beforeIteration() override; + virtual const uint32PointField_D& propertyId() const = 0; - virtual - bool insertParticles - ( - const realx3Vector& position, - const wordVector& shapes, - const setFieldList& setField - ) = 0; + virtual const realPointField_D& diameter() const = 0; - + virtual const realPointField_D& mass() const = 0; - virtual - realx3PointField_D& rAcceleration() = 0; + virtual realx3PointField_D& rAcceleration() = 0; - virtual - const realx3PointField_D& rAcceleration() const = 0; + virtual const realx3PointField_D& rAcceleration() const = 0; - virtual - const realVector_D& boundingSphere()const = 0; + virtual const realPointField_D& boundingSphere() const = 0; - virtual - word shapeTypeName()const = 0; + virtual word shapeTypeName() const = 0; - virtual - void boundingSphereMinMax(real & minDiam, real& maxDiam)const = 0; + virtual const shape& getShapes() const = 0; - + virtual void boundingSphereMinMax(real& minDiam, real& maxDiam) const = 0; }; // particles -} // pFlow +} // namespace pFlow #endif //__particles_hpp__ diff --git a/src/Particles/particles/regularParticleIdHandler/regularParticleIdHandler.cpp b/src/Particles/particles/regularParticleIdHandler/regularParticleIdHandler.cpp new file mode 100644 index 00000000..401bc281 --- /dev/null +++ b/src/Particles/particles/regularParticleIdHandler/regularParticleIdHandler.cpp @@ -0,0 +1,50 @@ +#include "regularParticleIdHandler.hpp" + + + +pFlow::regularParticleIdHandler::regularParticleIdHandler +( + pointStructure& pStruct +) +: + particleIdHandler(pStruct) +{ +} + +pFlow::Pair + pFlow::regularParticleIdHandler::getIdRange(uint32 nNewParticles) +{ + uint32 startId; + if(maxId_==-1) + { + startId = 0; + } + else + { + startId = maxId_+1; + } + uint32 endId = startId+nNewParticles-1; + maxId_ = endId; + return {startId, endId}; +} + +bool pFlow::regularParticleIdHandler::initialIdCheck() +{ + /// empty point structure / no particles in simulation + if( pStruct().empty() ) return true; + + uint32 maxId = max( *this ); + + /// particles should get ids from 0 to size-1 + if(maxId == -1) + { + fillSequence(*this,0u); + maxId_ = size()-1; + } + else + { + maxId_ = maxId; + } + + return true; +} diff --git a/src/Particles/particles/regularParticleIdHandler/regularParticleIdHandler.hpp b/src/Particles/particles/regularParticleIdHandler/regularParticleIdHandler.hpp new file mode 100644 index 00000000..4d40261f --- /dev/null +++ b/src/Particles/particles/regularParticleIdHandler/regularParticleIdHandler.hpp @@ -0,0 +1,60 @@ +/*------------------------------- 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 __regularParticleIdHandler_hpp__ +#define __regularParticleIdHandler_hpp__ + +#include "particleIdHandler.hpp" + +namespace pFlow +{ + +class regularParticleIdHandler +: + public particleIdHandler +{ +private: + + uint32 maxId_ = -1; + +public: + + ClassInfo("particleIdHandler"); + + explicit regularParticleIdHandler(pointStructure& pStruct); + + ~regularParticleIdHandler()override = default; + + add_vCtor + ( + particleIdHandler, + regularParticleIdHandler, + pointStructure + ); + + Pair getIdRange(uint32 nNewParticles)override; + + bool initialIdCheck()override; + +}; + +} + + +#endif //__regularParticleIdHandler_hpp__ \ No newline at end of file diff --git a/src/Particles/particles/shape/baseShapeNames.cpp b/src/Particles/particles/shape/baseShapeNames.cpp new file mode 100644 index 00000000..eaef39cb --- /dev/null +++ b/src/Particles/particles/shape/baseShapeNames.cpp @@ -0,0 +1,122 @@ +/*------------------------------- 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 "baseShapeNames.hpp" + +bool pFlow::baseShapeNames::createHashNames() +{ + hashNames_.clear(); + hashes_.clear(); + + std::hash hasher; + + uint32 i=0; + for(const auto& nm:shapeNames_) + { + if(!hashNames_.insertIf(nm, i)) + { + fatalErrorInFunction<< + " repeated name in the list of shape names: " << shapeNames_; + return false; + } + hashes_.push_back(hasher(nm)); + i++; + } + hashNames_.rehash(0); + + return true; +} + + +bool pFlow::baseShapeNames::readFromDictionary1() +{ + + shapeNames_ = getVal("names"); + numShapes_ = shapeNames_.size(); + + return true; +} + + +pFlow::baseShapeNames::baseShapeNames +( + const word &fileName, + repository *owner +) +: + fileDictionary + ( + objectFile + ( + fileName, + "", + objectFile::READ_ALWAYS, + objectFile::WRITE_ALWAYS + ), + owner + ) +{ + + if( !readFromDictionary1() ) + { + fatalErrorInFunction; + fatalExit; + } + + if( !createHashNames()) + { + fatalErrorInFunction; + fatalExit; + } + +} + + +bool pFlow::baseShapeNames::writeToDict(dictionary &dict)const +{ + + if( !dict.add("names", shapeNames_) ) + { + fatalErrorInFunction<< + " Error in writing names to dictionary "<< dict.globalName()< hashNames_; + + /// list of shape names + wordVector shapeNames_{"shapeNames"}; + + /// hash for names + Vector hashes_{"hashes"}; + + bool createHashNames(); + + bool readFromDictionary1(); + + using hasher = typename wordHashMap::hasher; + +protected: + + virtual + bool writeToDict(dictionary& dict)const; + +public: + + TypeInfo("baseShapeNames"); + + baseShapeNames( + const word& fileName, + repository* owner); + + ~baseShapeNames() override=default; + + + inline + const wordVector& shapeNames()const + { + return shapeNames_; + } + + inline + wordList shapeNameList()const + { + wordList wl; + wl.insert(wl.begin(), shapeNames_.begin(), shapeNames_.end()); + return wl; + } + + inline + const auto& hashes()const + { + return hashes_; + } + + inline + size_t numShapes()const + { + return numShapes_; + } + + // name to index + inline + bool shapeNameToIndex(const word& name, uint32& index)const + { + if(auto[iter, found] = hashNames_.findIf(name); found ) + { + index = iter->second; + return true; + } + else + { + index = 0; + return false; + } + } + + inline + bool indexToShapeName(uint32 i, word& name)const + { + if( i < numShapes_) + { + name = shapeNames_[i]; + return true; + } + return false; + } + + inline bool hashToIndex(const size_t& hs, uint32& idx) + { + for(auto i=0; i("materials"); + + if(materialNames_.size() != numShapes() ) + { + fatalErrorInFunction<< + " number of elements in materials and names are not the same in "<< globalName()<(propId) < property_.numMaterials(); + } + + + inline + bool indexToDensity(uint32 index, real& rho)const + { + if(indexValid(index)) + return property_.density(shapePropertyIds_[index], rho); + return false; + } + + inline + real indexToDensity(uint32 index)const + { + if(indexValid(index)) + { + return property_.density(shapePropertyIds_[index]); + } + + fatalExit; + return 0.0; + } + + inline + uint32 propertyId(uint32 index)const + { + if(indexValid(index)) + { + return shapePropertyIds_[index]; + } + fatalExit; + return 0.0; + } + + virtual + real maxBoundingSphere()const = 0; + + virtual + real minBoundingSphere()const = 0; + + virtual + bool boundingDiameter(uint32 index, real& bDiam)const =0; + + virtual + real boundingDiameter(uint32 index)const = 0; + + virtual + realVector boundingDiameter()const = 0; + + virtual + bool mass(uint32 index, real& m)const = 0; + + virtual + real mass(uint32 index) const =0; + + virtual + realVector mass()const =0; + + virtual + realVector density()const =0; + + virtual + bool Inertia(uint32 index, real& I)const = 0; + + virtual + real Inertia(uint32 index)const = 0; + + virtual + realVector Inertia()const=0; + + virtual + bool Inertia_xx(uint32 index, real& Ixx)const = 0; + + virtual + real Inertial_xx(uint32 index)const =0; + + virtual + bool Inertia_yy(uint32 index, real& Iyy)const = 0; + + virtual + real Inertial_yy(uint32 index)const = 0; + + virtual + bool Inertia_zz(uint32 index, real& Izz)const = 0; + + virtual + real Inertial_zz(uint32 index)const = 0; + +}; + +} + +#endif //__shape_hpp__ \ No newline at end of file diff --git a/src/Property/property.cpp b/src/Property/property.cpp index b2745e10..d6af1f47 100644 --- a/src/Property/property.cpp +++ b/src/Property/property.cpp @@ -18,55 +18,42 @@ Licence: -----------------------------------------------------------------------------*/ - #include "property.hpp" #include "dictionary.hpp" -bool pFlow::property::readDictionary -( - const dictionary& dict -) +bool pFlow::property::readDictionary() { - materials_ = dict.getVal("materials"); + materials_ = getVal("materials"); - densities_ = dict.getVal("densities"); + densities_ = getVal("densities"); if(materials_.size() != densities_.size() ) { fatalErrorInFunction<< " number of elements in material ("<(materials_.size()); return true; } pFlow::property::property ( + const word& fileName, const wordVector& materials, - const realVector& densities + const realVector& densities, + repository* owner ) : + fileDictionary + ( + objectFile + ( + fileName, + "", + objectFile::READ_NEVER, + objectFile::WRITE_NEVER + ), + owner + ), materials_(materials), densities_(densities) { + + if(!writeDictionary()) + { + fatalExit; + } + if(!makeNameIndex()) { fatalErrorInFunction<< - " error in the input parameters of constructor. \n"; + "error in the input parameters of constructor. \n"; fatalExit; } } pFlow::property::property ( -const fileSystem& file + const word& fileName, + repository* owner ) : - dict_ + fileDictionary ( - makeUnique - ("property", true) - ) -{ - iFstream dictStream(file); - - if(!dict_().read(dictStream)) - { - ioErrorInFile(dictStream.name(), dictStream.lineNumber()); - fatalExit; - } - - if(!readDictionary(dict_())) - { - fatalExit; - } - -} - -pFlow::property::property -( - const dictionary& dict -) -: - dict_ - ( - makeUnique(dict) + objectFile + ( + fileName, + "", + objectFile::READ_ALWAYS, + objectFile::WRITE_NEVER + ), + owner ) { - if(!readDictionary(dict_())) + if(!readDictionary()) { fatalExit; } + + if(!makeNameIndex()) + { + fatalErrorInFunction<< + "error in dictionary "<< globalName()< dict_ = nullptr; - /// list of name of materials wordVector materials_; @@ -55,6 +51,7 @@ protected: /// rapid mapping from name to index wordHashMap nameIndex_; + /// number of materials uint32 numMaterials_ = 0; @@ -62,10 +59,10 @@ protected: // - protected member functions /// read from dict - bool readDictionary(const dictionary& dict); + bool readDictionary(); /// write to dict - bool writeDictionary(dictionary& dict)const; + bool writeDictionary(); /// creates a mapp bool makeNameIndex(); @@ -73,22 +70,24 @@ protected: public: /// Type info - TypeInfoNV("property"); + TypeInfo("property"); - // - Constructors - /// Emptry constructor, used for reading from a file - property(){} + explicit + property( + const word& fileName, + repository* owner=nullptr); - /// Constructe from materials and densities - property(const wordVector& materials, const realVector& densities); - - /// Construct from file - property(const fileSystem& file); - - /// Construct from dictionary dict - property(const dictionary& dict); + property( + const word& fileName, + const fileSystem& dir + ); + + property(const word& fileName, + const wordVector& materials, + const realVector& densities, + repository* owner=nullptr); /// Default copy property(const property& ) = default; @@ -103,17 +102,11 @@ public: property& operator= (property&&) = default; /// Default destructor - ~property() = default; + ~property() override = default; // - Methods - /// Return dictionary - inline const auto& dict()const - { - return dict_(); - } - /// Return number of materials inline auto numMaterials()const { @@ -189,21 +182,9 @@ public: return false; } } + + - //// - IO operatoins - - /// Read from dictionary - bool read(const dictionary& dict) - { - return readDictionary(dict); - } - - /// Write to dictionary - bool write(dictionary& dict)const - { - return writeDictionary(dict); - } - }; } diff --git a/src/phasicFlow/CMakeLists.txt b/src/phasicFlow/CMakeLists.txt index 805a55d0..58117785 100644 --- a/src/phasicFlow/CMakeLists.txt +++ b/src/phasicFlow/CMakeLists.txt @@ -5,6 +5,7 @@ types/basicTypes/Logical.cpp types/types.cpp globals/error.cpp +globals/globalSettings.cpp processors/processors.cpp processors/localProcessors.cpp @@ -34,18 +35,6 @@ dictionary/entry/iEntry.cpp dictionary/entry/dataEntry.cpp dictionary/twoPartEntry/twoPartEntry.cpp -containers/Vector/Vectors.cpp -containers/VectorHD/VectorSingles.cpp -containers/Field/Fields.cpp -containers/List/anyList/anyList.cpp -containers/pointField/pointFields.cpp - -#setFieldList/setFieldList.cpp -#setFieldList/setFieldEntry.cpp - -Timer/Timer.cpp -Timer/Timers.cpp - repository/IOobject/objectFile.cpp repository/IOobject/IOfileHeader.cpp repository/IOobject/IOobject.cpp @@ -57,26 +46,64 @@ repository/Time/baseTimeControl.cpp repository/systemControl/systemControl.cpp repository/systemControl/dynamicLinkLibs.cpp +commandLine/commandLine.cpp + eventManagement/subscriber.cpp eventManagement/observer.cpp demComponent/demComponent.cpp +Timer/Timer.cpp +Timer/Timers.cpp + + +containers/Vector/Vectors.cpp +containers/VectorHD/VectorSingles.cpp +containers/Field/Fields.cpp +containers/symArrayHD/symArrays.cpp +containers/List/anyList/anyList.cpp + +structuredData/zAxis/zAxis.cpp structuredData/box/box.cpp +structuredData/sphere/sphere.cpp +structuredData/cylinder/cylinder.cpp +structuredData/peakableRegion/geometricRegion/geometricRegions.cpp +structuredData/peakableRegion/PeakableRegion/PeakableRegions.cpp +structuredData/peakableRegion/peakableRegion/peakableRegion.cpp + +structuredData/pointStructure/internalPoints/internalPointsKernels.cpp +structuredData/pointStructure/internalPoints/internalPoints.cpp + structuredData/line/line.cpp structuredData/infinitePlane/infinitePlane.cpp structuredData/plane/plane.cpp structuredData/domain/domain.cpp structuredData/domain/simulationDomain.cpp structuredData/domain/regularSimulationDomain.cpp -structuredData/pointStructure/internalPoints.cpp -structuredData/pointStructure/pointStructure.cpp structuredData/boundaries/boundaryBase/boundaryBase.cpp +structuredData/boundaries/boundaryBase/boundaryBaseKernels.cpp structuredData/boundaries/boundaryExit/boundaryExit.cpp -structuredData/pointStructure/boundaryList.cpp +structuredData/boundaries/boundaryNone/boundaryNone.cpp +structuredData/boundaries/boundaryPeriodic/boundaryPeriodic.cpp +structuredData/boundaries/boundaryReflective/boundaryReflective.cpp +structuredData/boundaries/boundaryList.cpp +structuredData/pointStructure/pointStructure/pointStructure.cpp +structuredData/pointStructure/selectors/pStructSelector/pStructSelector.cpp +structuredData/pointStructure/selectors/selectorStridedRange/selectorStridedRange.cpp +structuredData/pointStructure/selectors/selectorRandomPoints/selectorRandomPoints.cpp +structuredData/pointStructure/selectors/selectBox/selectBox.cpp +structuredData/pointStructure/selectors/selectorGeometric/selectorGeometrics.cpp -commandLine/commandLine.cpp +triSurface/subSurface.cpp +triSurface/triSurface.cpp +triSurface/multiTriSurface.cpp +containers/pointField/boundaryField/generalBoundary/generalBoundary.cpp +containers/pointField/pointField/pointFields.cpp +containers/triSurfaceField/triSurfaceFields.cpp + +setFieldList/setFieldList.cpp +setFieldList/setFieldEntry.cpp ) diff --git a/src/phasicFlow/Kokkos/KokkosTypes.hpp b/src/phasicFlow/Kokkos/KokkosTypes.hpp index 3d8cac38..c902abef 100644 --- a/src/phasicFlow/Kokkos/KokkosTypes.hpp +++ b/src/phasicFlow/Kokkos/KokkosTypes.hpp @@ -2,17 +2,17 @@ O C enter of O O E ngineering and O O M ultiscale modeling of - OOOOOOO F luid flow + 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 + 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 + 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. @@ -22,135 +22,141 @@ Licence: /** * \file KokkosType.hpp - * - * \brief name aliases and typedesf for Kokkos entities that are + * + * \brief name aliases and typedesf for Kokkos entities that are * frequently used in PhasicFlow. - * + * */ - #include #include #include #include "builtinTypes.hpp" - namespace pFlow { -///********DEP -class DeviceSide{}; -class HostSide{}; +/// Host memory space +using HostSpace = Kokkos::HostSpace; -template -struct selectSide{}; -/*********/// - -/// Host memory space -using HostSpace = Kokkos::HostSpace; - -/// Serial execution space -using Serial = Kokkos::Serial; +/// Serial execution space +using Serial = Kokkos::Serial; #ifdef _OPENMP -/// OpenMp execution space -using OpenMP = Kokkos::OpenMP; +/// OpenMp execution space +using OpenMP = Kokkos::OpenMP; #endif #ifdef __CUDACC__ -/// Cuda execution space -using Cuda = Kokkos::Cuda; +/// Cuda execution space +using Cuda = Kokkos::Cuda; #endif -/// Default Host execution space, on top of all host execution spaces -using DefaultHostExecutionSpace = Kokkos::DefaultHostExecutionSpace; +/// Default Host execution space, on top of all host execution spaces +using DefaultHostExecutionSpace = Kokkos::DefaultHostExecutionSpace; -/// Default execution space, it can be device exe. space, if a device space is -/// activated. -using DefaultExecutionSpace = Kokkos::DefaultExecutionSpace; +/// Default execution space, it can be device exe. space, if a device space is +/// activated. +using DefaultExecutionSpace = Kokkos::DefaultExecutionSpace; +using deviceRPolicyStatic = Kokkos::RangePolicy< + Kokkos::DefaultExecutionSpace, + Kokkos::Schedule, + Kokkos::IndexType>; + +using hostRPolicyStatic = Kokkos::RangePolicy< + Kokkos::DefaultExecutionSpace, + Kokkos::Schedule, + Kokkos::IndexType>; + +using deviceRPolicyDynamic = Kokkos::RangePolicy< + Kokkos::DefaultExecutionSpace, + Kokkos::Schedule, + Kokkos::IndexType>; + +using hostRPolicyDynamic = Kokkos::RangePolicy< + Kokkos::DefaultExecutionSpace, + Kokkos::Schedule, + Kokkos::IndexType>; /// Pair of two variables template -using Pair = Kokkos::pair; +using Pair = Kokkos::pair; /// View for a scalar template - using ViewTypeScalar = Kokkos::View; +using ViewTypeScalar = Kokkos::View; -/// 1D veiw as a vector +/// 1D veiw as a vector template - using ViewType1D = Kokkos::View; +using ViewType1D = Kokkos::View; /// 2D view as an array template - using ViewType2D = Kokkos::View; +using ViewType2D = Kokkos::View; /// 3D view as an array template - using ViewType3D = Kokkos::View; +using ViewType3D = Kokkos::View; -/// 1D dual view as a vector +/// 1D dual view as a vector template - using DualViewType1D = Kokkos::DualView; +using DualViewType1D = Kokkos::DualView; /// unordered map template - using unorderedMap = Kokkos::UnorderedMap; +using unorderedMap = Kokkos::UnorderedMap; -/// unordered set +/// unordered set template - using unorderedSet = Kokkos::UnorderedMap; +using unorderedSet = Kokkos::UnorderedMap; -/// Scalar on device +/// Scalar on device template - using deviceViewTypeScalar = Kokkos::View; +using deviceViewTypeScalar = Kokkos::View; /// 1D array (vector) with default device (memory space and execution space) template - using deviceViewType1D = Kokkos::View; - -/// 2D view on device as an array on device -template - using deviceViewType2D = Kokkos::View; - -/// 3D view on device as an array on device -template - using deviceViewType3D = Kokkos::View; +using deviceViewType1D = Kokkos::View; +/// 2D view on device as an array on device +template +using deviceViewType2D = Kokkos::View; +/// 3D view on device as an array on device +template +using deviceViewType3D = Kokkos::View; template - using hostViewTypeScalar = Kokkos::View; +using hostViewTypeScalar = Kokkos::View; /// 1D array (vector with host memeory space) template - using hostViewType1D = Kokkos::View; +using hostViewType1D = Kokkos::View; -/// 2D array on host -template - using hostViewType2D = Kokkos::View; +/// 2D array on host +template +using hostViewType2D = Kokkos::View; /// 3D array on host -template - using hostViewType3D = Kokkos::View; +template +using hostViewType3D = Kokkos::View; /// 1D vector on device with atomic capabilities template -using deviceAtomicViewType1D = - Kokkos::View< - T*, - Kokkos::MemoryTraits::value?0:Kokkos::Atomic>>; +using deviceAtomicViewType1D = Kokkos::View< + T*, + Kokkos::MemoryTraits< + std::is_same_v ? 0 : Kokkos::Atomic>>; /// 3D array on device with atomic capabilities template -using deviceAtomicViewType3D = - Kokkos::View< - T***, - Kokkos::MemoryTraits::value?0:Kokkos::Atomic>>; - +using deviceAtomicViewType3D = Kokkos::View< + T***, + Kokkos::MemoryTraits< + std::is_same_v ? 0 : Kokkos::Atomic>>; } // pFlow -#endif //__KokkosTypes_hpp__ +#endif //__KokkosTypes_hpp__ diff --git a/src/phasicFlow/Kokkos/KokkosUtilities.hpp b/src/phasicFlow/Kokkos/KokkosUtilities.hpp index 6d1c7f46..7669ba1f 100644 --- a/src/phasicFlow/Kokkos/KokkosUtilities.hpp +++ b/src/phasicFlow/Kokkos/KokkosUtilities.hpp @@ -2,17 +2,17 @@ O C enter of O O E ngineering and O O M ultiscale modeling of - OOOOOOO F luid flow + 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 + 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 + 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. @@ -21,209 +21,205 @@ Licence: #ifndef __KokkosUtilities_hpp__ #define __KokkosUtilities_hpp__ - #include "KokkosTypes.hpp" -#include "pFlowMacros.hpp" -#include "types.hpp" -#include "span.hpp" #include "dataIO.hpp" #include "iOstream.hpp" +#include "pFlowMacros.hpp" +#include "span.hpp" +#include "types.hpp" namespace pFlow { template -INLINE_FUNCTION_H -bool constexpr isHostAccessible() +INLINE_FUNCTION_H bool constexpr isHostAccessible() { - return Kokkos::SpaceAccessibility::accessible; + return Kokkos::SpaceAccessibility::accessible; } template -INLINE_FUNCTION_H -bool constexpr isDeviceAccessible() +INLINE_FUNCTION_H bool constexpr isDeviceAccessible() { - return Kokkos::SpaceAccessibility::accessible; + return Kokkos::SpaceAccessibility< + ExecutionSpace, + DefaultExecutionSpace::memory_space>::accessible; } /// Is MemoerySpace accessible from ExecutionSpace template -INLINE_FUNCTION_H -bool constexpr areAccessible() +INLINE_FUNCTION_H bool constexpr areAccessible() { - return Kokkos::SpaceAccessibility::accessible; + return Kokkos::SpaceAccessibility::accessible; } -template < - typename Type, - typename... Properties> -INLINE_FUNCTION_H -void reallocInit( ViewType1D& view, uint32 len) -{ - Kokkos::realloc(Kokkos::WithoutInitializing, view, len); -} - -template < - typename Type, - typename... Properties> -INLINE_FUNCTION_H -void reallocNoInit(ViewType1D& view, uint32 len) +template +INLINE_FUNCTION_H void +reallocInit(ViewType1D& view, uint32 len) { Kokkos::realloc(Kokkos::WithoutInitializing, view, len); } -template < - typename Type, - typename... Properties> -INLINE_FUNCTION_H -void reallocFill( ViewType1D& view, uint32 len, Type val) +template +INLINE_FUNCTION_H void +reallocNoInit(ViewType1D& view, uint32 len) +{ + Kokkos::realloc(Kokkos::WithoutInitializing, view, len); +} + +template +INLINE_FUNCTION_H void +reallocFill(ViewType1D& view, uint32 len, Type val) { reallocNoInit(view, len); Kokkos::deep_copy(view, val); } -template < - typename Type, - typename... Properties> -INLINE_FUNCTION_H -void reallocInit( ViewType2D& view, uint32 len1, uint32 len2) +template +INLINE_FUNCTION_H void +reallocInit(ViewType2D& view, uint32 len1, uint32 len2) { Kokkos::realloc(view, len1, len2); } -template < - typename Type, - typename... Properties> -INLINE_FUNCTION_H -void reallocNoInit(ViewType2D& view, uint32 len1, uint32 len2) -{ - Kokkos::realloc(Kokkos::WithoutInitializing, view, len1, len2); +template +INLINE_FUNCTION_H void +reallocNoInit(ViewType2D& view, uint32 len1, uint32 len2) +{ + Kokkos::realloc(Kokkos::WithoutInitializing, view, len1, len2); } -template < - typename Type, - typename... Properties> -INLINE_FUNCTION_H -void reallocFill( ViewType2D& view, uint32 len1, uint32 len2, Type val) +template +INLINE_FUNCTION_H void +reallocFill( + ViewType2D& view, + uint32 len1, + uint32 len2, + Type val +) { reallocNoInit(view, len1, len2); Kokkos::deep_copy(view, val); } -template < - typename Type, - typename... Properties> -INLINE_FUNCTION_H -void reallocInit( ViewType3D& view, uint32 len1, uint32 len2, uint32 len3) +template +INLINE_FUNCTION_H void +reallocInit( + ViewType3D& view, + uint32 len1, + uint32 len2, + uint32 len3 +) { Kokkos::realloc(view, len1, len2, len3); } -template < - typename Type, - typename... Properties> -INLINE_FUNCTION_H -void reallocNoInit(ViewType3D& view, uint32 len1, uint32 len2, uint32 len3) +template +INLINE_FUNCTION_H void +reallocNoInit( + ViewType3D& view, + uint32 len1, + uint32 len2, + uint32 len3 +) { - - Kokkos::realloc(Kokkos::WithoutInitializing, view, len1, len2, len3); + Kokkos::realloc(Kokkos::WithoutInitializing, view, len1, len2, len3); } -template < - typename Type, - typename... Properties> -INLINE_FUNCTION_H -void reallocFill( ViewType3D& view, uint32 len1, uint32 len2, uint32 len3, Type val) +template +INLINE_FUNCTION_H void +reallocFill( + ViewType3D& view, + uint32 len1, + uint32 len2, + uint32 len3, + Type val +) { reallocNoInit(view, len1, len2, len3); Kokkos::deep_copy(view, val); } -template < - typename Type, - typename... Properties> -INLINE_FUNCTION_H -void resizeInit(ViewType1D& view, uint32 newLen) +template +INLINE_FUNCTION_H void +resizeInit(ViewType1D& view, uint32 newLen) { Kokkos::resize(view, newLen); } -template < - typename Type, - typename... Properties> -INLINE_FUNCTION_H -void resizeNoInit(ViewType1D& view, uint32 newLen) +template +INLINE_FUNCTION_H void +resizeNoInit(ViewType1D& view, uint32 newLen) { Kokkos::resize(Kokkos::WithoutInitializing, view, newLen); } template -INLINE_FUNCTION_H -void swapViews(ViewType& v1, ViewType &v2) +INLINE_FUNCTION_H void +swapViews(ViewType& v1, ViewType& v2) { static_assert( - std::is_move_assignable::value && std::is_move_constructible::value, - "swapViews arguments must be move assignable and move constructible"); + std::is_move_assignable_v && + std::is_move_constructible_v, + "swapViews arguments must be move assignable and move constructible" + ); ViewType tmp = std::move(v1); - v1 = std::move(v2); - v2 = std::move(tmp); + v1 = std::move(v2); + v2 = std::move(tmp); } - template -INLINE_FUNCTION_H -iOstream& operator <<(iOstream& os, const Pair& p) +INLINE_FUNCTION_H iOstream& +operator<<(iOstream& os, const Pair& p) { - os<<'('< -INLINE_FUNCTION_H -span makeSpan(ViewType1D & v) +INLINE_FUNCTION_H span + makeSpan(ViewType1D& v) { return span(v.data(), v.size()); } template -INLINE_FUNCTION_H -span makeSpan(ViewType1D & v, uint32 size) +INLINE_FUNCTION_H span + makeSpan(ViewType1D& v, uint32 size) { return span(v.data(), size); } template -INLINE_FUNCTION_H -span makeSpan(const ViewType1D & v) +INLINE_FUNCTION_H span + makeSpan(const ViewType1D& v) { return span(const_cast(v.data()), v.size()); } template -INLINE_FUNCTION_H -span makeSpan(const ViewType1D & v, uint32 size) +INLINE_FUNCTION_H span + makeSpan(const ViewType1D& v, uint32 size) { return span(const_cast(v.data()), size); } - template -INLINE_FUNCTION_H -iOstream& operator <<(iOstream& os, const ViewType1D & v) +INLINE_FUNCTION_H iOstream& +operator<<(iOstream& os, const ViewType1D& v) { - using ExSpace = typename ViewType1D::execution_space; - static_assert(isHostAccessible(), "View memory is not accessible from Host"); + static_assert( + isHostAccessible(), "View memory is not accessible from Host" + ); span spn(v.data(), v.size()); - os< -#include "pFlowMacros.hpp" -#include "typeInfo.hpp" #include "builtinTypes.hpp" #include "iOstream.hpp" - +#include "pFlowMacros.hpp" +#include "typeInfo.hpp" namespace pFlow { - /** * Range for elements in an vector [start,end) - * + * */ template -struct Range -: -public Kokkos::pair +struct Range : public Kokkos::pair { - using Pair = Kokkos::pair; + using Pair = Kokkos::pair; TypeInfoTemplateNV11("Range", T) - //// - Constructors + //// - Constructors - /// Default - INLINE_FUNCTION_HD - Range(){} + /// Default + INLINE_FUNCTION_HD Range() = default; - /// From end, set start to 0 - INLINE_FUNCTION_HD - Range(const T& e) - : - Range(0,e) - {} - - /// From componeents - INLINE_FUNCTION_HD - Range(const T& s, const T& e) - : - Range::Pair(s,e) - {} + /// From end, set start to 0 + INLINE_FUNCTION_HD + explicit Range(const T& e) + : Range(0, e) + { + } - /// From pair - INLINE_FUNCTION_HD - Range(const Range::Pair &src ) - : - Range::Pair(src) - {} + /// From componeents + INLINE_FUNCTION_HD + Range(const T& s, const T& e) + : Range::Pair(s, e) + { + } - /// Copy - INLINE_FUNCTION_HD - Range(const Range&) = default; + /// From pair + INLINE_FUNCTION_HD + Range(const Range::Pair& src) + : Range::Pair(src) + { + } - /// Move - INLINE_FUNCTION_HD - Range(Range&&) = default; + /// Copy + INLINE_FUNCTION_HD + Range(const Range&) = default; - /// Copy assignment - INLINE_FUNCTION_HD - Range& operator=(const Range&) = default; + /// Move + INLINE_FUNCTION_HD + Range(Range&&) = default; - /// Move assignment - INLINE_FUNCTION_HD - Range& operator=(Range&&) = default; + /// Copy assignment + INLINE_FUNCTION_HD + Range& operator=(const Range&) = default; - /// Destructor - INLINE_FUNCTION_HD - ~Range()=default; + /// Move assignment + INLINE_FUNCTION_HD + Range& operator=(Range&&) = default; + + /// Destructor + INLINE_FUNCTION_HD + ~Range() = default; //// - Methods - /// Start - INLINE_FUNCTION_HD - T& start() - { - return this->first; - } + /// Start + INLINE_FUNCTION_HD + T& start() + { + return this->first; + } - /// End - INLINE_FUNCTION_HD - T& end() - { - return this->second; - } + /// End + INLINE_FUNCTION_HD + T& end() + { + return this->second; + } - INLINE_FUNCTION_HD - const T& start()const - { - return this->first; - } + INLINE_FUNCTION_HD + const T& start() const + { + return this->first; + } - INLINE_FUNCTION_HD - const T& end()const - { - return this->second; - } + INLINE_FUNCTION_HD + const T& end() const + { + return this->second; + } - INLINE_FUNCTION_HD - T numElements() - { - return end()-start(); - } - - INLINE_FUNCTION_HD - auto getPair()const - { - return Pair(this->first, this->second); - } + INLINE_FUNCTION_HD + T numElements() + { + return end() - start(); + } + INLINE_FUNCTION_HD + auto getPair() const + { + return Pair(this->first, this->second); + } }; template -INLINE_FUNCTION_H -iOstream& operator <<(iOstream& os, const Range& rng) +INLINE_FUNCTION_H iOstream& +operator<<(iOstream& os, const Range& rng) { - os<<"["<; +using range32 = Range; -using range64 = Range; +using range64 = Range; -using rangeU32 = Range; - -using rangeU64 = Range; +using rangeU32 = Range; +using rangeU64 = Range; } // pFlow -#endif //__KokkosTypes_hpp__ +#endif //__KokkosTypes_hpp__ diff --git a/src/phasicFlow/Kokkos/ViewAlgorithms.hpp b/src/phasicFlow/Kokkos/ViewAlgorithms.hpp index 7e8134a9..db071f0b 100644 --- a/src/phasicFlow/Kokkos/ViewAlgorithms.hpp +++ b/src/phasicFlow/Kokkos/ViewAlgorithms.hpp @@ -2,17 +2,17 @@ O C enter of O O E ngineering and O O M ultiscale modeling of - OOOOOOO F luid flow + 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 + 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 + 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. @@ -21,268 +21,279 @@ Licence: #ifndef __ViewAlgorithms_hpp__ #define __ViewAlgorithms_hpp__ - -#include "numericConstants.hpp" -#include "Range.hpp" #include "KokkosUtilities.hpp" +#include "Range.hpp" +#include "numericConstants.hpp" +#include "cudaAlgorithms.hpp" #include "kokkosAlgorithms.hpp" #include "stdAlgorithms.hpp" -#include "cudaAlgorithms.hpp" - namespace pFlow -{ -template -INLINE_FUNCTION_H -uint32 count( - const ViewType1D& view, - uint32 start, - uint32 end, - const T& val) { - - using ExecutionSpace = typename ViewType1D::execution_space; - - uint32 numElems = end-start; - - return pFlow::algorithms::KOKKOS::count - ( - view.data()+start, - numElems, - val - ); -} - template -INLINE_FUNCTION_H -void fill -( - ViewType1D& view, - rangeU32 span, - T val +INLINE_FUNCTION_H uint32 +count( + const ViewType1D& view, + uint32 start, + uint32 end, + const T& val ) { - auto subV = Kokkos::subview(view, span.getPair() ); + using ExecutionSpace = + typename ViewType1D::execution_space; + + uint32 numElems = end - start; + + return pFlow::algorithms::KOKKOS::count( + view.data() + start, numElems, val + ); +} + +template +INLINE_FUNCTION_H void +fill(ViewType1D& view, rangeU32 span, T val) +{ + using exe_space = typename ViewType1D::execution_space; + auto subV = Kokkos::subview(view, span.getPair()); + if constexpr (std::is_trivially_copyable_v) + { + Kokkos::deep_copy(subV, val); + } + else if constexpr (isHostAccessible()) + { + for (auto i = span.start(); i < span.end(); i++) + { + view[i] = val; + } + } + else + { + static_assert("fill is not valid for non-trivially-copyable data type"); + } +} + +template +void +fill(ViewType1D& view, uint32 start, uint32 end, T val) +{ + fill(view, rangeU32(start, end), val); +} + +template +void +fill( + ViewType3D& view, + rangeU32 range1, + rangeU32 range2, + rangeU32 range3, + const T& val +) +{ + static_assert(std::is_trivially_copyable_v, "Not valid type for fill"); + auto subV = Kokkos::subview(view, range1, range2, range3); Kokkos::deep_copy(subV, val); } template -void fill -( - ViewType1D& view, - uint32 start, - uint32 end, - T val -) +void +fill(ViewType3D& view, const T& val) { - fill(view, rangeU32(start, end),val); + static_assert(std::is_trivially_copyable_v, "Not valid type for fill"); + Kokkos::deep_copy(view, val); } -template< - typename Type, - typename... properties> -void fillSequence( - ViewType1D& view, - uint32 start, - uint32 end, - const Type startVal - ) -{ - - using ExecutionSpace = typename ViewType1D::execution_space; - uint32 numElems = end-start; - - pFlow::algorithms::KOKKOS::fillSequence( - view.data()+start, - numElems, - startVal); - - return ; -} - - -template< - typename Type, - typename... properties, - typename indexType, - typename... indexProperties> -bool fillSelected -( - ViewType1D view, - ViewType1D indices, - uint32 numElems, - Type val +template +void +fillSequence( + ViewType1D& view, + uint32 start, + uint32 end, + const Type startVal ) { static_assert( - areAccessible< - typename ViewType1D::execution_space, - typename ViewType1D::memory_space>(), - "In fillSelected, arguments view and indices must have similar spaces"); + std::is_trivially_copyable_v, "Not valid type for fill" + ); + using ExecutionSpace = + typename ViewType1D::execution_space; + uint32 numElems = end - start; + + pFlow::algorithms::KOKKOS::fillSequence( + view.data() + start, numElems, startVal + ); + + return; +} + +template< + typename Type, + typename... properties, + typename indexType, + typename... indexProperties> +bool +fillSelected( + ViewType1D view, + ViewType1D indices, + uint32 numElems, + Type val +) +{ + static_assert( + std::is_trivially_copyable_v, "Not valid type for fillSelected" + ); + static_assert( + areAccessible< + typename ViewType1D::execution_space, + typename ViewType1D::memory_space>(), + "In fillSelected, arguments view and indices must have similar spaces" + ); using ExSpace = typename ViewType1D::execution_space; - using policy = Kokkos::RangePolicy >; + using policy = Kokkos::RangePolicy>; Kokkos::parallel_for( - "ViewAlgorithms::fillSelected", - policy(0,numElems), - LAMBDA_HD(uint32 i){ - //view[indices[i]]= val; - }); + "ViewAlgorithms::fillSelected", + policy(0, numElems), + LAMBDA_HD(uint32 i){ + // view[indices[i]]= val; + } + ); Kokkos::fence(); return true; } template< - typename Type, - typename... properties, - typename indexType, - typename... indexProperties> -bool fillSelected( - ViewType1D view, - const ViewType1D indices, - const ViewType1D vals, - const uint32 numElems ) + typename Type, + typename... properties, + typename indexType, + typename... indexProperties> +bool +fillSelected( + ViewType1D view, + const ViewType1D indices, + const ViewType1D vals, + const uint32 numElems +) { - static_assert( - areAccessible< - typename ViewType1D::execution_space, - typename ViewType1D::memory_space>(), - "In fillSelected arguments view and indices must have similar spaces"); + std::is_trivially_copyable_v, "Not valid type for fillSelected" + ); + static_assert( + areAccessible< + typename ViewType1D::execution_space, + typename ViewType1D::memory_space>(), + "In fillSelected arguments view and indices must have similar spaces" + ); + + using ExecutionSpace = + typename ViewType1D::execution_space; - using ExecutionSpace = typename ViewType1D::execution_space; - pFlow::algorithms::KOKKOS::fillSelected( - view.data(), - indices.data(), - vals.data(), - numElems - ); + view.data(), indices.data(), vals.data(), numElems + ); return true; } - template -INLINE_FUNCTION_H -T min( - const ViewType1D& view, - uint32 start, - uint32 end) +INLINE_FUNCTION_H T +min(const ViewType1D& view, uint32 start, uint32 end) { + using ExecutionSpace = + typename ViewType1D::execution_space; - using ExecutionSpace = typename ViewType1D::execution_space; - - uint32 numElems = end-start; - - return - pFlow::algorithms::KOKKOS::min( - view.data()+start, - numElems); + uint32 numElems = end - start; + + return pFlow::algorithms::KOKKOS::min( + view.data() + start, numElems + ); } template -INLINE_FUNCTION_H -T max( - const ViewType1D& view, - uint32 start, - uint32 end) +INLINE_FUNCTION_H T +max(const ViewType1D& view, uint32 start, uint32 end) { + using ExecutionSpace = + typename ViewType1D::execution_space; - using ExecutionSpace = typename ViewType1D::execution_space; - - uint32 numElems = end-start; + uint32 numElems = end - start; - return - pFlow::algorithms::KOKKOS::max( - view.data()+start, - numElems); -} - -template < - typename dType, - typename... dProperties, - typename sType, - typename... sProperties> -INLINE_FUNCTION_H -void copy( - const ViewType1D& dst, - const ViewType1D& src - ) -{ - Kokkos::deep_copy(dst,src); + return pFlow::algorithms::KOKKOS::max( + view.data() + start, numElems + ); } -template < - typename dType, - typename... dProperties, - typename sType, - typename... sProperties> -INLINE_FUNCTION_H -void copy( - const ViewType1D& dst, - uint32 dStart, - const ViewType1D& src, - uint32 sStart, - uint32 sEnd - ) +template< + typename dType, + typename... dProperties, + typename sType, + typename... sProperties> +INLINE_FUNCTION_H void +copy( + const ViewType1D& dst, + const ViewType1D& src +) { - - range32 sSpan(sStart,sEnd); - range32 dSpan(dStart,dStart+(sEnd-sStart)); - - auto srcSub = Kokkos::subview(src, sSpan); - auto dstSub = Kokkos::subview(dst, dSpan); - - Kokkos::deep_copy(dstSub,srcSub); + Kokkos::deep_copy(dst, src); } -template < - typename dType, - typename sType, - typename... sProperties> -INLINE_FUNCTION_H -void getNth( - dType& dst, - const ViewType1D& src, - const uint32 n - ) +template< + typename dType, + typename... dProperties, + typename sType, + typename... sProperties> +INLINE_FUNCTION_H void +copy( + const ViewType1D& dst, + uint32 dStart, + const ViewType1D& src, + uint32 sStart, + uint32 sEnd +) { - range32 span(n,n+1); - auto subV = Kokkos::subview(src, span); - hostViewType1D dstView("getNth",1); - Kokkos::deep_copy(dstView,subV); + + auto srcSub = Kokkos::subview( + src, + Kokkos::make_pair(sStart, sEnd)); + + auto dstSub = Kokkos::subview( + dst, + Kokkos::make_pair(dStart, dStart + (sEnd - sStart))); + + Kokkos::deep_copy(dstSub, srcSub); +} + +template +INLINE_FUNCTION_H void +getNth(Type& dst, const ViewType1D& src, const uint32 n) +{ + auto subV = Kokkos::subview(src, Kokkos::make_pair(n, n + 1)); + hostViewType1D dstView("getNth", 1); + // hostViewTypeScalar + Kokkos::deep_copy(dstView, subV); dst = *dstView.data(); } - template -INLINE_FUNCTION_H -void sort( - ViewType1D& view, - uint32 start, - uint32 end) +INLINE_FUNCTION_H void +sort(ViewType1D& view, uint32 start, uint32 end) { - using ExecutionSpace = typename ViewType1D::execution_space; - - uint32 numElems = end-start; + using ExecutionSpace = + typename ViewType1D::execution_space; - if constexpr( isHostAccessible()) - { - pFlow::algorithms::STD::sort( - view.data()+start, - numElems); + uint32 numElems = end - start; + + if constexpr (isHostAccessible()) + { + pFlow::algorithms::STD::sort(view.data() + start, numElems); return; } #ifdef __CUDACC__ - - pFlow::algorithms::CUDA::sort( - view.data()+start, - numElems); + + pFlow::algorithms::CUDA::sort(view.data() + start, numElems); #else static_assert("sort on device is not defined!"); @@ -292,33 +303,32 @@ void sort( } template -INLINE_FUNCTION_H -void sort( - ViewType1D& view, - uint32 start, - uint32 end, - CompareFunc compare) +INLINE_FUNCTION_H void +sort( + ViewType1D& view, + uint32 start, + uint32 end, + CompareFunc compare +) { + using ExecutionSpace = + typename ViewType1D::execution_space; - using ExecutionSpace = typename ViewType1D::execution_space; - - uint32 numElems = end-start; + uint32 numElems = end - start; - if constexpr( isHostAccessible()) + if constexpr (isHostAccessible()) { - pFlow::algorithms::STD::sort( - view.data()+start, - numElems, - compare); - return; + pFlow::algorithms::STD::sort( + view.data() + start, numElems, compare + ); + return; } #ifdef __CUDACC__ - + pFlow::algorithms::CUDA::sort( - view.data()+start, - numElems, - compare); + view.data() + start, numElems, compare + ); #else static_assert("sort on device is not defined!"); @@ -328,165 +338,157 @@ void sort( } template< - typename Type, - typename... properties, - typename permType, - typename... permProperties> -void permuteSort( - const ViewType1D& view, - uint32 start, - uint32 end, - ViewType1D& permuteView, - uint32 permStart ) + typename Type, + typename... properties, + typename permType, + typename... permProperties> +void +permuteSort( + const ViewType1D& view, + uint32 start, + uint32 end, + ViewType1D& permuteView, + uint32 permStart +) { static_assert( - areAccessible< - typename ViewType1D::execution_space, - typename ViewType1D::memory_space>(), - "In permuteSort, view and permuteView should have the same space"); + areAccessible< + typename ViewType1D::execution_space, + typename ViewType1D::memory_space>(), + "In permuteSort, view and permuteView should have the same space" + ); - using ExecutionSpace = typename ViewType1D::execution_space; - - uint32 numElems = end-start; - - pFlow::algorithms::STD::permuteSort( - view.data()+start, - permuteView.data()+permStart, - numElems); + using ExecutionSpace = + typename ViewType1D::execution_space; + + uint32 numElems = end - start; + + pFlow::algorithms::STD::permuteSort( + view.data() + start, permuteView.data() + permStart, numElems + ); return; - #ifdef __CUDACC__ - + pFlow::algorithms::CUDA::permuteSort( - view.data()+start, - permuteView.data()+permStart, - numElems); + view.data() + start, permuteView.data() + permStart, numElems + ); #else static_assert("sort on device is not defined!"); #endif - } template -INLINE_FUNCTION_HD -int32 binarySearch_(const T* array, int32 length, const T& val) +INLINE_FUNCTION_HD int32 +binarySearch_(const T* array, int32 length, const T& val) { - if(length <= 0) return -1; - - int low = 0; - int high = length - 1; + if (length <= 0) + return -1; - while (low <= high) - { - int mid = low + (high - low)/2; - - if ( array[mid] > val) - { - high = mid - 1; - } - else if ( array[mid] < val) - { - low = mid + 1; - } - else - { - return mid; - } - } + int low = 0; + int high = length - 1; - return -1; // val not found in array[0, length) + while (low <= high) + { + int mid = low + (high - low) / 2; + + if (array[mid] > val) + { + high = mid - 1; + } + else if (array[mid] < val) + { + low = mid + 1; + } + else + { + return mid; + } + } + + return -1; // val not found in array[0, length) } -/// On DEVICE and HOST calls -template< - typename Type, - typename... properties> -INLINE_FUNCTION_HD -int32 binarySearch( - const ViewType1D& view, - uint32 start, - uint32 end, - const Type& val) +/// On DEVICE and HOST calls +template +INLINE_FUNCTION_HD uint32 +binarySearch( + const ViewType1D& view, + uint32 start, + uint32 end, + const Type& val +) { - - if(end<=start)return -1; + if (end <= start) + return -1; - if(auto res = - binarySearch_(view.data()+start,end-start,val); res>=0) { - return res+start; + if (auto res = binarySearch_(view.data() + start, end - start, val); + res != -1) + { + return res + start; } - else{ + else + { return res; } } -template< - typename Type, - typename... properties, - typename dType, - typename... dProperties> -void exclusiveScan( - const ViewType1D& view, - uint32 start, - uint32 end, - ViewType1D& dView, - uint32 dStart ) +template +void +exclusiveScan( + const ViewType1D& view, + uint32 start, + uint32 end, + ViewType1D& dView, + uint32 dStart +) { - - static_assert - ( - areAccessible< - typename ViewType1D::execution_space, - typename ViewType1D::memory_space>(), - "In exclusiveScan, view and dView should have the same space" + static_assert( + areAccessible< + typename ViewType1D::execution_space, + typename ViewType1D::memory_space>(), + "In exclusiveScan, view and dView should have the same space" ); - using ExecutionSpace = typename ViewType1D::execution_space; - - uint32 numElems = end-start; - - pFlow::algorithms::KOKKOS::exclusiveScan( - view.data()+start, - dView.data()+dStart, - numElems); + using ExecutionSpace = + typename ViewType1D::execution_space; + + uint32 numElems = end - start; + + pFlow::algorithms::KOKKOS::exclusiveScan( + view.data() + start, dView.data() + dStart, numElems + ); } - -template< - typename Type, - typename... properties, - typename dType, - typename... dProperties> -void inclusiveScan( - const ViewType1D& view, - uint32 start, - uint32 end, - ViewType1D& dView, - uint32 dStart) +template +void +inclusiveScan( + const ViewType1D& view, + uint32 start, + uint32 end, + ViewType1D& dView, + uint32 dStart +) { - using ExecutionSpace = typename ViewType1D::execution_space; - - static_assert - ( - areAccessible< - typename ViewType1D::execution_space, - typename ViewType1D::memory_space>(), - "In exclusiveScan, view and dView should have the same space" + using ExecutionSpace = + typename ViewType1D::execution_space; + + static_assert( + areAccessible< + typename ViewType1D::execution_space, + typename ViewType1D::memory_space>(), + "In exclusiveScan, view and dView should have the same space" ); + uint32 numElems = end - start; - uint32 numElems = end-start; - - pFlow::algorithms::KOKKOS::inclusiveScan( - view.data()+start, - dView.data()+dStart, - numElems); + pFlow::algorithms::KOKKOS::inclusiveScan( + view.data() + start, dView.data() + dStart, numElems + ); } } // pFlow - -#endif // Viewalgorithms +#endif // __ViewAlgorithms_hpp__ diff --git a/src/phasicFlow/Kokkos/baseAlgorithmsFwd_.hpp b/src/phasicFlow/Kokkos/baseAlgorithmsFwd_.hpp index c4fa96ad..779c0b03 100644 --- a/src/phasicFlow/Kokkos/baseAlgorithmsFwd_.hpp +++ b/src/phasicFlow/Kokkos/baseAlgorithmsFwd_.hpp @@ -2,50 +2,50 @@ O C enter of O O E ngineering and O O M ultiscale modeling of - OOOOOOO F luid flow + 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 + 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 + 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 -void insertSetElementH -( - ViewType1D& view, - hostViewType1D