diff --git a/CMakeLists.txt b/CMakeLists.txt index f9740a90..927c1ec2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,74 +1,73 @@ cmake_minimum_required(VERSION 3.16 FATAL_ERROR) # set the project name and version -project(phasicFlow VERSION 0.1 ) +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(BUILD_SHARED_LIBS ON CACHE BOOL "Build using shared libraries" FORCE) +mark_as_advanced(FORCE var BUILD_SHARED_LIBS) message(STATUS ${CMAKE_INSTALL_PREFIX}) -mark_as_advanced(FORCE var Kokkos_ENABLE_CUDA_LAMBDA) -mark_as_advanced(FORCE var Kokkos_ENABLE_OPENMP) -mark_as_advanced(FORCE var Kokkos_ENABLE_SERIAL) -mark_as_advanced(FORCE var Kokkos_ENABLE_CUDA_LAMBDA) -mark_as_advanced(FORCE var BUILD_SHARED_LIBS) +include(cmake/globals.cmake) -option(USE_STD_PARALLEL_ALG "Use TTB std parallel algorithms" ON) +#Kokkos directory to be included +set(Kokkos_Source_DIR) + +if(DEFINED ENV{Kokkos_DIR}) + set(Kokkos_Source_DIR $ENV{Kokkos_DIR}) +else() + set(Kokkos_Source_DIR $ENV{HOME}/Kokkos/kokkos) +endif() +message(STATUS "Kokkos source directory is ${Kokkos_Source_DIR}") +add_subdirectory(${Kokkos_Source_DIR} ${phasicFlow_BINARY_DIR}/kokkos) +Kokkos_cmake_settings() + + +option(pFlow_STD_Parallel_Alg "Use TTB std parallel algorithms" ON) option(pFlow_Build_Serial "Build phasicFlow and backends for serial execution" OFF) option(pFlow_Build_OpenMP "Build phasicFlow and backends for OpenMP execution" OFF) option(pFlow_Build_Cuda "Build phasicFlow and backends for Cuda execution" OFF) -option(pFlow_Build_Double "Build phasicFlow with double precision variables" ON) +option(pFlow_Build_Double "Build phasicFlow with double precision floating-oint variables" ON) +option(pFlow_Build_MPI "Build for MPI parallelization. This will enable multi-gpu run, CPU run on clusters (distributed memory machine). Use this combination Cuda+MPI, OpenMP + MPI or Serial+MPI " OFF) -set(BUILD_SHARED_LIBS ON CACHE BOOL "Build using shared libraries" FORCE) if(pFlow_Build_Serial) set(Kokkos_ENABLE_SERIAL ON CACHE BOOL "Serial execution" FORCE) set(Kokkos_ENABLE_OPENMP OFF CACHE BOOL "OpenMP execution" FORCE) set(Kokkos_ENABLE_CUDA OFF CACHE BOOL "Cuda execution" FORCE) set(Kokkos_ENABLE_CUDA_LAMBDA OFF CACHE BOOL "Cuda execution" FORCE) + set(Kokkos_ENABLE_CUDA_CONSTEXPR OFF CACHE BOOL "Enable constexpr on cuda code" FORCE) elseif(pFlow_Build_OpenMP ) set(Kokkos_ENABLE_SERIAL ON CACHE BOOL "Serial execution" FORCE) set(Kokkos_ENABLE_OPENMP ON CACHE BOOL "OpenMP execution" FORCE) set(Kokkos_ENABLE_CUDA OFF CACHE BOOL "Cuda execution" FORCE) set(Kokkos_ENABLE_CUDA_LAMBDA OFF CACHE BOOL "Cuda execution" FORCE) set(Kokkos_DEFAULT_HOST_PARALLEL_EXECUTION_SPACE SERIAL CACHE STRING "" FORCE) + set(Kokkos_ENABLE_CUDA_CONSTEXPR OFF CACHE BOOL "Enable constexpr on cuda code" FORCE) elseif(pFlow_Build_Cuda) set(Kokkos_ENABLE_SERIAL ON CACHE BOOL "Serial execution" FORCE) set(Kokkos_ENABLE_OPENMP OFF CACHE BOOL "OpenMP execution" FORCE) set(Kokkos_ENABLE_CUDA ON CACHE BOOL "Cuda execution" FORCE) set(Kokkos_ENABLE_CUDA_LAMBDA ON CACHE BOOL "Cuda execution" FORCE) + set(Kokkos_ENABLE_CUDA_CONSTEXPR ON CACHE BOOL "Enable constexpr on cuda code" FORCE) endif() - - -include(cmake/globals.cmake) -message(STATUS "Valid file extensions are ${validFiles}") +if(pFlow_Build_MPI) + find_package(MPI REQUIRED) +endif() include(cmake/makeLibraryGlobals.cmake) include(cmake/makeExecutableGlobals.cmake) configure_file(phasicFlowConfig.H.in phasicFlowConfig.H) - +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) #add a global include directory include_directories(src/setHelpers src/demComponent "${PROJECT_BINARY_DIR}") -#main subdirectories of the code -set(Kokkos_Source_DIR) - -if(DEFINED ENV{Kokkos_DIR}) - set(Kokkos_Source_DIR $ENV{Kokkos_DIR}) -# add_subdirectory($ENV{Kokkos_DIR} ${phasicFlow_BINARY_DIR}/kokkos) -# message(STATUS "Kokkos directory is $ENV{Kokkos_DIR}") -else() -# add_subdirectory($ENV{HOME}/Kokkos/kokkos ${phasicFlow_BINARY_DIR}/kokkos) - set(Kokkos_Source_DIR $ENV{HOME}/Kokkos/kokkos) -endif() - -message(STATUS "Kokkos source directory is ${Kokkos_Source_DIR}") -add_subdirectory(${Kokkos_Source_DIR} ${phasicFlow_BINARY_DIR}/kokkos) add_subdirectory(src) @@ -76,13 +75,11 @@ add_subdirectory(solvers) add_subdirectory(utilities) -add_subdirectory(DEMSystems) -#add_subdirectory(testIO) - +#add_subdirectory(DEMSystems) +add_subdirectory(testIO) install(FILES "${PROJECT_BINARY_DIR}/phasicFlowConfig.H" - DESTINATION include -) + DESTINATION include) include(InstallRequiredSystemLibraries) set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") diff --git a/cmake/bashrc b/cmake/bashrc index 50f8fa60..32c92d87 100644 --- a/cmake/bashrc +++ b/cmake/bashrc @@ -1,5 +1,5 @@ -export pFlow_PROJECT_VERSION=v0.1 +export pFlow_PROJECT_VERSION=v-1.0 export pFlow_PROJECT=phasicFlow @@ -20,6 +20,8 @@ export pFlow_SRC_DIR="$pFlow_PROJECT_DIR/src" export Kokkos_DIR="$kokkosDir" +export Zoltan_DIR="$projectDir/Zoltan" + # Cleanup variables (done as final statement for a clean exit code) unset projectDir @@ -27,5 +29,7 @@ export PATH="$pFlow_BIN_DIR:$PATH" export LD_LIBRARY_PATH="$pFlow_LIB_DIR:$LD_LIBRARY_PATH" +export LD_LIBRARY_PATH="$Zoltan_DIR/lib:$LD_LIBRARY_PATH" + #------------------------------------------------------------------------------ diff --git a/cmake/globals.cmake b/cmake/globals.cmake index b3158dd8..34c075b4 100644 --- a/cmake/globals.cmake +++ b/cmake/globals.cmake @@ -2,3 +2,52 @@ set(validFiles) list(APPEND validFiles *.C *.cpp *.cxx *.c *.cu *.H *.hpp *.hxx *.h *.cuh) +macro(Kokkos_cmake_settings) + +#mark_as_advanced(FORCE var Kokkos_ENABLE_CUDA_LAMBDA) +mark_as_advanced(FORCE var Kokkos_CXX_STANDARD) +#mark_as_advanced(FORCE var Kokkos_ENABLE_CUDA_CONSTEXPR) +mark_as_advanced(FORCE var Kokkos_ENABLE_OPENMP) +mark_as_advanced(FORCE var Kokkos_ENABLE_SERIAL) +mark_as_advanced(FORCE var Kokkos_ENABLE_CUDA) +mark_as_advanced(FORCE var Kokkos_ENABLE_HIP) +mark_as_advanced(FORCE var Kokkos_ENABLE_AGGRESSIVE_VECTORIZATION) +mark_as_advanced(FORCE var Kokkos_ENABLE_BENCHMARKS) +mark_as_advanced(FORCE var Kokkos_ENABLE_COMPILE_AS_CMAKE_LANGUAGE) +mark_as_advanced(FORCE var Kokkos_ENABLE_CUDA_LDG_INTRINSIC) +mark_as_advanced(FORCE var Kokkos_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE) +mark_as_advanced(FORCE var Kokkos_ENABLE_CUDA_UVM) +mark_as_advanced(FORCE var Kokkos_ENABLE_DEPRECATED_CODE_3) +mark_as_advanced(FORCE var Kokkos_ENABLE_DEPRECATED_CODE_4) +mark_as_advanced(FORCE var Kokkos_ENABLE_DEPRECATION_WARNINGS) +mark_as_advanced(FORCE var Kokkos_ENABLE_DESUL_ATOMICS_EXTERNAL) +mark_as_advanced(FORCE var Kokkos_ENABLE_EXAMPLES) +mark_as_advanced(FORCE var Kokkos_ENABLE_HEADER_SELF_CONTAINMENT_TESTS) +mark_as_advanced(FORCE var Kokkos_ENABLE_HIP_MULTIPLE_KERNEL_INSTANTIATIONS) +mark_as_advanced(FORCE var Kokkos_ENABLE_HIP_RELOCATABLE_DEVICE_CODE) +mark_as_advanced(FORCE var Kokkos_ENABLE_HPX) +mark_as_advanced(FORCE var Kokkos_ENABLE_HWLOC) +mark_as_advanced(FORCE var Kokkos_ENABLE_IMPL_CUDA_MALLOC_ASYNC) +mark_as_advanced(FORCE var Kokkos_ENABLE_IMPL_HPX_ASYNC_DISPATCH) +mark_as_advanced(FORCE var Kokkos_ENABLE_LARGE_MEM_TESTS) +mark_as_advanced(FORCE var Kokkos_ENABLE_DEBUG_DUALVIEW_MODIFY_CHECK) +mark_as_advanced(FORCE var Kokkos_ENABLE_LIBQUADMATH) +mark_as_advanced(FORCE var Kokkos_ENABLE_LIBRT) +mark_as_advanced(FORCE var Kokkos_ENABLE_MEMKIND) +mark_as_advanced(FORCE var Kokkos_ENABLE_ONEDPL) +mark_as_advanced(FORCE var Kokkos_ENABLE_OPENACC) +mark_as_advanced(FORCE var Kokkos_ENABLE_OPENMPTARGET) +mark_as_advanced(FORCE var Kokkos_ENABLE_ROCM) +mark_as_advanced(FORCE var Kokkos_ENABLE_SYCL) +mark_as_advanced(FORCE var Kokkos_ENABLE_TESTS) +mark_as_advanced(FORCE var Kokkos_ENABLE_THREADS) +mark_as_advanced(FORCE var Kokkos_ENABLE_TUNING) +mark_as_advanced(FORCE var Kokkos_ENABLE_UNSUPPORTED_ARCHS) +mark_as_advanced(FORCE var Kokkos_HPX_DIR) +mark_as_advanced(FORCE var Kokkos_HWLOC_DIR) +mark_as_advanced(FORCE var Kokkos_MEMKIND_DIR) +mark_as_advanced(FORCE var Kokkos_ROCM_DIR) +mark_as_advanced(FORCE var Kokkos_THREADS_DIR) + +endmacro() + diff --git a/cmake/makeExecutableGlobals.cmake b/cmake/makeExecutableGlobals.cmake index 24eb6e0f..06c48e14 100644 --- a/cmake/makeExecutableGlobals.cmake +++ b/cmake/makeExecutableGlobals.cmake @@ -31,7 +31,7 @@ target_include_directories(${target_name} message(STATUS "\nCreating make file for executable ${target_name}") message(STATUS " ${target_name} link libraries are: ${${target_link_libs}}") -message(STATUS " ${target_name} source files are: ${source_files}") +message(STATUS " ${target_name} source files are: ${${source_files}}") message(STATUS " ${target_name} include dirs are: ${includeDirs}\n") diff --git a/cmake/makeLibraryGlobals.cmake b/cmake/makeLibraryGlobals.cmake index b5e30156..4197983b 100644 --- a/cmake/makeLibraryGlobals.cmake +++ b/cmake/makeLibraryGlobals.cmake @@ -42,7 +42,7 @@ target_include_directories(${target_name} message(STATUS "\nCreating make file for library ${target_name}") message(STATUS " ${target_name} link libraries are: ${${target_link_libs}}") message(STATUS " ${target_name} source files are: ${source_files}") -message(STATUS " ${target_name} include dirs are: ${includeDirs}\n") +message(STATUS " ${target_name} include dirs are: ${includeDirs}\n \n") install(TARGETS ${target_name} DESTINATION lib) install(FILES ${includeFiles} DESTINATION include/${target_name}) diff --git a/phasicFlowConfig.H.in b/phasicFlowConfig.H.in index 919867e4..0f1b3224 100644 --- a/phasicFlowConfig.H.in +++ b/phasicFlowConfig.H.in @@ -5,5 +5,6 @@ #cmakedefine pFlow_Build_Serial #cmakedefine pFlow_Build_OpenMP #cmakedefine pFlow_Build_Cuda -#cmakedefine USE_STD_PARALLEL_ALG -#cmakedefine pFlow_Build_Double \ No newline at end of file +#cmakedefine pFlow_STD_Parallel_Alg +#cmakedefine pFlow_Build_Double +#cmakedefine pFlow_Build_MPI 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/solvers/iterateSphereParticles/createDEMComponents.hpp b/solvers/iterateSphereParticles/createDEMComponents.hpp new file mode 100755 index 00000000..85cb798a --- /dev/null +++ b/solvers/iterateSphereParticles/createDEMComponents.hpp @@ -0,0 +1,25 @@ +/*------------------------------- 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. + +-----------------------------------------------------------------------------*/ + +// +REPORT(0)<<"\nReading sphere particles . . ."<( objectFile( @@ -36,12 +36,12 @@ 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/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..863bd8a1 100644 --- a/src/Integration/AdamsBashforth2/AdamsBashforth2.hpp +++ b/src/Integration/AdamsBashforth2/AdamsBashforth2.hpp @@ -36,20 +36,16 @@ namespace pFlow */ class AdamsBashforth2 : - public integration + public integration, + public realx3PointField_D { -protected: +private: - /// dy at t-dt - realx3PointField_D& dy1_; - - /// Range policy for integration kernel (alias) - using rpIntegration = Kokkos::RangePolicy< - DefaultExecutionSpace, - Kokkos::Schedule, - Kokkos::IndexType - >; + auto& dy1() + { + return static_cast(*this); + } public: /// Type info @@ -60,17 +56,12 @@ public: /// 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,44 @@ 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); + 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..7e9212da 100644 --- a/src/Interaction/CMakeLists.txt +++ b/src/Interaction/CMakeLists.txt @@ -1,5 +1,10 @@ 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/contactSearch/contactSearch.cpp contactSearch/ContactSearch/ContactSearchs.cpp interaction/interaction.cpp 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..2a3150b1 100644 --- a/src/Interaction/contactLists/unsortedContactList.hpp +++ b/src/Interaction/contactLists/unsortedContactList.hpp @@ -72,7 +72,7 @@ protected: using rpFillPairs = Kokkos::RangePolicy< ExecutionSpace, Kokkos::Schedule, - Kokkos::IndexType, + Kokkos::IndexType, TagReFillPairs>; @@ -80,7 +80,7 @@ public: TypeInfoNV("unsortedContactList"); - unsortedContactList(int32 capacity=1) + explicit unsortedContactList(uint32 capacity=1) : UnsortedPairs(capacity), values_("values", UnsortedPairs::capacity()), @@ -122,7 +122,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 +131,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 +139,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 +148,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..84fe8c95 100644 --- a/src/Interaction/contactSearch/ContactSearch/ContactSearch.hpp +++ b/src/Interaction/contactSearch/ContactSearch/ContactSearch.hpp @@ -22,16 +22,17 @@ Licence: #ifndef __ContactSearch_hpp__ #define __ContactSearch_hpp__ - +#include "contactSearchGlobals.hpp" #include "contactSearch.hpp" #include "box.hpp" +#include "particles.hpp" +#include "geometry.hpp" namespace pFlow { template< - template class BaseMethod, - template class WallMapping + class searchMethod > class ContactSearch : @@ -39,32 +40,19 @@ 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 particleContactSearch_ = nullptr; - - uniquePtr wallMapping_ = nullptr; + uniquePtr ppwContactSearch_ = nullptr; public: - TypeInfoTemplate2("ContactSearch", ParticleContactSearchType, WallMappingType); + TypeInfoTemplate11("ContactSearch", SearchMethodType); ContactSearch( const dictionary& csDict, @@ -74,54 +62,41 @@ public: Timers& timers) : contactSearch(csDict, domain, prtcl, geom, timers) - { auto method = dict().getVal("method"); - auto wmMethod = dict().getVal("wallMapping"); - + auto nbDict = dict().subDict(method+"Info"); real minD, 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(); + + ppwContactSearch_ = + makeUnique ( nbDict, - this->domain(), + this->domainBox(), minD, maxD, position, - diam - ); - 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(), + flags, + diam, wnPoints, - wnTri, + wnTri, wPoints, wVertices - ); - REPORT(2)<<"Wall mapping algorithm for particle-wall is "<< - greenText(wallMapping_().typeName())<< endREPORT; + ); + REPORT(2)<<"Contact search algorithm for particle-particle is "<< + 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 enterBroadSearch(uint32 iter, real t, real dt)const override { - if(particleContactSearch_) + 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/contactSearch/contactSearch.cpp b/src/Interaction/contactSearch/contactSearch/contactSearch.cpp index 17c1dbd3..5753d4a2 100644 --- a/src/Interaction/contactSearch/contactSearch/contactSearch.cpp +++ b/src/Interaction/contactSearch/contactSearch/contactSearch.cpp @@ -19,7 +19,7 @@ Licence: -----------------------------------------------------------------------------*/ #include "contactSearch.hpp" - +#include "streams.hpp" pFlow::contactSearch::contactSearch( @@ -29,11 +29,12 @@ pFlow::contactSearch::contactSearch( const geometry& geom, Timers& timers) : - interactionBase(prtcl, geom), - domain_(domain), - dict_(dict), - sphereSphereTimer_("particle-particle contact search", &timers), - sphereWallTimer_("particle-wall contact search", &timers) + domainBox_(domain), + particles_(prtcl), + geometry_(geom), + ppTimer_("particle-particle contact search", &timers), + pwTimer_("particle-wall contact search", &timers), + dict_(dict) { } @@ -46,20 +47,16 @@ pFlow::uniquePtr pFlow::contactSearch::create( 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"); @@ -88,35 +81,51 @@ public: (dict, domain, prtcl, geom, timers) ); - const auto& domain()const - { - return domain_; - } - + const auto& dict()const { return dict_; } + const auto& domainBox()const + { + return domainBox_; + } + + const auto& Particles()const + { + return particles_; + } + + 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; + bool enterBroadSearch(uint32 iter, real t, real dt)const = 0; virtual - bool pwEnterBroadSearch()const = 0; - - virtual - bool ppPerformedBroadSearch()const = 0; - - virtual - bool pwPerformedBroadSearch()const = 0; - + bool performedBroadSearch()const = 0; static uniquePtr create( 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(2.0)); -} +using csExecutionSpace = DefaultExecutionSpace; + +using csIdType = uint32; + +using csPairContainerType = unsortedPairs; } -#endif +#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..9c8b3a29 --- /dev/null +++ b/src/Interaction/contactSearch/methods/cellBased/NBS/NBS.cpp @@ -0,0 +1,67 @@ +/*------------------------------- 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 +) +: + 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 + ) +{ +} 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..f0f83436 --- /dev/null +++ b/src/Interaction/contactSearch/methods/cellBased/NBS/NBS.hpp @@ -0,0 +1,148 @@ +/*------------------------------- 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); + + + 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..96e47917 --- /dev/null +++ b/src/Interaction/contactSearch/methods/cellBased/NBS/NBSLevel0.cpp @@ -0,0 +1,118 @@ +/*------------------------------- 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..5d85a118 --- /dev/null +++ b/src/Interaction/contactSearch/methods/cellBased/NBS/cellsWallLevel0.cpp @@ -0,0 +1,195 @@ +/*------------------------------- 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 +) +: + cellExtent_( max(cellExtent, 0.5 ) ), + numElements_(numElements), + numPoints_(numPoints), + vertices_(vertices), + points_(points) +{ + + allocateArrays(); +} + +bool pFlow::cellsWallLevel0::resetElements +( + uint32 numElements, + uint32 numPoints, + ViewType1D &points, + ViewType1D &vertices +) +{ + + numElements_ = numElements; + numPoints_ = numPoints; + points_ = points; + vertices_ = vertices; + + allocateArrays(); + + return true; +} + +bool pFlow::cellsWallLevel0::broadSearch +( + csPairContainerType &pairs, + const cells& searchBox, + const mapperNBS::CellIterator &particleMap +) +{ + + // map walls onto the cells + + this->build(searchBox); + + this->particleWallFindPairs(pairs, particleMap); + + 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 +) +{ + + uint32 getFull = 1; + + while (getFull) + { + + getFull = findPairsElementRangeCount(pairs, particleMap); + + 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."<(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..2ffb4414 --- /dev/null +++ b/src/Interaction/contactSearch/methods/cellBased/NBS/cellsWallLevel0.hpp @@ -0,0 +1,139 @@ +/*------------------------------- 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_; + + // 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); + + + + // - host call + // reset triangle elements if they have changed + bool resetElements( + uint32 numElements, + uint32 numPoints, + ViewType1D& points, + ViewType1D& vertices); + + + 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); + + + bool build(const cells& searchBox); + + bool particleWallFindPairs( + csPairContainerType& pairs, + const mapperNBS::CellIterator& particleMap); + + int32 findPairsElementRangeCount( + csPairContainerType& pairs, + const mapperNBS::CellIterator& particleMap); + + + +}; // 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..25064346 --- /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_ + ( + dict.getValOrSet("updateInterval", 1) + ) +{ + +} + +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..ec8938d7 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,14 @@ 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,22 +77,8 @@ public: const geometry& geom ), (control, prtcl, geom) - ); + ); - auto& contactSearchPtr() - { - return contactSearch_; - } - - auto& contactSearchRef() - { - return contactSearch_(); - } - - const auto& fileDict()const - { - return fileDict_; - } static uniquePtr create( diff --git a/src/Interaction/sphereInteraction/sphereInteraction.cpp b/src/Interaction/sphereInteraction/sphereInteraction.cpp index 0dacee74..1cb1472e 100644 --- a/src/Interaction/sphereInteraction/sphereInteraction.cpp +++ b/src/Interaction/sphereInteraction/sphereInteraction.cpp @@ -18,22 +18,18 @@ Licence: -----------------------------------------------------------------------------*/ -template< - typename contactForceModel, - typename geometryMotionModel, - template class contactListType > -bool pFlow::sphereInteraction:: - createSphereInteraction() +template class cLT> +bool pFlow::sphereInteraction::createSphereInteraction() { - realVector_D rhoD(this->densities()); + realVector_D rhoD("densities", this->densities()); - auto modelDict = this->fileDict().subDict("model"); + auto modelDict = this->subDict("model"); - REPORT(1)<<"Createing contact force model . . ."<( this->numMaterials(), - rhoD.deviceVector(), + rhoD.deviceView(), modelDict ); @@ -47,17 +43,9 @@ bool pFlow::sphereInteraction class contactListType > -bool pFlow::sphereInteraction:: - sphereSphereInteraction() +template class cLT> +bool pFlow::sphereInteraction::sphereSphereInteraction() { - - - auto lastItem = ppContactList_().loopCount(); // create the kernel functor @@ -66,17 +54,17 @@ bool pFlow::sphereInteractiondt(), 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() + 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 ); @@ -87,34 +75,32 @@ bool pFlow::sphereInteraction class contactListType > -bool pFlow::sphereInteraction:: - sphereWallInteraction() +template class cLT> +bool pFlow::sphereInteraction::sphereWallInteraction() { - int32 lastItem = pwContactList_().loopCount(); + uint32 lastItem = pwContactList_().loopCount(); + uint32 iter = this->currentIter(); real t = this->currentTime(); + real dt = this->dt(); pFlow::sphereInteractionKernels::pwInteractionFunctor pwInteraction( - this->dt(), + 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() + 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( @@ -127,4 +113,123 @@ bool pFlow::sphereInteraction 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)), + ppInteractionTimer_("sphere-sphere interaction", &this->timers()), + pwInteractionTimer_("sphere-wall interaction", &this->timers()), + contactListTimer_("contact list management", &this->timers()), + contactListTimer0_("contact list clear", &this->timers()) +{ + contactSearch_ = contactSearch::create( + subDict("contactSearch"), + prtcl.thisDomain().domainBox(), + prtcl, + geom, + 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 << " "< 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.hpp b/src/Interaction/sphereInteraction/sphereInteraction.hpp index b256c452..56c00047 100644 --- a/src/Interaction/sphereInteraction/sphereInteraction.hpp +++ b/src/Interaction/sphereInteraction/sphereInteraction.hpp @@ -23,7 +23,6 @@ Licence: #include "interaction.hpp" #include "sphereParticles.hpp" - #include "sphereInteractionKernels.hpp" namespace pFlow @@ -43,22 +42,19 @@ public: using ContactForceModel = contactForceModel; - using MotionModel = typename geometryMotionModel::MotionModel; + using MotionModel = typename geometryMotionModel::MotionModel; - using ModelStorage = typename ContactForceModel::contactForceStorage; + using ModelStorage = typename ContactForceModel::contactForceStorage; - using IdType = typename interaction::IdType; + using IdType = uint32; - using IndexType = typename interaction::IndexType; - - using ExecutionSpace = typename interaction::ExecutionSpace; + using IndexType = uint32; using ContactListType = - contactListType; + contactListType; - using PairsContainerType= typename contactSearch::PairContainerType; -protected: +private: /// const reference to geometry const GeometryMotionModel& geometryMotion_; @@ -66,15 +62,17 @@ protected: /// const reference to particles const sphereParticles& sphParticles_; + /// contact search object for pp and pw interactions + uniquePtr contactSearch_ = nullptr; /// contact force model - uniquePtr forceModel_ = nullptr; + uniquePtr forceModel_ = nullptr; /// contact list for particle-particle interactoins (keeps the history) - uniquePtr ppContactList_ = nullptr; + uniquePtr ppContactList_ = nullptr; /// contact list for particle-wall interactions (keeps the history) - uniquePtr pwContactList_ = nullptr; + uniquePtr pwContactList_ = nullptr; /// timer for particle-particle interaction computations Timer ppInteractionTimer_; @@ -82,42 +80,39 @@ protected: /// timer for particle-wall interaction computations Timer pwInteractionTimer_; + Timer contactListTimer_; + + Timer contactListTimer0_; + bool createSphereInteraction(); - bool managePPContactLists(); + bool sphereSphereInteraction(); - bool managePWContactLists(); + bool sphereWallInteraction(); + + //bool managePPContactLists(); + + //bool managePWContactLists(); /// range policy for p-p interaction execution using rpPPInteraction = - Kokkos::RangePolicy, Kokkos::Schedule>; + Kokkos::RangePolicy, Kokkos::Schedule>; /// range policy for p-w interaction execution using rpPWInteraction = rpPPInteraction; public: - TypeInfoTemplate3("sphereInteraction", ContactForceModel, MotionModel, ContactListType); - - // constructor + TypeInfoTemplate13("sphereInteraction", ContactForceModel, MotionModel, ContactListType); + /// Constructor from components 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; - } - } + const geometry& geom); + + /// Add virtual constructor add_vCtor ( interaction, @@ -125,97 +120,25 @@ public: 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; - 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()"< 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/sphereInteractions.cpp b/src/Interaction/sphereInteraction/sphereInteractions.cpp index 569fa7ad..1bd0da9c 100644 --- a/src/Interaction/sphereInteraction/sphereInteractions.cpp +++ b/src/Interaction/sphereInteraction/sphereInteractions.cpp @@ -28,22 +28,22 @@ Licence: template class pFlow::sphereInteraction< pFlow::cfModels::limitedLinearNormalRolling, - pFlow::fixedGeometry, + pFlow::stationaryGeometry, pFlow::unsortedContactList>; template class pFlow::sphereInteraction< pFlow::cfModels::limitedLinearNormalRolling, - pFlow::fixedGeometry, + pFlow::stationaryGeometry, pFlow::sortedContactList>; template class pFlow::sphereInteraction< pFlow::cfModels::nonLimitedLinearNormalRolling, - pFlow::fixedGeometry, + pFlow::stationaryGeometry, pFlow::unsortedContactList>; template class pFlow::sphereInteraction< pFlow::cfModels::nonLimitedLinearNormalRolling, - pFlow::fixedGeometry, + pFlow::stationaryGeometry, pFlow::sortedContactList>; template class pFlow::sphereInteraction< @@ -88,7 +88,7 @@ template class pFlow::sphereInteraction< pFlow::sortedContactList>; -template class pFlow::sphereInteraction< +/*template class pFlow::sphereInteraction< pFlow::cfModels::limitedLinearNormalRolling, pFlow::multiRotationAxisMotionGeometry, pFlow::unsortedContactList>; @@ -106,28 +106,28 @@ template class pFlow::sphereInteraction< template class pFlow::sphereInteraction< pFlow::cfModels::nonLimitedLinearNormalRolling, pFlow::multiRotationAxisMotionGeometry, - pFlow::sortedContactList>; + pFlow::sortedContactList>;*/ /// non-linear models template class pFlow::sphereInteraction< pFlow::cfModels::limitedNonLinearNormalRolling, - pFlow::fixedGeometry, + pFlow::stationaryGeometry, pFlow::unsortedContactList>; template class pFlow::sphereInteraction< pFlow::cfModels::limitedNonLinearNormalRolling, - pFlow::fixedGeometry, + pFlow::stationaryGeometry, pFlow::sortedContactList>; template class pFlow::sphereInteraction< pFlow::cfModels::nonLimitedNonLinearNormalRolling, - pFlow::fixedGeometry, + pFlow::stationaryGeometry, pFlow::unsortedContactList>; template class pFlow::sphereInteraction< pFlow::cfModels::nonLimitedNonLinearNormalRolling, - pFlow::fixedGeometry, + pFlow::stationaryGeometry, pFlow::sortedContactList>; template class pFlow::sphereInteraction< @@ -171,7 +171,7 @@ template class pFlow::sphereInteraction< pFlow::vibratingMotionGeometry, pFlow::sortedContactList>; -template class pFlow::sphereInteraction< +/*template class pFlow::sphereInteraction< pFlow::cfModels::limitedNonLinearNormalRolling, pFlow::multiRotationAxisMotionGeometry, pFlow::unsortedContactList>; @@ -189,28 +189,28 @@ template class pFlow::sphereInteraction< template class pFlow::sphereInteraction< pFlow::cfModels::nonLimitedNonLinearNormalRolling, pFlow::multiRotationAxisMotionGeometry, - pFlow::sortedContactList>; + pFlow::sortedContactList>;*/ // - nonLinearMod models template class pFlow::sphereInteraction< pFlow::cfModels::limitedNonLinearModNormalRolling, - pFlow::fixedGeometry, + pFlow::stationaryGeometry, pFlow::unsortedContactList>; template class pFlow::sphereInteraction< pFlow::cfModels::limitedNonLinearModNormalRolling, - pFlow::fixedGeometry, + pFlow::stationaryGeometry, pFlow::sortedContactList>; template class pFlow::sphereInteraction< pFlow::cfModels::nonLimitedNonLinearModNormalRolling, - pFlow::fixedGeometry, + pFlow::stationaryGeometry, pFlow::unsortedContactList>; template class pFlow::sphereInteraction< pFlow::cfModels::nonLimitedNonLinearModNormalRolling, - pFlow::fixedGeometry, + pFlow::stationaryGeometry, pFlow::sortedContactList>; template class pFlow::sphereInteraction< @@ -255,7 +255,7 @@ template class pFlow::sphereInteraction< pFlow::sortedContactList>; -template class pFlow::sphereInteraction< +/*template class pFlow::sphereInteraction< pFlow::cfModels::limitedNonLinearModNormalRolling, pFlow::multiRotationAxisMotionGeometry, pFlow::unsortedContactList>; @@ -274,3 +274,4 @@ template class pFlow::sphereInteraction< pFlow::cfModels::nonLimitedNonLinearModNormalRolling, pFlow::multiRotationAxisMotionGeometry, pFlow::sortedContactList>; +*/ \ No newline at end of file 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; iimpl_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> + +//#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,6 +196,63 @@ bool pFlow::sphereParticles::insertSphereParticles( return true; +}*/ + +bool pFlow::sphereParticles::initInertia() +{ + + 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."<( - 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 +362,17 @@ pFlow::sphereParticles::sphereParticles( fatalExit; } - if(rVelIntegration_->needSetInitialVals()) - { - - auto [minInd, maxInd] = pStruct().activeRange(); - int32IndexContainer indexHD(minInd, maxInd); + WARNING<<"setFields for rVelIntegration_"<setInitialVals(indexHD, rvel); - - } - - - if(!initializeParticles()) + if(!initInertia()) { + fatalErrorInFunction; fatalExit; } } -bool pFlow::sphereParticles::update(const eventMessage& msg) +/*bool pFlow::sphereParticles::update(const eventMessage& msg) { if(rVelIntegration_->needSetInitialVals()) @@ -350,7 +385,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; +} + + +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..f2ad5e48 100644 --- a/src/Particles/SphereParticles/sphereParticles/sphereParticles.hpp +++ b/src/Particles/SphereParticles/sphereParticles/sphereParticles.hpp @@ -44,22 +44,30 @@ class sphereParticles : public particles { -protected: +public: + using ShapeType = sphereShape; +private: - /// reference to material properties - const property& property_; + /// reference to shapes + ShapeType spheres_; - /// reference to shapes - sphereShape& shapes_; + /// property id on device + uint32PointField_D propertyId_; + + /// diameter / boundig sphere size of particles on device + realPointField_D diameter_; + + /// mass of particles field + realPointField_D mass_; /// pointField of inertial of particles - realPointField_D& I_; + realPointField_D I_; /// pointField of rotational Velocity of particles on device - realx3PointField_D& rVelocity_; + realx3PointField_D rVelocity_; /// pointField of rotational acceleration of particles on device - realx3PointField_D& rAcceleration_; + realx3PointField_D rAcceleration_; /// rotational velocity integrator uniquePtr rVelIntegration_ = nullptr; @@ -73,9 +81,9 @@ protected: /// timer for integration computations (correction step) Timer intCorrectTimer_; - bool diameterMassInertiaPropId(const word& shName, real& diam, real& mass, real& I, int8& propIdx); + bool initInertia(); - bool initializeParticles(); + /*bool initializeParticles(); bool insertSphereParticles( const wordVector& names, @@ -83,25 +91,17 @@ protected: bool setId = true); virtual uniquePtr> getFieldObjectList()const override; + */ public: /// construct from systemControl and property - sphereParticles(systemControl &control, const property& prop); + 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 @@ -112,17 +112,17 @@ public: * \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 ; + ) override ;*/ /// const reference to shapes object - const auto& shapes()const + const auto& spheres()const { - return shapes_; + return spheres_; } /// const reference to inertia pointField @@ -137,51 +137,75 @@ public: return I_; } - const realx3Vector_D rVelocity()const + const auto& rVelocity()const { return rVelocity_; } - const realVector_D& boundingSphere()const override - { - return this->diameter(); + auto& rVelocity() + { + 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; - realx3PointField_D& rAcceleration() override + const realPointField_D& diameter()const override { - return rAcceleration_; - } - - const realx3PointField_D& rAcceleration() const override - { - return rAcceleration_; + return diameter_; } + + const realPointField_D& mass()const override + { + return mass_; + } + /// before iteration step bool beforeIteration() override; /// iterate particles bool iterate() override; - /// after iteration step - bool afterIteration() override; + realx3PointField_D& rAcceleration() override + { + return rAcceleration_; + } + const realx3PointField_D& rAcceleration() const override + { + return rAcceleration_; + } + + const realPointField_D& boundingSphere()const override + { + return diameter(); + } + + word shapeTypeName()const override; + + const shape& getShapes()const override; + + + void boundingSphereMinMax(real & minDiam, real& maxDiam)const override; }; //sphereParticles 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..593ca168 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 -) +/*bool pFlow::dynamicPointStructure::beforeIteration() { - auto& pos = pStruct().pointPosition(); + pointStructure::beforeIteration(); + auto& acc = time().lookupObject("acceleration"); + return predict(dt(), acc); +}*/ - if(!integrationPos_().predict(dt, pos.VectorField(), velocity_.VectorField() ))return false; - if(!integrationVel_().predict(dt, velocity_.VectorField(), acceleration.VectorField()))return false; +/*bool pFlow::dynamicPointStructure::iterate() +{ + pointStructure::iterate(); + auto& acc = time().lookupObject("acceleration"); + return correct(dt(), acc); + +}*/ + +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,11 +129,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; } @@ -160,7 +152,7 @@ pFlow::uniquePtr pFlow::dynamicPointStructure::inser if(!integrationPos_().needSetInitialVals()) return newIndicesPtr; - auto hVel = velocity_.hostVector(); + auto hVel = velocity_.hostView(); auto n = newIndicesPtr().size(); auto index = newIndicesPtr().indicesHost(); @@ -178,7 +170,7 @@ pFlow::uniquePtr pFlow::dynamicPointStructure::inser }*/ -bool pFlow::dynamicPointStructure::update( +/*bool pFlow::dynamicPointStructure::update( const eventMessage& msg) { if( msg.isInsert()) @@ -197,8 +189,8 @@ bool pFlow::dynamicPointStructure::update( realx3Vector pos(n,RESERVE()); realx3Vector vel(n,RESERVE()); - const auto hVel = velocity().hostVector(); - const auto hPos = pStruct().pointPosition().hostVector(); + const auto hVel = velocity().hostView(); + const auto hPos = pStruct().pointPosition().hostView(); for(auto i=0; i 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(); - } + /// 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; + + - auto markDeleteOutOfBox(const box& domain) - { - return pStruct_.markDeleteOutOfBox(domain); - } bool predict(real dt, realx3PointField_D& acceleration); 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/baseShapeNames.cpp b/src/Particles/particles/baseShapeNames.cpp new file mode 100644 index 00000000..eaef39cb --- /dev/null +++ b/src/Particles/particles/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(id); +} - if( maxID != -1 && id.size() == 0 ) +pFlow::uniquePtr + pFlow::particleIdHandler::create(uint32PointField_D &id) +{ + word idHType = angleBracketsNames( + "particleIdHandler", + pFlowProcessors().localRunTypeName()); + + + if( pointFieldvCtorSelector_.search(idHType) ) { - nextId_ = 0; - } - else if( maxID == -1 && id.size()>0 ) - { - - nextId_ = 0; - id.modifyOnHost(); - - ForAll(i,id) - { - if(id.isActive(i)) - { - id[i] = getNextId(); - } - } - - id.syncViews(); - } - else if( maxID >= static_cast(id.size()) ) - { - nextId_ = maxID + 1; + REPORT(1)<<"Creating particle id handler "<< + Green_Text(idHType)< getIdRange(uint32 nNewParticles)=0; + + virtual + bool initialIdCheck()=0; + + static + uniquePtr create( + uint32PointField_D & id); + }; } diff --git a/src/Particles/particles/particles.cpp b/src/Particles/particles/particles.cpp index d5c3bb45..7b3a41d6 100644 --- a/src/Particles/particles/particles.cpp +++ b/src/Particles/particles/particles.cpp @@ -24,179 +24,97 @@ Licence: pFlow::particles::particles ( - systemControl& control, - const word& integrationMethod + systemControl &control ) -: - 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") - ) +: + observer(defaultMessage_), + demComponent("particles", control), + dynPointStruct_(control), + id_ + ( + objectFile + ( + "id", + "", + objectFile::READ_IF_PRESENT, + objectFile::WRITE_ALWAYS ), - 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 - ) + 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_( - control.time().emplaceObject( - objectFile( - "contactForce", - "", - objectFile::READ_IF_PRESENT, - objectFile::WRITE_ALWAYS - ), - pStruct(), - zero3 - ) - ), + objectFile( + "contactForce", + "", + objectFile::READ_IF_PRESENT, + objectFile::WRITE_ALWAYS), + dynPointStruct_, + zero3), contactTorque_( - control.time().emplaceObject( - objectFile( - "contactTorque", - "", - objectFile::READ_IF_PRESENT, - objectFile::WRITE_ALWAYS - ), - pStruct(), - zero3 - ) - ), - idHandler_(id_) + objectFile( + "contactTorque", + "", + objectFile::READ_IF_PRESENT, + objectFile::WRITE_ALWAYS), + dynPointStruct_, + zero3), + idHandler_(particleIdHandler::create(id_)) { - - this->subscribe(pStruct()); + this->addToSubscriber(dynPointStruct_); + + idHandler_().initialIdCheck(); } bool pFlow::particles::beforeIteration() { - auto domain = this->control().domain(); - - 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(); +} \ No newline at end of file diff --git a/src/Particles/particles/particles.hpp b/src/Particles/particles/particles.hpp index 7b207c50..8ba1cfce 100644 --- a/src/Particles/particles/particles.hpp +++ b/src/Particles/particles/particles.hpp @@ -23,57 +23,44 @@ Licence: #define __particles_hpp__ #include "dynamicPointStructure.hpp" +#include "demComponent.hpp" +#include "shape.hpp" #include "particleIdHandler.hpp" -#include "demParticles.hpp" + namespace pFlow { -class setFieldList; - class particles : - public eventObserver, - public demParticles + public observer, + public demComponent { -protected: +private: - // owner repository - Time& time_; - - const word integrationMethod_; - - // dynamic point structure for particles + /// dynamic point structure for particles center mass 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_; + /// id of particles on host + uint32PointField_D id_; - // - object handling particle id - particleIdHandler idHandler_; + uint32PointField_D shapeIndex_; - virtual uniquePtr> getFieldObjectList()const; + /// acceleration on device + realx3PointField_D accelertion_; + + /// contact force field + realx3PointField_D contactForce_; + + /// contact torque field + realx3PointField_D contactTorque_; + + uniquePtr idHandler_ = nullptr; + + static inline + const message defaultMessage_{message::DEFAULT}; + + void zeroForce() { @@ -85,173 +72,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_; - } +protected: inline auto& dynPointStruct() { return dynPointStruct_; } - inline const auto& pStruct()const{ - return dynPointStruct_.pStruct(); + inline auto& pointPosition() + { + return dynPointStruct_.pointPosition(); } - inline auto& pStruct(){ - return dynPointStruct_.pStruct(); + /*inline + auto& velocity() + { + return dynPointStruct_.velocity(); + }*/ + + inline + auto& shapeIndex() + { + return shapeIndex_; + } + +public: + + // type info + TypeInfo("particles"); + + explicit particles(systemControl& control); + + + inline + const auto& dynPointStruct()const + { + return dynPointStruct_; + } + + inline + const pointStructure& pStruct()const + { + return dynPointStruct_; + } + + inline + const auto& simDomain()const + { + return dynPointStruct_.simDomain(); + } + + inline + const auto& thisDomain()const + { + return dynPointStruct_.thisDomain(); } inline auto size()const{ - return pStruct().size(); + return dynPointStruct_.size(); } inline auto capacity() const{ - return pStruct().capacity(); - } - - inline auto activePointsMaskD()const{ - return pStruct().activePointsMaskD(); - } - - inline auto numActive()const - { - return pStruct().numActive(); + return dynPointStruct_.capacity(); } - 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 numActive()const { - return pStruct().pointPosition(); + return dynPointStruct_.numActive(); + } + + inline bool isAllActive()const + { + return dynPointStruct_.isAllActive(); } - inline const auto& pointVelocity()const{ - return dynPointStruct().velocity(); + inline + const auto& pointPosition()const + { + return dynPointStruct_.pointPosition(); } - inline const auto& velocity()const{ - return dynPointStruct().velocity(); + inline + const auto& velocity()const + { + return dynPointStruct_.velocity(); } - inline const auto& id()const{ - return id_; - } - - inline auto& id(){ - return id_; - } - - inline const auto& diameter()const{ - return diameter_; - } - - inline auto& diameter(){ - return diameter_; - } - - inline const auto& mass()const{ - return mass_; - } - - inline auto& mass() { - return mass_; - } - - inline const auto& accelertion()const{ - return accelertion_; - } - - inline auto& accelertion(){ + inline + const auto& accelertion()const + { return accelertion_; } inline - realx3PointField_D& contactForce() + auto& accelertion() + { + return accelertion_; + } + + inline + auto& contactForce() { return contactForce_; } inline - const realx3PointField_D& contactForce() const + const auto& contactForce() const { return contactForce_; } inline - realx3PointField_D& contactTorque() + auto& contactTorque() { return contactTorque_; } inline - const realx3PointField_D& contactTorque() const + const auto& contactTorque() const { return contactTorque_; } - inline const auto& propertyId()const{ - return propertyId_; - } - - inline auto& propertyId(){ - return propertyId_; - } - - inline const auto& shapeName()const{ - return shapeName_; - } - - inline auto& shapName(){ - return shapeName_; - } - bool beforeIteration() override; - virtual + bool iterate()override; + + bool afterIteration() override; + + /*virtual bool insertParticles ( const realx3Vector& position, const wordVector& shapes, const setFieldList& setField - ) = 0; + ) = 0;*/ + virtual + const uint32PointField_D& propertyId()const = 0; + virtual + const realPointField_D& diameter()const = 0; + + virtual + const realPointField_D& mass()const = 0; virtual realx3PointField_D& rAcceleration() = 0; @@ -260,11 +224,14 @@ public: const realx3PointField_D& rAcceleration() const = 0; virtual - const realVector_D& boundingSphere()const = 0; + const realPointField_D& boundingSphere()const = 0; virtual word shapeTypeName()const = 0; + virtual + const shape& getShapes()const = 0; + virtual void boundingSphereMinMax(real & minDiam, real& maxDiam)const = 0; diff --git a/src/Particles/particles/regularParticleHandler.cpp b/src/Particles/particles/regularParticleHandler.cpp new file mode 100644 index 00000000..429ac0b2 --- /dev/null +++ b/src/Particles/particles/regularParticleHandler.cpp @@ -0,0 +1,50 @@ +#include "regularParticleHandler.hpp" + + + +pFlow::regularParticleHandler::regularParticleHandler +( + uint32PointField_D & id +) +: + particleIdHandler(id) +{ +} + +pFlow::Pair + pFlow::regularParticleHandler::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::regularParticleHandler::initialIdCheck() +{ + /// empty point structure / no particles in simulation + if( id().pStruct().empty() ) return true; + + uint32 maxId = max(id()); + + /// particles should get ids from 0 to size-1 + if(maxId == -1) + { + fillSequence(id(),0u); + maxId_ = id().size()-1; + } + else + { + maxId_ = maxId; + } + + return true; +} diff --git a/src/Particles/particles/regularParticleHandler.hpp b/src/Particles/particles/regularParticleHandler.hpp new file mode 100644 index 00000000..9c4ee1dd --- /dev/null +++ b/src/Particles/particles/regularParticleHandler.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 __regularParticleHandler_hpp__ +#define __regularParticleHandler_hpp__ + +#include "particleIdHandler.hpp" + +namespace pFlow +{ + +class regularParticleHandler +: + public particleIdHandler +{ +private: + + uint32 maxId_ = -1; + +public: + + TypeInfo("particleIdHandler"); + + explicit regularParticleHandler(uint32PointField_D & id); + + ~regularParticleHandler()override = default; + + add_vCtor + ( + particleIdHandler, + regularParticleHandler, + pointField + ); + + Pair getIdRange(uint32 nNewParticles)override; + + bool initialIdCheck()override; + +}; + +} + + +#endif //__regularParticleHandler_hpp__ \ No newline at end of file diff --git a/src/Particles/particles/shape.cpp b/src/Particles/particles/shape.cpp new file mode 100644 index 00000000..bcf66e74 --- /dev/null +++ b/src/Particles/particles/shape.cpp @@ -0,0 +1,77 @@ +#include "shape.hpp" + + +bool pFlow::shape::findPropertyIds() +{ + shapePropertyIds_.resize(numShapes()); + + ForAll( i, materialNames_) + { + if(uint32 propId; property_.nameToIndex(materialNames_[i], propId) ) + { + shapePropertyIds_[i] = propId; + } + else + { + fatalErrorInFunction<<"Material name "<< materialNames_[i]<< + " is not valid in dictionary "<("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; + } + + 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-old.txt b/src/phasicFlow/CMakeLists-old.txt new file mode 100644 index 00000000..b6b68815 --- /dev/null +++ b/src/phasicFlow/CMakeLists-old.txt @@ -0,0 +1,87 @@ + +list(APPEND SourceFiles +types/basicTypes/bTypesFunctions.cpp +types/basicTypes/Logical.cpp +types/types.cpp + +globals/error.cpp + +streams/token/tokenIO.cpp +streams/token/token.cpp +streams/iStream/IOstream.cpp +streams/iStream/iIstream.cpp +streams/iStream/iOstream.cpp +streams/Stream/Istream.cpp +streams/Stream/Ostream.cpp +streams/Fstream/iFstream.cpp +streams/Fstream/oFstream.cpp +streams/Fstream/fileStream.cpp +streams/TStream/iTstream.cpp +streams/TStream/oTstream.cpp +streams/streams.cpp + +dictionary/dictionary.cpp +dictionary/entry/iEntry.cpp +dictionary/entry/dataEntry.cpp +dictionary/twoPartEntry/twoPartEntry.cpp + +fileSystem/fileSystem.cpp + +commandLine/commandLine.cpp + +random/randomReal/randomReal.cpp +random/randomReal/randomReals.cpp + +Timer/Timer.cpp +Timer/Timers.cpp + +repository/Time/Time.cpp +repository/Time/timeControl.cpp +repository/systemControl/systemControl.cpp +repository/systemControl/dynamicLinkLibs.cpp +repository/repository/repository.cpp +repository/IOobject/objectFile.cpp +repository/IOobject/IOobject.cpp +repository/IOobject/IOfileHeader.cpp + +structuredData/box/box.cpp +structuredData/cells/cells.cpp +structuredData/cylinder/cylinder.cpp +structuredData/sphere/sphere.cpp +structuredData/iBox/iBoxs.cpp +structuredData/line/line.cpp +structuredData/zAxis/zAxis.cpp +structuredData/pointStructure/pointStructure.cpp +structuredData/pointStructure/mortonIndexing.cpp +structuredData/pointStructure/selectors/pStructSelector/pStructSelector.cpp +structuredData/pointStructure/selectors/selectBox/selectBox.cpp +structuredData/pointStructure/selectors/selectRange/selectRange.cpp +structuredData/pointStructure/selectors/selectRandom/selectRandom.cpp +structuredData/trisurfaceStructure/triSurface.cpp +structuredData/trisurfaceStructure/multiTriSurface.cpp +structuredData/trisurfaceStructure/stlFile.cpp +structuredData/peakableRegion/sphereRegion/sphereRegion.cpp +structuredData/peakableRegion/cylinderRegion/cylinderRegion.cpp +structuredData/peakableRegion/boxRegion/boxRegion.cpp +structuredData/peakableRegion/peakableRegion/peakableRegion.cpp +structuredData/peakableRegion/peakableRegions.cpp + +containers/Vector/Vectors.cpp +containers/Field/Fields.cpp +containers/symArrayHD/symArrays.cpp +containers/triSurfaceField/triSurfaceFields.cpp +containers/bitsetHD/bitsetHDs.cpp +containers/indexContainer/indexContainer.cpp + +setFieldList/setFieldList.cpp +setFieldList/setFieldEntry.cpp + +eventSubscriber/eventSubscriber.cpp +eventSubscriber/eventObserver.cpp) + +set(link_libs Kokkos::kokkos tbb) + +pFlow_add_library_install(phasicFlow SourceFiles link_libs) + +target_include_directories(phasicFlow PUBLIC ./Kokkos ./algorithms ./globals) + diff --git a/src/phasicFlow/CMakeLists.txt b/src/phasicFlow/CMakeLists.txt index b6b68815..67ade22e 100644 --- a/src/phasicFlow/CMakeLists.txt +++ b/src/phasicFlow/CMakeLists.txt @@ -6,82 +6,142 @@ types/types.cpp globals/error.cpp +processors/processors.cpp +processors/localProcessors.cpp +processors/pFlowProcessors.cpp + streams/token/tokenIO.cpp streams/token/token.cpp streams/iStream/IOstream.cpp -streams/iStream/iIstream.cpp streams/iStream/iOstream.cpp -streams/Stream/Istream.cpp +streams/iStream/iIstream.cpp streams/Stream/Ostream.cpp -streams/Fstream/iFstream.cpp -streams/Fstream/oFstream.cpp -streams/Fstream/fileStream.cpp +streams/Stream/Istream.cpp +streams/processorOstream/processorOstream.cpp +streams/masterOstream/masterOstream.cpp streams/TStream/iTstream.cpp streams/TStream/oTstream.cpp +streams/Fstream/iFstream.cpp +streams/Fstream/oFstream.cpp +streams/Fstream/fileStream.cpp streams/streams.cpp +fileSystem/fileSystem.cpp + dictionary/dictionary.cpp +dictionary/fileDictionary.cpp dictionary/entry/iEntry.cpp dictionary/entry/dataEntry.cpp dictionary/twoPartEntry/twoPartEntry.cpp -fileSystem/fileSystem.cpp +repository/IOobject/objectFile.cpp +repository/IOobject/IOfileHeader.cpp +repository/IOobject/IOobject.cpp +repository/IOobject/IOPattern.cpp +repository/repository/repository.cpp +repository/Time/Time.cpp +repository/Time/timeControl.cpp +repository/Time/baseTimeControl.cpp +repository/systemControl/systemControl.cpp +repository/systemControl/dynamicLinkLibs.cpp commandLine/commandLine.cpp -random/randomReal/randomReal.cpp -random/randomReal/randomReals.cpp +eventManagement/subscriber.cpp +eventManagement/observer.cpp + +demComponent/demComponent.cpp Timer/Timer.cpp Timer/Timers.cpp -repository/Time/Time.cpp -repository/Time/timeControl.cpp -repository/systemControl/systemControl.cpp -repository/systemControl/dynamicLinkLibs.cpp -repository/repository/repository.cpp -repository/IOobject/objectFile.cpp -repository/IOobject/IOobject.cpp -repository/IOobject/IOfileHeader.cpp -structuredData/box/box.cpp -structuredData/cells/cells.cpp -structuredData/cylinder/cylinder.cpp -structuredData/sphere/sphere.cpp -structuredData/iBox/iBoxs.cpp -structuredData/line/line.cpp +containers/Vector/Vectors.cpp +containers/VectorHD/VectorSingles.cpp +containers/Field/Fields.cpp +containers/symArrayHD/symArrays.cpp +containers/List/anyList/anyList.cpp + +structuredData/pointStructure/internalPointsKernels.cpp +structuredData/pointStructure/internalPoints.cpp + structuredData/zAxis/zAxis.cpp +structuredData/box/box.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/boundaries/boundaryBase/boundaryBase.cpp +structuredData/boundaries/boundaryBase/boundaryBaseKernels.cpp +structuredData/boundaries/boundaryExit/boundaryExit.cpp +structuredData/boundaries/boundaryNone/boundaryNone.cpp +structuredData/boundaries/boundaryPeriodic/boundaryPeriodic.cpp +structuredData/boundaries/boundaryList.cpp structuredData/pointStructure/pointStructure.cpp -structuredData/pointStructure/mortonIndexing.cpp structuredData/pointStructure/selectors/pStructSelector/pStructSelector.cpp structuredData/pointStructure/selectors/selectBox/selectBox.cpp structuredData/pointStructure/selectors/selectRange/selectRange.cpp structuredData/pointStructure/selectors/selectRandom/selectRandom.cpp -structuredData/trisurfaceStructure/triSurface.cpp -structuredData/trisurfaceStructure/multiTriSurface.cpp -structuredData/trisurfaceStructure/stlFile.cpp -structuredData/peakableRegion/sphereRegion/sphereRegion.cpp -structuredData/peakableRegion/cylinderRegion/cylinderRegion.cpp -structuredData/peakableRegion/boxRegion/boxRegion.cpp -structuredData/peakableRegion/peakableRegion/peakableRegion.cpp -structuredData/peakableRegion/peakableRegions.cpp -containers/Vector/Vectors.cpp -containers/Field/Fields.cpp -containers/symArrayHD/symArrays.cpp +triSurface/subSurface.cpp +triSurface/triSurface.cpp +triSurface/multiTriSurface.cpp + +containers/pointField/pointFields.cpp containers/triSurfaceField/triSurfaceFields.cpp -containers/bitsetHD/bitsetHDs.cpp -containers/indexContainer/indexContainer.cpp setFieldList/setFieldList.cpp setFieldList/setFieldEntry.cpp -eventSubscriber/eventSubscriber.cpp -eventSubscriber/eventObserver.cpp) + + +) + +set(link_libs) set(link_libs Kokkos::kokkos tbb) + -pFlow_add_library_install(phasicFlow SourceFiles link_libs) -target_include_directories(phasicFlow PUBLIC ./Kokkos ./algorithms ./globals) +if(pFlow_Build_MPI) + + set(Zoltan_Install_DIR) + if(DEFINED ENV{Zoltan_DIR}) + set(Zoltan_Install_DIR $ENV{Zoltan_DIR}) + else() + set(Zoltan_Install_DIR $ENV{HOME}/PhasicFlow/Zoltan) + endif() + message(STATUS "Zoltan install directory is ${Zoltan_Install_DIR}") + + set(ZOLTAN_PREFIX "${Zoltan_Install_DIR}" CACHE STRING "Zoltan install directory") + + find_path(ZOLTAN_INCLUDE_DIR zoltan.h PATHS "${ZOLTAN_PREFIX}/include") + + message(STATUS "Zoltan include path: ${ZOLTAN_INCLUDE_DIR}") + + find_library(ZOLTAN_LIBRARY zoltan PATHS "${ZOLTAN_PREFIX}/lib") + message(STATUS "Zoltan lib path: ${ZOLTAN_LIBRARY}") + + list(APPEND SourceFiles + MPIParallelization/partitioning.cpp + MPIParallelization/rcb1DPartitioning.cpp + MPIParallelization/domain/MPISimulationDomain.cpp + #MPIParallelization/dataIOMPI.cpp + MPIParallelization/procCommunication.cpp + MPIParallelization/boundaryProcessor.cpp + MPIParallelization/scatteredMasterDistributeChar.cpp + MPIParallelization/processorBoundaryFields.cpp + ) + + list(APPEND link_libs MPI::MPI_CXX ${ZOLTAN_LIBRARY} -lm ) + pFlow_add_library_install(phasicFlow SourceFiles link_libs) + target_include_directories(phasicFlow PUBLIC ./globals ${ZOLTAN_INCLUDE_DIR}) + +else() + pFlow_add_library_install(phasicFlow SourceFiles link_libs) + target_include_directories(phasicFlow PUBLIC ./globals) +endif() + diff --git a/src/phasicFlow/Kokkos/KokkosTypes.hpp b/src/phasicFlow/Kokkos/KokkosTypes.hpp index 4f59872f..d58df4cb 100644 --- a/src/phasicFlow/Kokkos/KokkosTypes.hpp +++ b/src/phasicFlow/Kokkos/KokkosTypes.hpp @@ -17,133 +17,146 @@ Licence: implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -----------------------------------------------------------------------------*/ - #ifndef __KokkosTypes_hpp__ #define __KokkosTypes_hpp__ +/** + * \file KokkosType.hpp + * + * \brief name aliases and typedesf for Kokkos entities that are + * frequently used in PhasicFlow. + * + */ + #include #include #include -#include "iOstream.hpp" +#include "builtinTypes.hpp" namespace pFlow { -class DeviceSide{}; -class HostSide{}; -template -struct selectSide{}; +/// Host memory space +using HostSpace = Kokkos::HostSpace; -using HostSpace = Kokkos::HostSpace; -using Serial = Kokkos::Serial; +/// Serial execution space +using Serial = Kokkos::Serial; #ifdef _OPENMP -using OpenMP = Kokkos::OpenMP; +/// OpenMp execution space +using OpenMP = Kokkos::OpenMP; #endif +#ifdef __CUDACC__ +/// Cuda execution space +using Cuda = Kokkos::Cuda; +#endif + +/// 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; +using deviceRPolicyStatic = + Kokkos::RangePolicy< + Kokkos::DefaultExecutionSpace, + Kokkos::Schedule, + Kokkos::IndexType >; + +using hostRPolicyStatic = + Kokkos::RangePolicy< + Kokkos::DefaultExecutionSpace, + Kokkos::Schedule, + Kokkos::IndexType >; + + +/// Pair of two variables template - using kPair = Kokkos::pair; - -template - using kRange = kPair; - -using range = kRange; - -using range64 = kRange; +using Pair = Kokkos::pair; +/// View for a scalar template using ViewTypeScalar = Kokkos::View; +/// 1D veiw as a vector template using ViewType1D = Kokkos::View; +/// 2D view as an array template - using DualViewType1D = Kokkos::DualView; + using ViewType2D = Kokkos::View; +/// 3D view as an array template using ViewType3D = Kokkos::View; +/// 1D dual view as a vector +template + using DualViewType1D = Kokkos::DualView; + +/// unordered map template using unorderedMap = Kokkos::UnorderedMap; +/// unordered set template using unorderedSet = Kokkos::UnorderedMap; -template - using deviceHashMap= Kokkos::UnorderedMap; - -template - using hostHashMap= Kokkos::UnorderedMap; - -template - using deviceHashSet= Kokkos::UnorderedMap; - -template - using hostHashSet = Kokkos::UnorderedMap; - -// a 1D array (vector) with default device (memory space and execution space) +/// Scalar on device template 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; + + -// a 1D array (vector with host memeory space) template using hostViewTypeScalar = Kokkos::View; +/// 1D array (vector with host memeory space) template using hostViewType1D = Kokkos::View; +/// 2D array on host template using hostViewType2D = Kokkos::View; - -#ifdef __CUDACC__ -using Cuda = Kokkos::Cuda; -template - using cudaViewTypeScalar = Kokkos::View; - -template - using cudaViewType1D = Kokkos::View; - +/// 3D array on host template - using cudaViewType2D = Kokkos::View; -#endif - + using hostViewType3D = Kokkos::View; +/// 1D vector on device with atomic capabilities template using deviceAtomicViewType1D = Kokkos::View< T*, Kokkos::MemoryTraits::value?0:Kokkos::Atomic>>; +/// 3D array on device with atomic capabilities template using deviceAtomicViewType3D = Kokkos::View< T***, Kokkos::MemoryTraits::value?0:Kokkos::Atomic>>; -template -iOstream& operator <<(iOstream& os, const kRange& rng) -{ - os<<"["<::accessible; } +template +INLINE_FUNCTION_H +bool constexpr isDeviceAccessible() +{ + return Kokkos::SpaceAccessibility::accessible; +} + +/// Is MemoerySpace accessible from ExecutionSpace template INLINE_FUNCTION_H bool constexpr areAccessible() @@ -48,43 +58,63 @@ template < typename Type, typename... Properties> INLINE_FUNCTION_H -void realloc( ViewType1D& view, int32 len) +void reallocInit( ViewType1D& view, uint32 len) { - Kokkos::realloc(view, len); + Kokkos::realloc(Kokkos::WithoutInitializing, view, len); } template < typename Type, typename... Properties> INLINE_FUNCTION_H -void reallocNoInit(ViewType1D& view, int32 len) +void reallocNoInit(ViewType1D& view, uint32 len) { - using ViewType = ViewType1D; - word vl = view.label(); - view = ViewType(); // Deallocate first - view = ViewType( - Kokkos::view_alloc( - Kokkos::WithoutInitializing, - vl), - len); + Kokkos::realloc(Kokkos::WithoutInitializing, view, len); } template < typename Type, typename... Properties> INLINE_FUNCTION_H -void reallocFill( ViewType1D& view, int32 len, Type val) +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) +{ + Kokkos::realloc(view, len1, len2); +} template < typename Type, typename... Properties> INLINE_FUNCTION_H -void realloc( ViewType3D& view, int32 len1, int32 len2, int32 len3) +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) +{ + 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) { Kokkos::realloc(view, len1, len2, len3); } @@ -93,38 +123,107 @@ template < typename Type, typename... Properties> INLINE_FUNCTION_H -void reallocNoInit(ViewType3D& view, int32 len1, int32 len2, int32 len3) +void reallocNoInit(ViewType3D& view, uint32 len1, uint32 len2, uint32 len3) { - using ViewType = ViewType3D; - word vl = view.label(); - view = ViewType(); // Deallocate first - view = ViewType( - Kokkos::view_alloc( - Kokkos::WithoutInitializing, - vl), - len1, len2, len3); + + Kokkos::realloc(Kokkos::WithoutInitializing, view, len1, len2, len3); } template < typename Type, typename... Properties> INLINE_FUNCTION_H -void reallocFill( ViewType3D& view, int32 len1, int32 len2, int32 len3, Type val) +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) +{ + Kokkos::resize(view, newLen); +} + +template < + typename Type, + typename... Properties> +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) { - auto tmp = v1; - v1 = v2; - v2 = tmp; + static_assert( + std::is_move_assignable::value && std::is_move_constructible::value, + "swapViews arguments must be move assignable and move constructible"); + + ViewType tmp = std::move(v1); + v1 = std::move(v2); + v2 = std::move(tmp); } + +template +INLINE_FUNCTION_H +iOstream& operator <<(iOstream& os, const Pair& p) +{ + os<<'('< +INLINE_FUNCTION_H +span makeSpan(ViewType1D & v) +{ + return span(v.data(), v.size()); +} + +template +INLINE_FUNCTION_H +span makeSpan(ViewType1D & v, uint32 size) +{ + return span(v.data(), size); +} + +template +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) +{ + return span(const_cast(v.data()), size); +} + + +template +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"); + + span spn(v.data(), v.size()); + os< + +#include "pFlowMacros.hpp" +#include "typeInfo.hpp" +#include "builtinTypes.hpp" +#include "iOstream.hpp" + + +namespace pFlow +{ + + +/** + * Range for elements in an vector [start,end) + * + */ +template +struct Range +: +public Kokkos::pair +{ + using Pair = Kokkos::pair; + + TypeInfoTemplateNV11("Range", T) + + //// - Constructors + + /// Default + INLINE_FUNCTION_HD + Range(){} + + /// 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 pair + INLINE_FUNCTION_HD + Range(const Range::Pair &src ) + : + Range::Pair(src) + {} + + /// Copy + INLINE_FUNCTION_HD + Range(const Range&) = default; + + /// Move + INLINE_FUNCTION_HD + Range(Range&&) = default; + + /// Copy assignment + INLINE_FUNCTION_HD + Range& operator=(const 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; + } + + /// End + INLINE_FUNCTION_HD + T& end() + { + return this->second; + } + + INLINE_FUNCTION_HD + const T& start()const + { + return this->first; + } + + 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); + } + +}; + +template +INLINE_FUNCTION_H +iOstream& operator <<(iOstream& os, const Range& rng) +{ + os<<"["<; + +using range64 = Range; + +using rangeU32 = Range; + +using rangeU64 = Range; + + +} // pFlow + +#endif //__KokkosTypes_hpp__ diff --git a/src/phasicFlow/Kokkos/ViewAlgorithms.hpp b/src/phasicFlow/Kokkos/ViewAlgorithms.hpp index 2e94cc3c..d765e014 100644 --- a/src/phasicFlow/Kokkos/ViewAlgorithms.hpp +++ b/src/phasicFlow/Kokkos/ViewAlgorithms.hpp @@ -23,7 +23,9 @@ Licence: #include "numericConstants.hpp" +#include "Range.hpp" #include "KokkosUtilities.hpp" + #include "kokkosAlgorithms.hpp" #include "stdAlgorithms.hpp" #include "cudaAlgorithms.hpp" @@ -31,36 +33,25 @@ Licence: namespace pFlow { - -inline const size_t maxSizeToSerial__ = 64; - template INLINE_FUNCTION_H -int32 count( +uint32 count( const ViewType1D& view, - int32 start, - int32 end, + uint32 start, + uint32 end, const T& val) { + using ExecutionSpace = typename ViewType1D::execution_space; - int32 numElems = end-start; + uint32 numElems = end-start; - if constexpr( isHostAccessible()) - { - if(numElems( - view.data()+start, - numElems, - val); - } - } - - return pFlow::algorithms::KOKKOS::count( - view.data()+start, - numElems, - val); + return pFlow::algorithms::KOKKOS::count + ( + view.data()+start, + numElems, + val + ); } template @@ -68,40 +59,66 @@ INLINE_FUNCTION_H void fill ( ViewType1D& view, - range span, + rangeU32 span, T val ) { - using ExecutionSpace = typename ViewType1D::execution_space; - - - if constexpr( isHostAccessible()) + using exe_space = typename ViewType1D::execution_space; + auto subV = Kokkos::subview(view, span.getPair() ); + if constexpr ( std::is_trivially_copyable_v) { - int32 numElems = span.second-span.first; - if( numElems()) + { + for(auto i=span.start(); i( - view.data()+span.first, - numElems, - val); - return; + view[i] = val; } } - - auto subV = Kokkos::subview(view, span); - Kokkos::deep_copy(subV, val); + else + { + static_assert("fill is not valid for non-trivially-copyable data type"); + } + } template void fill ( ViewType1D& view, - int32 start, - int32 end, + uint32 start, + uint32 end, T val ) { - fill(view, range(start,end),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 +( + ViewType3D& view, + const T& val +) +{ + static_assert(std::is_trivially_copyable_v, "Not valid type for fill"); + Kokkos::deep_copy(view, val); } template< @@ -109,26 +126,14 @@ template< typename... properties> void fillSequence( ViewType1D& view, - int32 start, - int32 end, + uint32 start, + uint32 end, const Type startVal ) { - + static_assert(std::is_trivially_copyable_v, "Not valid type for fill"); using ExecutionSpace = typename ViewType1D::execution_space; - int32 numElems = end-start; - - if constexpr( isHostAccessible()) - { - if(numElems( - view.data()+start, - numElems, - startVal); - return ; - } - } + uint32 numElems = end-start; pFlow::algorithms::KOKKOS::fillSequence( view.data()+start, @@ -144,38 +149,32 @@ template< typename... properties, typename indexType, typename... indexProperties> -bool fillSelected( +bool fillSelected +( ViewType1D view, - const ViewType1D indices, - const int32 numElems, - const Type val, - typename std::enable_if_t< - areAccessible< - typename ViewType1D::execution_space, - typename ViewType1D::memory_space>(), - bool> = true ) + ViewType1D indices, + uint32 numElems, + Type val +) { - using ExecutionSpace = typename ViewType1D::execution_space; - - if constexpr( isHostAccessible()) - { - if(numElems( - view.data(), - indices.data(), - numElems, - val); - return true; - } - } + 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"); - pFlow::algorithms::KOKKOS::fillSelected( - view.data(), - indices.data(), - numElems, - val); + using ExSpace = typename ViewType1D::execution_space; + using policy = Kokkos::RangePolicy >; + + Kokkos::parallel_for( + "ViewAlgorithms::fillSelected", + policy(0,numElems), + LAMBDA_HD(uint32 i){ + //view[indices[i]]= val; + }); + Kokkos::fence(); return true; } @@ -185,39 +184,21 @@ template< typename... properties, typename indexType, typename... indexProperties> - //typename valType> //, - //typename... valProperties> bool fillSelected( ViewType1D view, const ViewType1D indices, - const ViewType1D vals, - const int32 numElems , - typename std::enable_if_t< - areAccessible< + const ViewType1D vals, + const uint32 numElems ) +{ + static_assert(std::is_trivially_copyable_v, "Not valid type for fillSelected"); + static_assert( + areAccessible< typename ViewType1D::execution_space, typename ViewType1D::memory_space>(), - bool> = true ) -{ + "In fillSelected arguments view and indices must have similar spaces"); using ExecutionSpace = typename ViewType1D::execution_space; - - - if constexpr( isHostAccessible()) - { - if(numElems( - view.data(), - indices.data(), - vals.data(), - numElems - ); - return true; - } - } - - pFlow::algorithms::KOKKOS::fillSelected( view.data(), indices.data(), @@ -233,26 +214,15 @@ template INLINE_FUNCTION_H T min( const ViewType1D& view, - int32 start, - int32 end) + uint32 start, + uint32 end) { using ExecutionSpace = typename ViewType1D::execution_space; - int32 numElems = end-start; - - if constexpr( isHostAccessible()) - { - if(numElems( - view.data()+start, - numElems); - } - } - - return + uint32 numElems = end-start; + + return pFlow::algorithms::KOKKOS::min( view.data()+start, numElems); @@ -262,24 +232,13 @@ template INLINE_FUNCTION_H T max( const ViewType1D& view, - int32 start, - int32 end) + uint32 start, + uint32 end) { using ExecutionSpace = typename ViewType1D::execution_space; - int32 numElems = end-start; - - if constexpr( isHostAccessible()) - { - if(numElems( - view.data()+start, - numElems); - } - } + uint32 numElems = end-start; return pFlow::algorithms::KOKKOS::max( @@ -309,15 +268,15 @@ template < INLINE_FUNCTION_H void copy( const ViewType1D& dst, - int32 dStart, + uint32 dStart, const ViewType1D& src, - int32 sStart, - int32 sEnd + uint32 sStart, + uint32 sEnd ) { - range sSpan(sStart,sEnd); - range dSpan(dStart,dStart+(sEnd-sStart)); + range32 sSpan(sStart,sEnd); + range32 dSpan(dStart,dStart+(sEnd-sStart)); auto srcSub = Kokkos::subview(src, sSpan); auto dstSub = Kokkos::subview(dst, dSpan); @@ -326,19 +285,19 @@ void copy( } template < - typename dType, - typename sType, + typename Type, typename... sProperties> INLINE_FUNCTION_H void getNth( - dType& dst, - const ViewType1D& src, - const int32 n + Type& dst, + const ViewType1D& src, + const uint32 n ) { - range span(n,n+1); - auto subV = Kokkos::subview(src, span); - hostViewType1D dstView("getNth",1); + + auto subV = Kokkos::subview(src, Kokkos::make_pair(n,n+1)); + hostViewType1D dstView("getNth",1); + //hostViewTypeScalar Kokkos::deep_copy(dstView,subV); dst = *dstView.data(); } @@ -348,30 +307,19 @@ template INLINE_FUNCTION_H void sort( ViewType1D& view, - int32 start, - int32 end) + uint32 start, + uint32 end) { - using ExecutionSpace = typename ViewType1D::execution_space; - int32 numElems = end-start; + uint32 numElems = end-start; if constexpr( isHostAccessible()) - { - if(numElems( - view.data()+start, - numElems); - return; - } - else - { - pFlow::algorithms::STD::sort( - view.data()+start, - numElems); - return; - } + { + pFlow::algorithms::STD::sort( + view.data()+start, + numElems); + return; } #ifdef __CUDACC__ @@ -391,33 +339,22 @@ template INLINE_FUNCTION_H void sort( ViewType1D& view, - int32 start, - int32 end, + uint32 start, + uint32 end, CompareFunc compare) { using ExecutionSpace = typename ViewType1D::execution_space; - int32 numElems = end-start; + uint32 numElems = end-start; if constexpr( isHostAccessible()) { - if(numElems( - view.data()+start, - numElems, - compare); - return; - } - else - { - pFlow::algorithms::STD::sort( - view.data()+start, - numElems, - compare); - return; - } + pFlow::algorithms::STD::sort( + view.data()+start, + numElems, + compare); + return; } #ifdef __CUDACC__ @@ -441,40 +378,28 @@ template< typename... permProperties> void permuteSort( const ViewType1D& view, - int32 start, - int32 end, + uint32 start, + uint32 end, ViewType1D& permuteView, - int32 permStart, - typename std::enable_if_t< + uint32 permStart ) +{ + static_assert( areAccessible< typename ViewType1D::execution_space, typename ViewType1D::memory_space>(), - bool> = true ) -{ + "In permuteSort, view and permuteView should have the same space"); + using ExecutionSpace = typename ViewType1D::execution_space; - int32 numElems = end-start; - - if constexpr( isHostAccessible()) - { - if(numElems( - view.data()+start, - permuteView.data()+permStart, - numElems ); - return; - } - else - { - pFlow::algorithms::STD::permuteSort( - view.data()+start, - permuteView.data()+permStart, - numElems); - return; - } - } + uint32 numElems = end-start; + + pFlow::algorithms::STD::permuteSort( + view.data()+start, + permuteView.data()+permStart, + numElems); + return; + #ifdef __CUDACC__ pFlow::algorithms::CUDA::permuteSort( @@ -488,21 +413,52 @@ void permuteSort( } +template +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; + + 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( +uint32 binarySearch( const ViewType1D& view, - int32 start, - int32 end, + uint32 start, + uint32 end, const Type& val) { if(end<=start)return -1; if(auto res = - pFlow::algorithms::binarySearch(view.data()+start,end-start,val); res>=0) { + binarySearch_(view.data()+start,end-start,val); res!=-1) { return res+start; } else{ @@ -513,36 +469,29 @@ int32 binarySearch( template< typename Type, typename... properties, - typename dType, typename... dProperties> void exclusiveScan( const ViewType1D& view, - int32 start, - int32 end, - ViewType1D& dView, - int32 dStart, - typename std::enable_if_t< + uint32 start, + uint32 end, + ViewType1D& dView, + uint32 dStart ) +{ + + static_assert + ( areAccessible< typename ViewType1D::execution_space, - typename ViewType1D::memory_space>(), - bool> = true ) -{ + typename ViewType1D::memory_space>(), + "In exclusiveScan, view and dView should have the same space" + + ); + using ExecutionSpace = typename ViewType1D::execution_space; - int32 numElems = end-start; - if constexpr( isHostAccessible()) - { - if(numElems( - view.data()+start, - dView.data()+dStart, - numElems); - return; - } - } - - pFlow::algorithms::KOKKOS::exclusiveScan( + uint32 numElems = end-start; + + pFlow::algorithms::KOKKOS::exclusiveScan( view.data()+start, dView.data()+dStart, numElems); @@ -552,36 +501,28 @@ void exclusiveScan( template< typename Type, typename... properties, - typename dType, typename... dProperties> void inclusiveScan( const ViewType1D& view, - int32 start, - int32 end, - ViewType1D& dView, - int32 dStart, - typename std::enable_if_t< - areAccessible< - typename ViewType1D::execution_space, - typename ViewType1D::memory_space>(), - bool> = true ) + uint32 start, + uint32 end, + ViewType1D& dView, + uint32 dStart) { using ExecutionSpace = typename ViewType1D::execution_space; - int32 numElems = end-start; - if constexpr( isHostAccessible()) - { - if(numElems( - view.data()+start, - dView.data()+dStart, - numElems); - return; - } - } + static_assert + ( + areAccessible< + typename ViewType1D::execution_space, + typename ViewType1D::memory_space>(), + "In exclusiveScan, view and dView should have the same space" + ); - pFlow::algorithms::KOKKOS::inclusiveScan( + + uint32 numElems = end-start; + + pFlow::algorithms::KOKKOS::inclusiveScan( view.data()+start, dView.data()+dStart, numElems); diff --git a/src/phasicFlow/Kokkos/baseAlgorithmsFwd.hpp b/src/phasicFlow/Kokkos/baseAlgorithmsFwd_.hpp similarity index 100% rename from src/phasicFlow/Kokkos/baseAlgorithmsFwd.hpp rename to src/phasicFlow/Kokkos/baseAlgorithmsFwd_.hpp diff --git a/src/phasicFlow/Kokkos/baseAlgorithms.hpp b/src/phasicFlow/Kokkos/baseAlgorithms_.hpp similarity index 96% rename from src/phasicFlow/Kokkos/baseAlgorithms.hpp rename to src/phasicFlow/Kokkos/baseAlgorithms_.hpp index 70f1f76f..0c887ae4 100644 --- a/src/phasicFlow/Kokkos/baseAlgorithms.hpp +++ b/src/phasicFlow/Kokkos/baseAlgorithms_.hpp @@ -213,17 +213,6 @@ void insertSetElementD } -/*template -void fill -( - ViewType1D& view, - range range, - T val -) -{ - auto subV = Kokkos::subview(view, range); - Kokkos::deep_copy(subV, val); -}*/ template diff --git a/src/Geometry/geometryMotion/geometryMotionsInstantiate.cpp b/src/phasicFlow/Kokkos/phasicFlowKokkos.hpp similarity index 72% rename from src/Geometry/geometryMotion/geometryMotionsInstantiate.cpp rename to src/phasicFlow/Kokkos/phasicFlowKokkos.hpp index a8ec4fd9..3372ba8a 100644 --- a/src/Geometry/geometryMotion/geometryMotionsInstantiate.cpp +++ b/src/phasicFlow/Kokkos/phasicFlowKokkos.hpp @@ -18,15 +18,13 @@ Licence: -----------------------------------------------------------------------------*/ -#include "fixedWall.hpp" -#include "rotatingAxisMotion.hpp" -#include "multiRotatingAxisMotion.hpp" -#include "vibratingMotion.hpp" +#ifndef __phsicFlowKokkos_hpp__ +#define __phsicFlowKokkos_hpp__ -template class pFlow::geometryMotion; +#include "KokkosTypes.hpp" +#include "KokkosUtilities.hpp" +#include "ViewAlgorithms.hpp" +#include "Range.hpp" -template class pFlow::geometryMotion; -template class pFlow::geometryMotion; - -template class pFlow::geometryMotion; +#endif // __phsicFlowKokkos_hpp__ diff --git a/src/phasicFlow/Timer/Timer.cpp b/src/phasicFlow/Timer/Timer.cpp index 9a4546e4..424addec 100644 --- a/src/phasicFlow/Timer/Timer.cpp +++ b/src/phasicFlow/Timer/Timer.cpp @@ -22,7 +22,7 @@ Licence: #include "Timers.hpp" #include "streams.hpp" -pFlow::Timer::Timer(const word name, Timers* parrent) +pFlow::Timer::Timer(const word& name, Timers* parrent) : name_(name), parrent_(parrent) diff --git a/src/phasicFlow/Timer/Timer.hpp b/src/phasicFlow/Timer/Timer.hpp index 4c731444..ac32ba35 100644 --- a/src/phasicFlow/Timer/Timer.hpp +++ b/src/phasicFlow/Timer/Timer.hpp @@ -63,15 +63,15 @@ public: TypeInfo("Timer"); - Timer(){} + Timer() = default; - Timer(const word name) + explicit Timer(const word& name) : name_(name) {} - Timer(const word name, Timers* parrent); + Timer(const word& name, Timers* parrent); const word& name()const diff --git a/src/phasicFlow/algorithms/algorithmFunctions.hpp b/src/phasicFlow/algorithms/algorithmFunctions.hpp index 44778caf..0ce97355 100644 --- a/src/phasicFlow/algorithms/algorithmFunctions.hpp +++ b/src/phasicFlow/algorithms/algorithmFunctions.hpp @@ -60,37 +60,6 @@ struct minimum return lhs < rhs ? lhs : rhs; } }; - -template -INLINE_FUNCTION_HD -int binarySearch(const T* array, int length, const T& val) -{ - - int low = 0; - int high = length - 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; - } - } - - return -1; // val not found in array[0, length) -} - - } #endif // __algorithmFunctions_hpp__ \ No newline at end of file diff --git a/src/phasicFlow/algorithms/kokkosAlgorithms.hpp b/src/phasicFlow/algorithms/kokkosAlgorithms.hpp index 218e6e6d..6102dd7a 100644 --- a/src/phasicFlow/algorithms/kokkosAlgorithms.hpp +++ b/src/phasicFlow/algorithms/kokkosAlgorithms.hpp @@ -30,15 +30,15 @@ namespace pFlow::algorithms::KOKKOS template INLINE_FUNCTION_H -int32 count(const Type* first, int32 numElems, const Type& val) +uint32 count(const Type* first, uint32 numElems, const Type& val) { using policy = Kokkos::RangePolicy< ExecutionSpace, - Kokkos::IndexType >; - int32 num = 0; + Kokkos::IndexType >; + uint32 num = 0; Kokkos::parallel_reduce("count", policy(0, numElems), - LAMBDA_HD(int32 i, int32& updateVal){ + LAMBDA_HD(uint32 i, uint32& updateVal){ if(equal(first[i],val)) updateVal++; }, num); @@ -50,17 +50,17 @@ int32 count(const Type* first, int32 numElems, const Type& val) template INLINE_FUNCTION_H -void fillSequence(Type* first, int32 numElems, const Type& firstVal) +void fillSequence(Type* first, uint32 numElems, const Type& firstVal) { using policy = Kokkos::RangePolicy< ExecutionSpace, - Kokkos::IndexType >; + Kokkos::IndexType >; Kokkos::parallel_for( "fillSequence", policy(0, numElems), - LAMBDA_HD(int32 i){ + LAMBDA_HD(uint32 i){ first[i] = firstVal+i; }); Kokkos::fence(); @@ -68,15 +68,15 @@ void fillSequence(Type* first, int32 numElems, const Type& firstVal) template INLINE_FUNCTION_H -void fillSelected(Type* first, const indexType* indices, const int32 numElems, const Type val) +void fillSelected(Type* first, const indexType* indices, const uint32 numElems, const Type val) { using policy = Kokkos::RangePolicy< ExecutionSpace, - Kokkos::IndexType >; + Kokkos::IndexType >; Kokkos::parallel_for( "fillSelected", policy(0,numElems), - LAMBDA_HD(int32 i){ + LAMBDA_HD(uint32 i){ first[indices[i]]= val; }); Kokkos::fence(); @@ -84,16 +84,16 @@ void fillSelected(Type* first, const indexType* indices, const int32 numElems, c template INLINE_FUNCTION_H -void fillSelected(Type* first, const indexType* indices, const Type* vals, const int32 numElems) +void fillSelected(Type* first, const indexType* indices, const Type* vals, const uint32 numElems) { using policy = Kokkos::RangePolicy< ExecutionSpace, - Kokkos::IndexType >; + Kokkos::IndexType >; Kokkos::parallel_for( "fillSelected", policy(0,numElems), - LAMBDA_HD(int32 i){ + LAMBDA_HD(uint32 i){ first[indices[i]]= vals[i]; }); Kokkos::fence(); @@ -101,17 +101,17 @@ void fillSelected(Type* first, const indexType* indices, const Type* vals, const template INLINE_FUNCTION_H -Type max(const Type* first, int32 numElems) +Type max(const Type* first, uint32 numElems) { using policy = Kokkos::RangePolicy< ExecutionSpace, - Kokkos::IndexType >; + Kokkos::IndexType >; Type maxElement=0; Kokkos::parallel_reduce( "max", policy(0, numElems), - LAMBDA_HD(int32 i, Type& maxUpdate){ + LAMBDA_HD(uint32 i, Type& maxUpdate){ if(maxUpdate(maxElement)); @@ -144,38 +144,38 @@ Type min(const Type* first, int32 numElems) //void sort(Type* first, int32 numElems, CompareFunc compare); //void permuteSort(const Type* first, PermuteType* pFirst, int32 numElems); -template -void exclusiveScan(Type* first, DestType* dFirst, int32 numElems) +template +void exclusiveScan(Type* first, Type* dFirst, uint32 numElems) { using policy = Kokkos::RangePolicy< ExecutionSpace, - Kokkos::IndexType >; + Kokkos::IndexType >; Kokkos::parallel_scan( "exclusiveScan", policy(0, numElems), - LAMBDA_HD(const int32 i, DestType& valToUpdate, const bool final) + LAMBDA_HD(const uint32 i, Type& valToUpdate, const bool final) { - const int32 val = first[i]; + const Type val = first[i]; if(final) dFirst[i] = valToUpdate; valToUpdate += val; }); } -template -void inclusiveScan(Type* first, DestType* dFirst, int32 numElems) +template +void inclusiveScan(Type* first, Type* dFirst, uint32 numElems) { using policy = Kokkos::RangePolicy< ExecutionSpace, - Kokkos::IndexType >; + Kokkos::IndexType >; Kokkos::parallel_scan( "inclusiveScan", policy(0, numElems), - LAMBDA_HD(const int32 i, int32& valToUpdate, const bool final) + LAMBDA_HD(const uint32 i, Type& valToUpdate, const bool final) { - const int32 val = first[i]; + const Type val = first[i]; valToUpdate += val; if(final) dFirst[i] = valToUpdate; diff --git a/src/phasicFlow/commandLine/CLI/Validators.hpp b/src/phasicFlow/commandLine/CLI/Validators.hpp index 03eb77b6..ffddd84b 100644 --- a/src/phasicFlow/commandLine/CLI/Validators.hpp +++ b/src/phasicFlow/commandLine/CLI/Validators.hpp @@ -11,7 +11,7 @@ #include "TypeTools.hpp" // [CLI11:public_includes:set] -#include +#include "math.hpp" #include #include #include diff --git a/src/phasicFlow/commandLine/commandLine.cpp b/src/phasicFlow/commandLine/commandLine.cpp index d2002570..f9d82161 100644 --- a/src/phasicFlow/commandLine/commandLine.cpp +++ b/src/phasicFlow/commandLine/commandLine.cpp @@ -38,10 +38,10 @@ pFlow::commandLine::commandLine(word appName, word disptn) CLI::App::add_flag_callback( "--description", [disptn, appName]() { - output<<"\n"<configurable(false); diff --git a/src/phasicFlow/containers/Field/Field.cpp b/src/phasicFlow/containers/Field/Field.cpp index 5569ea9b..335fbe49 100644 --- a/src/phasicFlow/containers/Field/Field.cpp +++ b/src/phasicFlow/containers/Field/Field.cpp @@ -18,7 +18,120 @@ Licence: -----------------------------------------------------------------------------*/ -template class VectorField, class T, class PropType> +template +bool pFlow::Field::read +( + iIstream& is +) +{ + + bool tokenFound = true; + + tokenFound = is.findToken(fieldKey_); + + if( !tokenFound ) + { + ioErrorInFile( is.name(), is.lineNumber() ) << + " error in searching for filedkey " << fieldKey_<name()< +bool pFlow::Field::read +( + iIstream& is, + const IOPattern& iop +) +{ + + bool tokenFound = true; + + if(iop.thisProcReadData()) + tokenFound = is.findToken(fieldKey_); + + if( !tokenFound ) + { + ioErrorInFile( is.name(), is.lineNumber() ) << + " error in searching for filedkey " << fieldKey_<name()< +bool pFlow::Field::write +( + iOstream& os +)const +{ + + os.writeWordKeyword(fieldKey_)< +bool pFlow::Field::write +( + iOstream& os, + const IOPattern& iop +)const +{ + + if(iop.thisProcWriteData()) + os.writeWordKeyword(fieldKey_)< class VectorField, class T, class PropType> bool pFlow::Field::readUniform ( iIstream& is, @@ -94,10 +207,10 @@ bool pFlow::Field::readNonUniform return true; -} +}*/ -template class VectorField, class T, class PropType> +/*template class VectorField, class T, class PropType> bool pFlow::Field::readField ( iIstream& is, @@ -178,5 +291,4 @@ bool pFlow::Field::writeField(iOstream& os)const os.endEntry(); return true; -} - +}*/ diff --git a/src/phasicFlow/containers/Field/Field.hpp b/src/phasicFlow/containers/Field/Field.hpp index 1a0f2448..887b994d 100644 --- a/src/phasicFlow/containers/Field/Field.hpp +++ b/src/phasicFlow/containers/Field/Field.hpp @@ -21,226 +21,198 @@ Licence: #ifndef __Field_hpp__ #define __Field_hpp__ + +#include "types.hpp" #include "VectorSingle.hpp" -#include "vocabs.hpp" +#include "Vector.hpp" +#include "streams.hpp" namespace pFlow { - -template class VectorField, class T, class PropType=void> +template class Field : - public VectorField + public VectorSingle { public: - - using VectorType = VectorField; + using VectorType = VectorSingle; - using FieldType = Field; + using FieldType = Field; - using iterator = typename VectorType::iterator; + using FieldTypeHost = Field; - using constIterator = typename VectorType::constIterator; + using memory_space = typename VectorType::memory_space; - using reference = typename VectorType::reference; + using execution_space = typename VectorType::execution_space; + + using iterator = typename VectorType::iterator; + + using const_iterator = typename VectorType::const_iterator; + + using reference = typename VectorType::reference; - using constReference = typename VectorType::constReference; + using const_reference = typename VectorType::const_reference; - using valueType = typename VectorType::valueType; + using value_type = typename VectorType::value_type; - using pointer = typename VectorType::pointer; + using pointer = typename VectorType::pointer; - using constPointer = typename VectorType::constPointer; + using const_pointer = typename VectorType::const_pointer; -protected: +private: static const inline word FKey = "value"; const word fieldKey_ = FKey; - bool readUniform( iIstream& is, size_t len, bool readLength = true); - - bool readNonUniform( iIstream& is, size_t len); - public: - // - type info - TypeInfoTemplateNV2("Field", T, VectorType::memoerySpaceName()); + /// type info + TypeInfoTemplateNV111("Field", T, VectorType::memoerySpaceName()); //// - Constructors - // construct an empty Filed with default fieldKey + /// construct an empty Filed with default fieldKey Field() : VectorType() {} - // construct an empty Field with fieldKey - Field(const word& fieldKey) + Field(const word& name) : - VectorType(), - fieldKey_(fieldKey) + VectorType(name) {} - // construct an empty field with name and fieldKey + /// Construct an empty field with name and fieldKey Field(const word& name, const word& fieldKey) : VectorType(name), fieldKey_(fieldKey) {} - - // construct an empty Filed with default fieldKey - Field(size_t len) - : - VectorType(len) - {} - - // construct an empty Field with fieldKey - Field(const word& fieldKey, size_t len) - : - VectorType(len), - fieldKey_(fieldKey) - {} - - // construct an empty field with name and fieldKey + + /// Construct a field with name and fieldKey and specified len Field(const word& name, const word& fieldKey, size_t len) : VectorType(name, len), fieldKey_(fieldKey) {} - // construct an empty Filed with default fieldKey and set vector to val - Field(size_t len, const T& val) - : - VectorType(len, val) - {} - - // construct an empty Field with fieldKey and set vector to val - Field(const word& fieldKey, size_t len, const T& val) - : - VectorType(len, val), - fieldKey_(fieldKey) - {} - - // construct an empty field with name and fieldKey and set vector to val + + /// Construct a field with name, fieldKey and + /// set length to len and value to val Field(const word& name, const word& fieldKey, size_t len, const T& val) : VectorType(name, len, val), fieldKey_(fieldKey) {} - // construct a field with capacity and len and default fieldKey - Field(size_t capacity, size_t len, RESERVE) + Field(const word& name, const word& fieldKey, size_t capacity, size_t len, const T& val) : - VectorType(capacity, len, RESERVE()) - {} - - // construct an empty Field with fieldKey - Field(const word& fieldKey, size_t capacity, size_t len, RESERVE) - : - VectorType(capacity, len, RESERVE()), + VectorType(name, len, len, RESERVE()), fieldKey_(fieldKey) - {} + { + VectorType::fill(val); + } - // construct an empty field with name and fieldKey + /// Construct a field with name, fieldKey, capacity and len Field(const word& name, const word& fieldKey, size_t capacity, size_t len, RESERVE) : VectorType(name, capacity, len, RESERVE()), fieldKey_(fieldKey) {} - // construct with vec and default fieldKey - Field(const Vector& vec) - : - VectorType(vec) - {} - - // construct an empty Field with fieldKey + /// Construct a field with fieldKey and Vector vec Field(const word& fieldKey, const Vector& vec) : - VectorType(vec), + VectorType(vec.name(), vec.vectorField()), fieldKey_(fieldKey) {} - // construct an empty field with name and fieldKey + /// Construct a field with name, fieldKey and Vector vec Field(const word& name, const word& fieldKey, const Vector& vec) + : + VectorType(name, vec.vectorField()), + fieldKey_(fieldKey) + {} + + /// Construct a field with name and fieldKey and std::vector + Field(const word& name, const word& fieldKey, const std::vector& vec) : VectorType(name, vec), fieldKey_(fieldKey) {} - - // - copy construct with new name and fieldkey + /// Copy construct with new name and fieldkey Field(const word& name, const word& fieldKey, const FieldType& src): VectorType(name, src), fieldKey_(fieldKey) {} - // - default copy constructor + /// Default copy constructor Field(const FieldType&) = default; - // - default copy assignment - FieldType& operator = (const FieldType&) = default; - - // - no move constructor - Field(FieldType&&) = delete; - - // - no move assignment - FieldType& operator = (FieldType&&) = delete; - - // - clone as a uniquePtr - INLINE_FUNCTION_H - uniquePtr clone() const + /// Copy assignment, name and fieldKey + /// on the left hand side are preserved + FieldType& operator = (const FieldType& rhs) { - return makeUnique(*this); + if(&rhs == this) return *this; + VectorType::operator=(rhs); + return *this; } - // - clone as a raw pointer - INLINE_FUNCTION_H - FieldType* clonePtr()const - { - return new FieldType(*this); - } + /// Move constructor + Field(FieldType&&) = default; + + /// Move assignment + FieldType& operator = (FieldType&&) = default; //// - Methods - const word& fieldKey()const + /// return field key + word fieldKey()const { return fieldKey_; } - + + word name()const + { + return VectorType::name(); + } + + + void fillField(rangeU32 span, const T& val) + { + this->fill(span, val); + } + + void fillField(const T& val) + { + this->fill(val); + } + //// - IO operations - bool readField(iIstream& is, const size_t len, bool resume, bool readLength = true); + bool read(iIstream& is); - bool readField(iIstream& is, bool resume ); + bool write(iOstream& os)const; - - bool writeField(iOstream& os)const; + bool read(iIstream& is, const IOPattern& iop); - bool read(iIstream& is, bool resume = false) - { - return readField(is, resume); - } - bool write(iOstream& os)const - { - return writeField(os); - } - + bool write(iOstream& os, const IOPattern& iop )const; }; -template class VectorField, class T, class PropType> -inline iIstream& operator >> (iIstream & is, Field & ifld ) +template +inline iIstream& operator >> (iIstream & is, Field & ifld ) { - if( !ifld.readField(is, false) ) + if( !ifld.read(is, IOPattern::MasterProcessorOnly) ) { ioErrorInFile (is.name(), is.lineNumber()); fatalExit; @@ -248,11 +220,11 @@ inline iIstream& operator >> (iIstream & is, Field & i return is; } -template class VectorField, class T, class PropType> -inline iOstream& operator << (iOstream& os, const Field& ofld ) +template +inline iOstream& operator << (iOstream& os, const Field& ofld ) { - if( !ofld.writeField(os) ) + if( !ofld.write(os, IOPattern::AllProcessorsDifferent) ) { ioErrorInFile(os.name(), os.lineNumber()); fatalExit; diff --git a/src/phasicFlow/containers/Field/Fields.cpp b/src/phasicFlow/containers/Field/Fields.cpp index 28779371..55337632 100644 --- a/src/phasicFlow/containers/Field/Fields.cpp +++ b/src/phasicFlow/containers/Field/Fields.cpp @@ -21,61 +21,17 @@ Licence: #include "Fields.hpp" -template class pFlow::Field; +template class pFlow::Field; -template class pFlow::Field; +template class pFlow::Field; -template class pFlow::Field; +template class pFlow::Field; -template class pFlow::Field; +template class pFlow::Field; -template class pFlow::Field; +template class pFlow::Field; -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; - -template class pFlow::Field; +template class pFlow::Field; -template class pFlow::Field>; - diff --git a/src/phasicFlow/containers/Field/Fields.hpp b/src/phasicFlow/containers/Field/Fields.hpp index 8b2ff92c..a0b8d192 100644 --- a/src/phasicFlow/containers/Field/Fields.hpp +++ b/src/phasicFlow/containers/Field/Fields.hpp @@ -24,73 +24,58 @@ Licence: #include "types.hpp" #include "Field.hpp" #include "VectorSingle.hpp" -#include "VectorDual.hpp" +//#include "VectorDual.hpp" namespace pFlow { +using int8Field_D = Field; -using int8Field_D = Field; +using int8Field_H = Field; -using int8Field_H = Field; +using int32Field_D = Field; -using int16Field_D = Field; +using int32Field_H = Field; -using int16Field_H = Field; +using int64Field_D = Field; -using int32Field_D = Field; +using int64Field_H = Field; -using int32Field_H = Field; +using uint8Field_D = Field; -using int64Field_D = Field; +using uint8Field_H = Field; -using int64Field_H = Field; +using uint32Field_D = Field; -using uint32Field_D = Field; +using uint32Field_H = Field; -using uint32Field_H = Field; +using uint64Field_D = Field; -using labelField_D = Field; +using uint64Field_H = Field ; -using labelField_H = Field ; +using uint32x3Field_D = Field; -using realField_D = Field; +using uint32x3Field_H = Field; -using realField_H = Field ; +using realField_D = Field; -using realx3Field_D = Field; +using realField_H = Field ; -using realx3Field_H = Field; +using realx3Field_D = Field; -using uint16x3Field_D = Field; +using realx3Field_H = Field; -using uint16x3Field_H = Field; +using realx3x3Field_D = Field; -using uint32x3Field_D = Field; - -using uint32x3Field_H = Field; - -using int32x3Field_D = Field; - -using int32x3Field_H = Field; - -using int64x3Field_D = Field; - -using int64x3Field_H = Field; - -using realx3x3Field_D = Field; - -using realx3x3Field_H = Field; +using realx3x3Field_H = Field; // - no typedef on device (since word does not compile on CUDA) -using wordField_H = Field; +using wordField_H = Field; // host device fields -using int8Field_HD = Field; - -using int16Field_HD = Field; +/*using int8Field_HD = Field; using int32Field_HD = Field; @@ -104,20 +89,13 @@ using realField_HD = Field; using realx3Field_HD = Field; -using uint16x3Field_HD = Field; - using uint32x3Field_HD = Field; using int32x3Field_HD = Field; using int64x3Field_HD = Field; -using realx3x3Field_HD = Field; - - -using wordField = Field>; - - +using realx3x3Field_HD = Field;*/ } diff --git a/src/phasicFlow/containers/List/List/List.hpp b/src/phasicFlow/containers/List/List/List.hpp index e416ae92..ca39e1e9 100644 --- a/src/phasicFlow/containers/List/List/List.hpp +++ b/src/phasicFlow/containers/List/List/List.hpp @@ -49,11 +49,11 @@ public: using iterator = typename listType::iterator; - using constIterator = typename listType::const_iterator; + using const_iterator = typename listType::const_iterator; using reference = typename listType::reference; - using constReference= typename listType::const_reference; + using const_reference= typename listType::const_reference; using initList = typename std::initializer_list; @@ -62,12 +62,7 @@ public: protected: - // position of ith element - auto pos(size_t i); - - // position of ith element - const auto pos(size_t i)const; - + static inline size_t getListStride(const size_t& len) { size_t stride = 1; @@ -86,7 +81,7 @@ protected: public: // - Type info - TypeInfoTemplateNV("List", T); + TypeInfoTemplateNV11("List", T); //// - Constructors @@ -114,30 +109,19 @@ public: // - copy construct - List(const List& src): - listType(src) - {} + List(const List& src) = default; + // - move construct - List( List && mv) - : - listType(std::move(mv)) - {} - + List( List && mv) = default; + // - copy assignment - ListType& operator=(const ListType& rhs) - { - listType::operator=(rhs); - return *this; - } + ListType& operator=(const ListType& rhs) = default; + // - move assignment - ListType& operator=(ListType&& rhs) - { - listType::operator=(std::move(rhs)); - return *this; - } - + ListType& operator=(ListType&& rhs) = default; + uniquePtr clone()const{ return makeUnique(*this); @@ -162,6 +146,12 @@ public: // - size of container size_t size()const; + // position of ith element + auto pos(size_t i, bool noError = false); + + // position of ith element + const auto pos(size_t i, bool noError = false)const; + // - access to ith element // fatal exit if out of range T& operator[](size_t i); @@ -172,7 +162,7 @@ public: // - find the position of the first element with value val // cend() if not found - constIterator find(const T& val) const; + const_iterator find(const T& val) const; // - find the position of the first element with value val // end() if not found @@ -227,9 +217,8 @@ iIstream& operator >>(iIstream& is, List& lst); using int64List = List; using int32List = List; -using int16List = List; using int8List = List; -using labelList = List