mirror of
https://github.com/PhasicFlow/phasicFlow.git
synced 2025-06-12 16:26:23 +00:00
src folder
This commit is contained in:
@ -6,6 +6,7 @@ project(phasicFlow VERSION 0.1 )
|
|||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||||
set(CMAKE_INSTALL_PREFIX ${phasicFlow_SOURCE_DIR} CACHE PATH "Install path of phasicFlow" FORCE)
|
set(CMAKE_INSTALL_PREFIX ${phasicFlow_SOURCE_DIR} CACHE PATH "Install path of phasicFlow" FORCE)
|
||||||
|
set(CMAKE_BUILD_TYPE Release CACHE STRING "build type" FORCE)
|
||||||
|
|
||||||
message(STATUS ${CMAKE_INSTALL_PREFIX})
|
message(STATUS ${CMAKE_INSTALL_PREFIX})
|
||||||
|
|
||||||
@ -13,24 +14,26 @@ mark_as_advanced(FORCE var Kokkos_ENABLE_CUDA_LAMBDA)
|
|||||||
mark_as_advanced(FORCE var Kokkos_ENABLE_OPENMP)
|
mark_as_advanced(FORCE var Kokkos_ENABLE_OPENMP)
|
||||||
mark_as_advanced(FORCE var Kokkos_ENABLE_SERIAL)
|
mark_as_advanced(FORCE var Kokkos_ENABLE_SERIAL)
|
||||||
mark_as_advanced(FORCE var Kokkos_ENABLE_CUDA_LAMBDA)
|
mark_as_advanced(FORCE var Kokkos_ENABLE_CUDA_LAMBDA)
|
||||||
|
mark_as_advanced(FORCE var BUILD_SHARED_LIBS)
|
||||||
|
|
||||||
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
|
|
||||||
option(USE_STD_PARALLEL_ALG "Use TTB std parallel algorithms" ON)
|
option(USE_STD_PARALLEL_ALG "Use TTB std parallel algorithms" ON)
|
||||||
option(pFlow_Build_Serial "Build phasicFlow and backends for serial execution" ON)
|
option(pFlow_Build_Serial "Build phasicFlow and backends for serial execution" ON)
|
||||||
option(pFlow_Build_OpenMP "Build phasicFlow and backends for OpenMP 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_Cuda "Build phasicFlow and backends for Cuda execution" OFF)
|
||||||
|
|
||||||
if(dFlow_Build_Serial)
|
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_SERIAL ON CACHE BOOL "Serial execution" FORCE)
|
||||||
set(Kokkos_ENABLE_OPENMP OFF CACHE BOOL "OpenMP 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 OFF CACHE BOOL "Cuda execution" FORCE)
|
||||||
set(Kokkos_ENABLE_CUDA_LAMBDA OFF CACHE BOOL "Cuda execution" FORCE)
|
set(Kokkos_ENABLE_CUDA_LAMBDA OFF CACHE BOOL "Cuda execution" FORCE)
|
||||||
elseif(dFlow_Build_OpenMP )
|
elseif(pFlow_Build_OpenMP )
|
||||||
set(Kokkos_ENABLE_SERIAL ON CACHE BOOL "Serial execution" FORCE)
|
set(Kokkos_ENABLE_SERIAL ON CACHE BOOL "Serial execution" FORCE)
|
||||||
set(Kokkos_ENABLE_OPENMP ON CACHE BOOL "OpenMP 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 OFF CACHE BOOL "Cuda execution" FORCE)
|
||||||
set(Kokkos_ENABLE_CUDA_LAMBDA OFF CACHE BOOL "Cuda execution" FORCE)
|
set(Kokkos_ENABLE_CUDA_LAMBDA OFF CACHE BOOL "Cuda execution" FORCE)
|
||||||
elseif(dFlow_Build_Cuda)
|
elseif(pFlow_Build_Cuda)
|
||||||
set(Kokkos_ENABLE_SERIAL ON CACHE BOOL "Serial execution" FORCE)
|
set(Kokkos_ENABLE_SERIAL ON CACHE BOOL "Serial execution" FORCE)
|
||||||
set(Kokkos_ENABLE_OPENMP OFF CACHE BOOL "OpenMP 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 ON CACHE BOOL "Cuda execution" FORCE)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
export pFlow_PROJECT_VERSION=v0.1
|
export pFlow_PROJECT_VERSION=v0.1
|
||||||
|
|
||||||
export pFlow_PROJECT=phasicFlow-$pFlow_PROJECT_VERSION
|
export pFlow_PROJECT=phasicFlow
|
||||||
|
|
||||||
|
|
||||||
projectDir="$HOME/PhasicFlow"
|
projectDir="$HOME/PhasicFlow"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#add a library to dFlow with source files and target_link_libs (thouse under the main CMakeLists.txt)
|
#add a library to pFlow with source files and target_link_libs (thouse under the main CMakeLists.txt)
|
||||||
macro(pFlow_make_executable_install target_name source_files target_link_libs)
|
macro(pFlow_make_executable_install target_name source_files target_link_libs)
|
||||||
|
|
||||||
# add library
|
# add library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#add a library to dFlow with source files and target_link_libs (thouse under the main CMakeLists.txt)
|
#add a library to pFlow with source files and target_link_libs (thouse under the main CMakeLists.txt)
|
||||||
macro(pFlow_add_library_install target_name src_files target_link_libs)
|
macro(pFlow_add_library_install target_name src_files target_link_libs)
|
||||||
|
|
||||||
set(source_files ${${src_files}})
|
set(source_files ${${src_files}})
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
|
|
||||||
add_subdirectory(phasicFlow)
|
add_subdirectory(phasicFlow)
|
||||||
|
|
||||||
#add_subdirectory(Integration)
|
add_subdirectory(Integration)
|
||||||
|
|
||||||
#add_subdirectory(Property)
|
add_subdirectory(Property)
|
||||||
|
|
||||||
#add_subdirectory(Particles)
|
add_subdirectory(Particles)
|
||||||
|
|
||||||
#add_subdirectory(Interaction)
|
add_subdirectory(Interaction)
|
||||||
|
|
||||||
#add_subdirectory(MotionModel)
|
add_subdirectory(MotionModel)
|
||||||
|
|
||||||
#add_subdirectory(Geometry)
|
add_subdirectory(Geometry)
|
||||||
|
|
||||||
|
12
src/Geometry/CMakeLists.txt
Normal file
12
src/Geometry/CMakeLists.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
list(APPEND SourceFiles
|
||||||
|
geometry/geometry.C
|
||||||
|
geometryMotion/geometryMotions.C
|
||||||
|
)
|
||||||
|
|
||||||
|
set(link_libs Kokkos::kokkos phasicFlow MotionModel Property)
|
||||||
|
|
||||||
|
pFlow_add_library_install(Geometry SourceFiles link_libs)
|
||||||
|
|
||||||
|
|
||||||
|
|
47
src/Geometry/geometry/demGeometry.H
Normal file
47
src/Geometry/geometry/demGeometry.H
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*------------------------------- 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 __demGeometry_H__
|
||||||
|
#define __demGeometry_H__
|
||||||
|
|
||||||
|
#include "demComponent.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
class demGeometry
|
||||||
|
:
|
||||||
|
public demComponent
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
demGeometry(systemControl& control)
|
||||||
|
:
|
||||||
|
demComponent("geometry", control)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
316
src/Geometry/geometry/geometry.C
Normal file
316
src/Geometry/geometry/geometry.C
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
/*------------------------------- 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 "geometry.H"
|
||||||
|
#include "vocabs.H"
|
||||||
|
|
||||||
|
|
||||||
|
bool pFlow::geometry::findPropertyId()
|
||||||
|
{
|
||||||
|
|
||||||
|
int8Vector propId(0, surface().capacity(),RESERVE());
|
||||||
|
propId.clear();
|
||||||
|
|
||||||
|
uint32 pId;
|
||||||
|
forAll(matI, materialName_)
|
||||||
|
{
|
||||||
|
|
||||||
|
if( !wallProperty_.nameToIndex( materialName_[matI], pId ) )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"material name for the geometry is invalid: "<< materialName_[matI]<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 surfSize = surface().surfNumTriangles(matI);
|
||||||
|
|
||||||
|
for(int32 i=0; i<surfSize; i++)
|
||||||
|
{
|
||||||
|
propId.push_back(pId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
propertyId_.assign(propId);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pFlow::geometry::geometry
|
||||||
|
(
|
||||||
|
systemControl& control,
|
||||||
|
const property& prop
|
||||||
|
)
|
||||||
|
:
|
||||||
|
demGeometry(control),
|
||||||
|
wallProperty_(prop),
|
||||||
|
geometryRepository_(control.geometry()),
|
||||||
|
triSurface_(
|
||||||
|
control.geometry().emplaceObject<multiTriSurface>(
|
||||||
|
objectFile(
|
||||||
|
"triSurface",
|
||||||
|
"",
|
||||||
|
objectFile::READ_ALWAYS,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
motionComponentName_(
|
||||||
|
control.geometry().emplaceObject<wordField>(
|
||||||
|
objectFile(
|
||||||
|
"motionComponentName",
|
||||||
|
"",
|
||||||
|
objectFile::READ_ALWAYS,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
),
|
||||||
|
"motionNamesList"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
materialName_(
|
||||||
|
control.geometry().emplaceObject<wordField>(
|
||||||
|
objectFile(
|
||||||
|
"materialName",
|
||||||
|
"",
|
||||||
|
objectFile::READ_ALWAYS,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
),
|
||||||
|
"materialNamesList"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
propertyId_(
|
||||||
|
control.geometry().emplaceObject<int8TriSurfaceField_D>(
|
||||||
|
objectFile(
|
||||||
|
"propertyId",
|
||||||
|
"",
|
||||||
|
objectFile::READ_NEVER,
|
||||||
|
objectFile::WRITE_NEVER),
|
||||||
|
surface(),
|
||||||
|
0 ) ),
|
||||||
|
contactForceWall_(
|
||||||
|
control.geometry().emplaceObject<realx3TriSurfaceField_D>(
|
||||||
|
objectFile(
|
||||||
|
"contactForceWall",
|
||||||
|
"",
|
||||||
|
objectFile::READ_IF_PRESENT,
|
||||||
|
objectFile::WRITE_ALWAYS),
|
||||||
|
surface(),
|
||||||
|
zero3) ),
|
||||||
|
stressWall_(
|
||||||
|
control.geometry().emplaceObject<realx3TriSurfaceField_D>(
|
||||||
|
objectFile(
|
||||||
|
"stressWall",
|
||||||
|
"",
|
||||||
|
objectFile::READ_IF_PRESENT,
|
||||||
|
objectFile::WRITE_ALWAYS),
|
||||||
|
surface(),
|
||||||
|
zero3) )
|
||||||
|
{
|
||||||
|
|
||||||
|
if(!findPropertyId())
|
||||||
|
{
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pFlow::geometry::geometry
|
||||||
|
(
|
||||||
|
systemControl& control,
|
||||||
|
const property& prop,
|
||||||
|
const multiTriSurface& triSurface,
|
||||||
|
const wordVector& motionCompName,
|
||||||
|
const wordVector& matName
|
||||||
|
)
|
||||||
|
:
|
||||||
|
demGeometry(control),
|
||||||
|
wallProperty_(prop),
|
||||||
|
geometryRepository_(control.geometry()),
|
||||||
|
triSurface_(
|
||||||
|
control.geometry().emplaceObject<multiTriSurface>(
|
||||||
|
objectFile(
|
||||||
|
"triSurface",
|
||||||
|
"",
|
||||||
|
objectFile::READ_NEVER,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
),
|
||||||
|
triSurface
|
||||||
|
)
|
||||||
|
),
|
||||||
|
motionComponentName_(
|
||||||
|
control.geometry().emplaceObject<wordField>(
|
||||||
|
objectFile(
|
||||||
|
"motionComponentName",
|
||||||
|
"",
|
||||||
|
objectFile::READ_NEVER,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
),
|
||||||
|
"motionNamesList",
|
||||||
|
motionCompName
|
||||||
|
)
|
||||||
|
),
|
||||||
|
materialName_(
|
||||||
|
control.geometry().emplaceObject<wordField>(
|
||||||
|
objectFile(
|
||||||
|
"materialName",
|
||||||
|
"",
|
||||||
|
objectFile::READ_NEVER,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
),
|
||||||
|
"materialNamesList",
|
||||||
|
matName
|
||||||
|
)
|
||||||
|
),
|
||||||
|
propertyId_(
|
||||||
|
control.geometry().emplaceObject<int8TriSurfaceField_D>(
|
||||||
|
objectFile(
|
||||||
|
"propertyId",
|
||||||
|
"",
|
||||||
|
objectFile::READ_NEVER,
|
||||||
|
objectFile::WRITE_NEVER),
|
||||||
|
surface(),
|
||||||
|
0 ) ),
|
||||||
|
contactForceWall_(
|
||||||
|
control.geometry().emplaceObject<realx3TriSurfaceField_D>(
|
||||||
|
objectFile(
|
||||||
|
"contactForceWall",
|
||||||
|
"",
|
||||||
|
objectFile::READ_IF_PRESENT,
|
||||||
|
objectFile::WRITE_ALWAYS),
|
||||||
|
surface(),
|
||||||
|
zero3) ),
|
||||||
|
stressWall_(
|
||||||
|
control.geometry().emplaceObject<realx3TriSurfaceField_D>(
|
||||||
|
objectFile(
|
||||||
|
"stressWall",
|
||||||
|
"",
|
||||||
|
objectFile::READ_IF_PRESENT,
|
||||||
|
objectFile::WRITE_ALWAYS),
|
||||||
|
surface(),
|
||||||
|
zero3) )
|
||||||
|
{
|
||||||
|
if(!findPropertyId())
|
||||||
|
{
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pFlow::geometry::geometry
|
||||||
|
(
|
||||||
|
systemControl& control,
|
||||||
|
const property& prop,
|
||||||
|
const dictionary& dict,
|
||||||
|
const multiTriSurface& triSurface,
|
||||||
|
const wordVector& motionCompName,
|
||||||
|
const wordVector& matName
|
||||||
|
)
|
||||||
|
:
|
||||||
|
geometry(control, prop, triSurface, motionCompName, matName)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
pFlow::uniquePtr<pFlow::geometry>
|
||||||
|
pFlow::geometry::create
|
||||||
|
(
|
||||||
|
systemControl& control,
|
||||||
|
const property& prop
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//motionModelFile__
|
||||||
|
auto motionDictPtr = IOobject::make<dictionary>
|
||||||
|
(
|
||||||
|
objectFile
|
||||||
|
(
|
||||||
|
motionModelFile__,
|
||||||
|
control.geometry().path(),
|
||||||
|
objectFile::READ_ALWAYS,
|
||||||
|
objectFile::WRITE_NEVER
|
||||||
|
),
|
||||||
|
motionModelFile__,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
word model = motionDictPtr().getObject<dictionary>().getVal<word>("motionModel");
|
||||||
|
|
||||||
|
auto geomModel = angleBracketsNames("geometry", model);
|
||||||
|
|
||||||
|
Report(1)<< "Selecting geometry model . . ."<<endReport;
|
||||||
|
if( systemControlvCtorSelector_.search(geomModel) )
|
||||||
|
{
|
||||||
|
auto objPtr = systemControlvCtorSelector_[geomModel] (control, prop);
|
||||||
|
Report(2)<<"Model "<< greenText(geomModel)<<" is created.\n"<<endReport;
|
||||||
|
return objPtr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printKeys
|
||||||
|
(
|
||||||
|
fatalError << "Ctor Selector "<< yellowText(geomModel) << " dose not exist. \n"
|
||||||
|
<<"Avaiable ones are: \n\n"
|
||||||
|
,
|
||||||
|
systemControlvCtorSelector_
|
||||||
|
);
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
pFlow::uniquePtr<pFlow::geometry>
|
||||||
|
pFlow::geometry::create(
|
||||||
|
systemControl& control,
|
||||||
|
const property& prop,
|
||||||
|
const dictionary& dict,
|
||||||
|
const multiTriSurface& triSurface,
|
||||||
|
const wordVector& motionCompName,
|
||||||
|
const wordVector& propName)
|
||||||
|
{
|
||||||
|
|
||||||
|
word model = dict.getVal<word>("motionModel");
|
||||||
|
|
||||||
|
auto geomModel = angleBracketsNames("geometry", model);
|
||||||
|
|
||||||
|
Report(1)<< "Selecting geometry model . . ."<<endReport;
|
||||||
|
|
||||||
|
if( dictionaryvCtorSelector_.search(geomModel) )
|
||||||
|
{
|
||||||
|
auto objPtr = dictionaryvCtorSelector_[geomModel]
|
||||||
|
(
|
||||||
|
control,
|
||||||
|
prop,
|
||||||
|
dict,
|
||||||
|
triSurface,
|
||||||
|
motionCompName,
|
||||||
|
propName
|
||||||
|
);
|
||||||
|
Report(2)<<"Model "<< greenText(geomModel)<<" is created.\n"<<endReport;
|
||||||
|
return objPtr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printKeys
|
||||||
|
(
|
||||||
|
fatalError << "Ctor Selector "<< yellowText(geomModel) << " dose not exist. \n"
|
||||||
|
<<"Avaiable ones are: \n\n"
|
||||||
|
,
|
||||||
|
dictionaryvCtorSelector_
|
||||||
|
);
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
268
src/Geometry/geometry/geometry.H
Normal file
268
src/Geometry/geometry/geometry.H
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
/*------------------------------- 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 __geometry_H__
|
||||||
|
#define __geometry_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "virtualConstructor.H"
|
||||||
|
#include "demGeometry.H"
|
||||||
|
#include "property.H"
|
||||||
|
#include "Fields.H"
|
||||||
|
#include "Vectors.H"
|
||||||
|
#include "multiTriSurface.H"
|
||||||
|
#include "triSurfaceFields.H"
|
||||||
|
#include "dictionary.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
class geometry
|
||||||
|
:
|
||||||
|
public demGeometry
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
const property& wallProperty_;
|
||||||
|
|
||||||
|
// - this object is owned by geometryRepository_
|
||||||
|
repository& geometryRepository_;
|
||||||
|
|
||||||
|
// all triangles of walls
|
||||||
|
multiTriSurface& triSurface_;
|
||||||
|
|
||||||
|
//
|
||||||
|
wordField& motionComponentName_;
|
||||||
|
|
||||||
|
//
|
||||||
|
wordField& materialName_;
|
||||||
|
|
||||||
|
int8TriSurfaceField_D& propertyId_;
|
||||||
|
|
||||||
|
realx3TriSurfaceField_D& contactForceWall_;
|
||||||
|
|
||||||
|
realx3TriSurfaceField_D& stressWall_;
|
||||||
|
|
||||||
|
bool findPropertyId();
|
||||||
|
|
||||||
|
void zeroForce()
|
||||||
|
{
|
||||||
|
contactForceWall_.fill(zero3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// - type info
|
||||||
|
TypeName("geometry");
|
||||||
|
|
||||||
|
//// - Constructors
|
||||||
|
|
||||||
|
// - empty
|
||||||
|
geometry(systemControl& control, const property& prop);
|
||||||
|
|
||||||
|
// - from components
|
||||||
|
geometry(systemControl& control,
|
||||||
|
const property& prop,
|
||||||
|
const multiTriSurface& triSurface,
|
||||||
|
const wordVector& motionCompName,
|
||||||
|
const wordVector& propName
|
||||||
|
);
|
||||||
|
|
||||||
|
geometry(systemControl& control,
|
||||||
|
const property& prop,
|
||||||
|
const dictionary& dict,
|
||||||
|
const multiTriSurface& triSurface,
|
||||||
|
const wordVector& motionCompName,
|
||||||
|
const wordVector& propName);
|
||||||
|
|
||||||
|
|
||||||
|
virtual ~geometry() = default;
|
||||||
|
|
||||||
|
create_vCtor
|
||||||
|
(
|
||||||
|
geometry,
|
||||||
|
systemControl,
|
||||||
|
(
|
||||||
|
systemControl& control,
|
||||||
|
const property& prop
|
||||||
|
),
|
||||||
|
(control, prop)
|
||||||
|
);
|
||||||
|
|
||||||
|
create_vCtor
|
||||||
|
(
|
||||||
|
geometry,
|
||||||
|
dictionary,
|
||||||
|
(systemControl& control,
|
||||||
|
const property& prop,
|
||||||
|
const dictionary& dict,
|
||||||
|
const multiTriSurface& triSurface,
|
||||||
|
const wordVector& motionCompName,
|
||||||
|
const wordVector& propName),
|
||||||
|
(control, prop, dict, triSurface, motionCompName, propName)
|
||||||
|
);
|
||||||
|
|
||||||
|
////- Methods
|
||||||
|
|
||||||
|
inline
|
||||||
|
auto size()const
|
||||||
|
{
|
||||||
|
return triSurface_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
auto numPoints()const
|
||||||
|
{
|
||||||
|
return triSurface_.numPoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
auto numTriangles()const
|
||||||
|
{
|
||||||
|
return size();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
const auto& points()const
|
||||||
|
{
|
||||||
|
return triSurface_.points();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
const auto& vertices()const
|
||||||
|
{
|
||||||
|
return triSurface_.vertices();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto getTriangleAccessor()const
|
||||||
|
{
|
||||||
|
return triSurface_.getTriangleAccessor();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto& surface()
|
||||||
|
{
|
||||||
|
return triSurface_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const auto& surface()const
|
||||||
|
{
|
||||||
|
return triSurface_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
realx3TriSurfaceField_D& contactForceWall()
|
||||||
|
{
|
||||||
|
return contactForceWall_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
const realx3TriSurfaceField_D& contactForceWall() const
|
||||||
|
{
|
||||||
|
return contactForceWall_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const auto& wallProperty()const
|
||||||
|
{
|
||||||
|
return wallProperty_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// owner repository
|
||||||
|
inline
|
||||||
|
const repository& owner()const
|
||||||
|
{
|
||||||
|
return geometryRepository_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
repository& owner()
|
||||||
|
{
|
||||||
|
return geometryRepository_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto path()
|
||||||
|
{
|
||||||
|
return owner().path();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual
|
||||||
|
word motionModelTypeName()const = 0;
|
||||||
|
|
||||||
|
virtual
|
||||||
|
const int8Vector_HD& triMotionIndex() const =0;
|
||||||
|
|
||||||
|
virtual
|
||||||
|
const int8Vector_HD& pointMotionIndex()const = 0;
|
||||||
|
|
||||||
|
const int8TriSurfaceField_D& propertyId() const
|
||||||
|
{
|
||||||
|
return propertyId_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool beforeIteration() override {
|
||||||
|
|
||||||
|
this->zeroForce();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool afterIteration() override {
|
||||||
|
|
||||||
|
auto Force = contactForceWall_.deviceVectorAll();
|
||||||
|
auto area = triSurface_.area().deviceVectorAll();
|
||||||
|
auto stress = stressWall_.deviceVectorAll();
|
||||||
|
auto numTri =triSurface_.size();
|
||||||
|
|
||||||
|
Kokkos::parallel_for(
|
||||||
|
"geometry::calculateStress",
|
||||||
|
numTri,
|
||||||
|
LAMBDA_HD(int32 i){
|
||||||
|
stress[i] = Force[i]/area[i];
|
||||||
|
});
|
||||||
|
Kokkos::fence();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool write()const
|
||||||
|
{
|
||||||
|
return owner().write();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// static
|
||||||
|
|
||||||
|
static
|
||||||
|
uniquePtr<geometry> create(systemControl& control, const property& prop);
|
||||||
|
|
||||||
|
static
|
||||||
|
uniquePtr<geometry> create(
|
||||||
|
systemControl& control,
|
||||||
|
const property& prop,
|
||||||
|
const dictionary& dict,
|
||||||
|
const multiTriSurface& triSurface,
|
||||||
|
const wordVector& motionCompName,
|
||||||
|
const wordVector& propName);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
189
src/Geometry/geometryMotion/geometryMotion.C
Normal file
189
src/Geometry/geometryMotion/geometryMotion.C
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template<typename MotionModel>
|
||||||
|
bool pFlow::geometryMotion<MotionModel>::moveGeometry()
|
||||||
|
{
|
||||||
|
|
||||||
|
real dt = this->dt();
|
||||||
|
|
||||||
|
auto pointMIndex= pointMotionIndex_.deviceVector();
|
||||||
|
auto mModel = motionModel_.getModel();
|
||||||
|
realx3* points = triSurface_.pointsData_D();
|
||||||
|
auto numPoints = triSurface_.numPoints();
|
||||||
|
|
||||||
|
|
||||||
|
Kokkos::parallel_for(
|
||||||
|
"geometryMotion<MotionModel>::movePoints",
|
||||||
|
numPoints,
|
||||||
|
LAMBDA_HD(int32 i){
|
||||||
|
auto newPos = mModel.transferPoint(pointMIndex[i], points[i], dt);
|
||||||
|
points[i] = newPos;
|
||||||
|
});
|
||||||
|
|
||||||
|
Kokkos::fence();
|
||||||
|
|
||||||
|
// end of calculations
|
||||||
|
moveGeomTimer_.end();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename MotionModel>
|
||||||
|
bool pFlow::geometryMotion<MotionModel>::findMotionIndex()
|
||||||
|
{
|
||||||
|
motionIndex_.clear();
|
||||||
|
triMotionIndex_.reserve( this->surface().capacity() );
|
||||||
|
triMotionIndex_.clear();
|
||||||
|
|
||||||
|
forAll( surfI, motionComponentName_)
|
||||||
|
{
|
||||||
|
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<surfSize; i++)
|
||||||
|
{
|
||||||
|
triMotionIndex_.push_back(mInd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
motionIndex_.syncViews();
|
||||||
|
triMotionIndex_.syncViews();
|
||||||
|
|
||||||
|
pointMotionIndex_.reserve(triSurface_.numPoints());
|
||||||
|
pointMotionIndex_.clear();
|
||||||
|
|
||||||
|
forAll(surfI, motionIndex_)
|
||||||
|
{
|
||||||
|
auto nP = triSurface_.surfNumPoints(surfI);
|
||||||
|
for(int32 i=0; i<nP; i++)
|
||||||
|
{
|
||||||
|
pointMotionIndex_.push_back(motionIndex_[surfI]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pointMotionIndex_.syncViews();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename MotionModel>
|
||||||
|
pFlow::geometryMotion<MotionModel>::geometryMotion
|
||||||
|
(
|
||||||
|
systemControl& control,
|
||||||
|
const property& prop
|
||||||
|
)
|
||||||
|
:
|
||||||
|
geometry(control, prop),
|
||||||
|
motionModel_(
|
||||||
|
this->owner().template emplaceObject<MotionModel>(
|
||||||
|
objectFile(
|
||||||
|
motionModelFile__,
|
||||||
|
"",
|
||||||
|
objectFile::READ_ALWAYS,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
moveGeomTimer_("move geometry", &this->timers())
|
||||||
|
{
|
||||||
|
findMotionIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename MotionModel>
|
||||||
|
pFlow::geometryMotion<MotionModel>::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<MotionModel>(
|
||||||
|
objectFile(
|
||||||
|
motionModelFile__,
|
||||||
|
"",
|
||||||
|
objectFile::READ_NEVER,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
),
|
||||||
|
motionModel
|
||||||
|
)
|
||||||
|
),
|
||||||
|
moveGeomTimer_("move geometry", &this->timers())
|
||||||
|
{
|
||||||
|
findMotionIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename MotionModel>
|
||||||
|
pFlow::geometryMotion<MotionModel>::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<MotionModel>(
|
||||||
|
objectFile(
|
||||||
|
motionModelFile__,
|
||||||
|
"",
|
||||||
|
objectFile::READ_NEVER,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
),
|
||||||
|
dict
|
||||||
|
)
|
||||||
|
),
|
||||||
|
moveGeomTimer_("move geometry", &this->timers())
|
||||||
|
{
|
||||||
|
findMotionIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename MotionModel>
|
||||||
|
bool pFlow::geometryMotion<MotionModel>::iterate()
|
||||||
|
{
|
||||||
|
if( motionModel_.isMoving() )
|
||||||
|
{
|
||||||
|
moveGeomTimer_.start();
|
||||||
|
moveGeometry();
|
||||||
|
moveGeomTimer_.end();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
155
src/Geometry/geometryMotion/geometryMotion.H
Normal file
155
src/Geometry/geometryMotion/geometryMotion.H
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
/*------------------------------- 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 __geometryMotion_H__
|
||||||
|
#define __geometryMotion_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "geometry.H"
|
||||||
|
#include "VectorDuals.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
template<typename MotionModelType>
|
||||||
|
class geometryMotion
|
||||||
|
:
|
||||||
|
public geometry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
using MotionModel = MotionModelType;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
MotionModel& motionModel_;
|
||||||
|
|
||||||
|
// motion indext mapped on each surface
|
||||||
|
int32Vector_HD motionIndex_;
|
||||||
|
|
||||||
|
// motion index mapped on each triangle
|
||||||
|
int8Vector_HD triMotionIndex_;
|
||||||
|
|
||||||
|
/// motion index mapped on each point
|
||||||
|
int8Vector_HD pointMotionIndex_;
|
||||||
|
|
||||||
|
// timer for moveGeometry
|
||||||
|
Timer moveGeomTimer_;
|
||||||
|
|
||||||
|
|
||||||
|
bool findMotionIndex();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// type info
|
||||||
|
TypeNameTemplate("geometry", MotionModel);
|
||||||
|
|
||||||
|
//// - Constructors
|
||||||
|
|
||||||
|
geometryMotion(systemControl& control, const property& prop);
|
||||||
|
|
||||||
|
// construct from components
|
||||||
|
geometryMotion(
|
||||||
|
systemControl& control,
|
||||||
|
const property& prop,
|
||||||
|
const multiTriSurface& triSurface,
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
add_vCtor
|
||||||
|
(
|
||||||
|
geometry,
|
||||||
|
geometryMotion,
|
||||||
|
systemControl
|
||||||
|
);
|
||||||
|
|
||||||
|
add_vCtor
|
||||||
|
(
|
||||||
|
geometry,
|
||||||
|
geometryMotion,
|
||||||
|
dictionary
|
||||||
|
);
|
||||||
|
|
||||||
|
//// - Methods
|
||||||
|
|
||||||
|
auto getModel()const
|
||||||
|
{
|
||||||
|
return motionModel_.getModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
word motionModelTypeName()const override
|
||||||
|
{
|
||||||
|
return motionModel_.typeName();
|
||||||
|
}
|
||||||
|
|
||||||
|
const int8Vector_HD& triMotionIndex()const override
|
||||||
|
{
|
||||||
|
return triMotionIndex_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int8Vector_HD& pointMotionIndex()const override
|
||||||
|
{
|
||||||
|
return pointMotionIndex_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - iterate
|
||||||
|
bool beforeIteration() override {
|
||||||
|
geometry::beforeIteration();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool iterate() override ;
|
||||||
|
|
||||||
|
bool afterIteration() override {
|
||||||
|
geometry::afterIteration();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool moveGeometry();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "geometryMotion.C"
|
||||||
|
|
||||||
|
#ifndef BUILD_SHARED_LIBS
|
||||||
|
#include "geometryMotionsInstantiate.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif //__geometryMotion_H__
|
25
src/Geometry/geometryMotion/geometryMotions.C
Normal file
25
src/Geometry/geometryMotion/geometryMotions.C
Normal file
@ -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.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "geometryMotions.H"
|
||||||
|
|
||||||
|
#ifdef BUILD_SHARED_LIBS
|
||||||
|
#include "geometryMotionsInstantiate.C"
|
||||||
|
#endif
|
40
src/Geometry/geometryMotion/geometryMotions.H
Normal file
40
src/Geometry/geometryMotion/geometryMotions.H
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*------------------------------- 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 __geometryMotions_H__
|
||||||
|
#define __geometryMotions_H__
|
||||||
|
|
||||||
|
#include "geometryMotion.H"
|
||||||
|
#include "fixedWall.H"
|
||||||
|
#include "rotatingAxisMotion.H"
|
||||||
|
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
typedef geometryMotion<rotatingAxisMotion> rotationAxisMotionGeometry;
|
||||||
|
|
||||||
|
typedef geometryMotion<fixedWall> fixedGeometry;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
28
src/Geometry/geometryMotion/geometryMotionsInstantiate.C
Normal file
28
src/Geometry/geometryMotion/geometryMotionsInstantiate.C
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*------------------------------- 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.H"
|
||||||
|
#include "rotatingAxisMotion.H"
|
||||||
|
|
||||||
|
template class pFlow::geometryMotion<pFlow::fixedWall>;
|
||||||
|
|
||||||
|
template class pFlow::geometryMotion<pFlow::rotatingAxisMotion>;
|
||||||
|
|
||||||
|
|
98
src/Integration/AdamsBashforth2/AdamsBashforth2.C
Normal file
98
src/Integration/AdamsBashforth2/AdamsBashforth2.C
Normal file
@ -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.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "AdamsBashforth2.H"
|
||||||
|
|
||||||
|
//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
|
||||||
|
)
|
||||||
|
:
|
||||||
|
integration(baseName, owner, pStruct, method),
|
||||||
|
dy1_(
|
||||||
|
owner.emplaceObject<realx3PointField_D>(
|
||||||
|
objectFile(
|
||||||
|
groupNames(baseName,"dy1"),
|
||||||
|
"",
|
||||||
|
objectFile::READ_IF_PRESENT,
|
||||||
|
objectFile::WRITE_ALWAYS),
|
||||||
|
pStruct,
|
||||||
|
zero3))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::AdamsBashforth2::predict
|
||||||
|
(
|
||||||
|
real UNUSED(dt),
|
||||||
|
realx3Vector_D& UNUSED(y),
|
||||||
|
realx3Vector_D& UNUSED(dy)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::AdamsBashforth2::correct
|
||||||
|
(
|
||||||
|
real dt,
|
||||||
|
realx3Vector_D& y,
|
||||||
|
realx3Vector_D& dy
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if(this->pStruct().allActive())
|
||||||
|
{
|
||||||
|
return intAll(dt, y, dy, this->pStruct().activeRange());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return intRange(dt, y, dy, this->pStruct().activePointsMaskD());
|
||||||
|
}
|
||||||
|
|
||||||
|
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<real>(3.0 / 2.0) * d_dy[i] - static_cast<real>(1.0 / 2.0) * d_dy1[i]);
|
||||||
|
d_dy1[i] = d_dy[i];
|
||||||
|
});
|
||||||
|
Kokkos::fence();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
109
src/Integration/AdamsBashforth2/AdamsBashforth2.H
Normal file
109
src/Integration/AdamsBashforth2/AdamsBashforth2.H
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*------------------------------- 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 __AdamsBashforth2_H__
|
||||||
|
#define __AdamsBashforth2_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "integration.H"
|
||||||
|
#include "pointFields.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
class AdamsBashforth2
|
||||||
|
:
|
||||||
|
public integration
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
realx3PointField_D& dy1_;
|
||||||
|
|
||||||
|
using rpIntegration = Kokkos::RangePolicy<
|
||||||
|
DefaultExecutionSpace,
|
||||||
|
Kokkos::Schedule<Kokkos::Static>,
|
||||||
|
Kokkos::IndexType<int32>
|
||||||
|
>;
|
||||||
|
public:
|
||||||
|
|
||||||
|
// type info
|
||||||
|
TypeName("AdamsBashforth2");
|
||||||
|
|
||||||
|
//// - Constructors
|
||||||
|
AdamsBashforth2(
|
||||||
|
const word& baseName,
|
||||||
|
repository& owner,
|
||||||
|
const pointStructure& pStruct,
|
||||||
|
const word& method);
|
||||||
|
|
||||||
|
virtual ~AdamsBashforth2()=default;
|
||||||
|
|
||||||
|
// - add a virtual constructor
|
||||||
|
add_vCtor(
|
||||||
|
integration,
|
||||||
|
AdamsBashforth2,
|
||||||
|
word);
|
||||||
|
|
||||||
|
|
||||||
|
//// - Methods
|
||||||
|
bool predict(real UNUSED(dt), realx3Vector_D& UNUSED(y), realx3Vector_D& UNUSED(dy)) override;
|
||||||
|
|
||||||
|
bool correct(real dt, realx3Vector_D& y, realx3Vector_D& dy) override;
|
||||||
|
|
||||||
|
bool intAll(real dt, realx3Vector_D& y, realx3Vector_D& dy, range activeRng);
|
||||||
|
|
||||||
|
template<typename activeFunctor>
|
||||||
|
bool intRange(real dt, realx3Vector_D& y, realx3Vector_D& dy, activeFunctor activeP );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename activeFunctor>
|
||||||
|
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<real>(3.0 / 2.0) * d_dy[i] - static_cast<real>(1.0 / 2.0) * d_dy1[i]);
|
||||||
|
d_dy1[i] = d_dy[i];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Kokkos::fence();
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // pFlow
|
||||||
|
|
||||||
|
#endif //__integration_H__
|
120
src/Integration/AdamsBashforth3/AdamsBashforth3.C
Normal file
120
src/Integration/AdamsBashforth3/AdamsBashforth3.C
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/*------------------------------- 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 "AdamsBashforth3.H"
|
||||||
|
|
||||||
|
//const real AB3_coef[] = { 23.0 / 12.0, 16.0 / 12.0, 5.0 / 12.0 };
|
||||||
|
|
||||||
|
pFlow::AdamsBashforth3::AdamsBashforth3
|
||||||
|
(
|
||||||
|
const word& baseName,
|
||||||
|
repository& owner,
|
||||||
|
const pointStructure& pStruct,
|
||||||
|
const word& method
|
||||||
|
)
|
||||||
|
:
|
||||||
|
integration(baseName, owner, pStruct, method),
|
||||||
|
/*dy1_(
|
||||||
|
owner.emplaceObject<realx3PointField_D>(
|
||||||
|
objectFile(
|
||||||
|
groupNames(baseName,"dy1"),
|
||||||
|
"",
|
||||||
|
objectFile::READ_IF_PRESENT,
|
||||||
|
objectFile::WRITE_ALWAYS),
|
||||||
|
pStruct,
|
||||||
|
zero3)),
|
||||||
|
dy2_(
|
||||||
|
owner.emplaceObject<realx3PointField_D>(
|
||||||
|
objectFile(
|
||||||
|
groupNames(baseName,"dy2"),
|
||||||
|
"",
|
||||||
|
objectFile::READ_IF_PRESENT,
|
||||||
|
objectFile::WRITE_ALWAYS),
|
||||||
|
pStruct,
|
||||||
|
zero3))*/
|
||||||
|
history_(
|
||||||
|
owner.emplaceObject<HistoryFieldType>(
|
||||||
|
objectFile(
|
||||||
|
groupNames(baseName,"AB3History"),
|
||||||
|
"",
|
||||||
|
objectFile::READ_IF_PRESENT,
|
||||||
|
objectFile::WRITE_ALWAYS),
|
||||||
|
pStruct,
|
||||||
|
AB3History({zero3,zero3})))
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::AdamsBashforth3::predict
|
||||||
|
(
|
||||||
|
real UNUSED(dt),
|
||||||
|
realx3Vector_D& UNUSED(y),
|
||||||
|
realx3Vector_D& UNUSED(dy)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::AdamsBashforth3::correct
|
||||||
|
(
|
||||||
|
real dt,
|
||||||
|
realx3Vector_D& y,
|
||||||
|
realx3Vector_D& dy
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this->pStruct().allActive())
|
||||||
|
{
|
||||||
|
return intAll(dt, y, dy, this->pStruct().activeRange());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return intRange(dt, y, dy, this->pStruct().activePointsMaskD());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::AdamsBashforth3::intAll(
|
||||||
|
real dt,
|
||||||
|
realx3Vector_D& y,
|
||||||
|
realx3Vector_D& dy,
|
||||||
|
range activeRng)
|
||||||
|
{
|
||||||
|
auto d_dy = dy.deviceVectorAll();
|
||||||
|
auto d_y = y.deviceVectorAll();
|
||||||
|
auto d_history = history_.deviceVectorAll();
|
||||||
|
|
||||||
|
Kokkos::parallel_for(
|
||||||
|
"AdamsBashforth3::correct",
|
||||||
|
rpIntegration (activeRng.first, activeRng.second),
|
||||||
|
LAMBDA_HD(int32 i){
|
||||||
|
auto ldy = d_dy[i];
|
||||||
|
d_y[i] += dt*( static_cast<real>(23.0 / 12.0) * ldy
|
||||||
|
- static_cast<real>(16.0 / 12.0) * d_history[i].dy1_
|
||||||
|
+ static_cast<real>(5.0 / 12.0) * d_history[i].dy2_);
|
||||||
|
d_history[i] = {ldy ,d_history[i].dy1_};
|
||||||
|
});
|
||||||
|
Kokkos::fence();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
166
src/Integration/AdamsBashforth3/AdamsBashforth3.H
Normal file
166
src/Integration/AdamsBashforth3/AdamsBashforth3.H
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __AdamsBashforth3_H__
|
||||||
|
#define __AdamsBashforth3_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "integration.H"
|
||||||
|
#include "pointFields.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
struct AB3History
|
||||||
|
{
|
||||||
|
realx3 dy1_={0,0,0};
|
||||||
|
realx3 dy2_={0,0,0};
|
||||||
|
|
||||||
|
TypeNameNV("AB3History");
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
INLINE_FUNCTION
|
||||||
|
iIstream& operator>>(iIstream& str, AB3History& ab3)
|
||||||
|
{
|
||||||
|
str.readBegin("AB3History");
|
||||||
|
|
||||||
|
str >> ab3.dy1_;
|
||||||
|
str >> ab3.dy2_;
|
||||||
|
|
||||||
|
str.readEnd("AB3History");
|
||||||
|
|
||||||
|
str.check(FUNCTION_NAME);
|
||||||
|
|
||||||
|
return str;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION
|
||||||
|
iOstream& operator<<(iOstream& str, const AB3History& ab3)
|
||||||
|
{
|
||||||
|
str << token::BEGIN_LIST << ab3.dy1_
|
||||||
|
<< token::SPACE << ab3.dy2_
|
||||||
|
<< token::END_LIST;
|
||||||
|
|
||||||
|
str.check(FUNCTION_NAME);
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class AdamsBashforth3
|
||||||
|
:
|
||||||
|
public integration
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
using HistoryFieldType = pointField<VectorSingle,AB3History>;
|
||||||
|
//realx3PointField_D& dy1_;
|
||||||
|
|
||||||
|
//realx3PointField_D& dy2_;
|
||||||
|
|
||||||
|
// this is a device
|
||||||
|
HistoryFieldType history_;
|
||||||
|
|
||||||
|
using rpIntegration = Kokkos::RangePolicy<
|
||||||
|
DefaultExecutionSpace,
|
||||||
|
Kokkos::Schedule<Kokkos::Static>,
|
||||||
|
Kokkos::IndexType<int32>
|
||||||
|
>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// type info
|
||||||
|
TypeName("AdamsBashforth3");
|
||||||
|
|
||||||
|
//// - Constructors
|
||||||
|
AdamsBashforth3(
|
||||||
|
const word& baseName,
|
||||||
|
repository& owner,
|
||||||
|
const pointStructure& pStruct,
|
||||||
|
const word& method);
|
||||||
|
|
||||||
|
virtual ~AdamsBashforth3()=default;
|
||||||
|
|
||||||
|
// - add a virtual constructor
|
||||||
|
add_vCtor(
|
||||||
|
integration,
|
||||||
|
AdamsBashforth3,
|
||||||
|
word);
|
||||||
|
|
||||||
|
|
||||||
|
//// - Methods
|
||||||
|
bool predict(
|
||||||
|
real UNUSED(dt),
|
||||||
|
realx3Vector_D & UNUSED(y),
|
||||||
|
realx3Vector_D& UNUSED(dy)) override;
|
||||||
|
|
||||||
|
bool correct(real dt,
|
||||||
|
realx3Vector_D & y,
|
||||||
|
realx3Vector_D& dy) override;
|
||||||
|
|
||||||
|
bool intAll(real dt,
|
||||||
|
realx3Vector_D& y,
|
||||||
|
realx3Vector_D& dy,
|
||||||
|
range activeRng);
|
||||||
|
|
||||||
|
template<typename activeFunctor>
|
||||||
|
bool intRange(real dt,
|
||||||
|
realx3Vector_D& y,
|
||||||
|
realx3Vector_D& dy,
|
||||||
|
activeFunctor activeP );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename activeFunctor>
|
||||||
|
bool pFlow::AdamsBashforth3::intRange(
|
||||||
|
real dt,
|
||||||
|
realx3Vector_D& y,
|
||||||
|
realx3Vector_D& dy,
|
||||||
|
activeFunctor activeP )
|
||||||
|
{
|
||||||
|
auto d_dy = dy.deviceVectorAll();
|
||||||
|
auto d_y = y.deviceVectorAll();
|
||||||
|
auto d_history = history_.deviceVectorAll();
|
||||||
|
auto activeRng = activeP.activeRange();
|
||||||
|
|
||||||
|
Kokkos::parallel_for(
|
||||||
|
"AdamsBashforth3::correct",
|
||||||
|
rpIntegration (activeRng.first, activeRng.second),
|
||||||
|
LAMBDA_HD(int32 i){
|
||||||
|
if( activeP(i))
|
||||||
|
{
|
||||||
|
auto ldy = d_dy[i];
|
||||||
|
d_y[i] += dt*( static_cast<real>(23.0 / 12.0) * ldy
|
||||||
|
- static_cast<real>(16.0 / 12.0) * d_history[i].dy1_
|
||||||
|
+ static_cast<real>(5.0 / 12.0) * d_history[i].dy2_);
|
||||||
|
d_history[i] = {ldy ,d_history[i].dy1_};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Kokkos::fence();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // pFlow
|
||||||
|
|
||||||
|
#endif //__integration_H__
|
13
src/Integration/CMakeLists.txt
Normal file
13
src/Integration/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
list(APPEND SourceFiles
|
||||||
|
integration/integration.C
|
||||||
|
AdamsBashforth3/AdamsBashforth3.C
|
||||||
|
AdamsBashforth2/AdamsBashforth2.C
|
||||||
|
)
|
||||||
|
|
||||||
|
set(link_libs Kokkos::kokkos phasicFlow)
|
||||||
|
|
||||||
|
pFlow_add_library_install(Integration SourceFiles link_libs)
|
||||||
|
|
||||||
|
|
||||||
|
|
62
src/Integration/integration/integration.C
Normal file
62
src/Integration/integration/integration.C
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*------------------------------- 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 "integration.H"
|
||||||
|
|
||||||
|
pFlow::integration::integration
|
||||||
|
(
|
||||||
|
const word& baseName,
|
||||||
|
repository& owner,
|
||||||
|
const pointStructure& pStruct,
|
||||||
|
const word& method
|
||||||
|
)
|
||||||
|
:
|
||||||
|
owner_(owner),
|
||||||
|
baseName_(baseName),
|
||||||
|
pStruct_(pStruct)
|
||||||
|
{
|
||||||
|
CONSUME_PARAM(method);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pFlow::uniquePtr<pFlow::integration>
|
||||||
|
pFlow::integration::create(
|
||||||
|
const word& baseName,
|
||||||
|
repository& owner,
|
||||||
|
const pointStructure& pStruct,
|
||||||
|
const word& method)
|
||||||
|
{
|
||||||
|
if( wordvCtorSelector_.search(method) )
|
||||||
|
{
|
||||||
|
return wordvCtorSelector_[method] (baseName, owner, pStruct, method);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printKeys
|
||||||
|
(
|
||||||
|
fatalError << "Ctor Selector "<< method << " dose not exist. \n"
|
||||||
|
<<"Avaiable ones are: \n\n"
|
||||||
|
,
|
||||||
|
wordvCtorSelector_
|
||||||
|
);
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
103
src/Integration/integration/integration.H
Normal file
103
src/Integration/integration/integration.H
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __integration_H__
|
||||||
|
#define __integration_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "virtualConstructor.H"
|
||||||
|
#include "Vectors.H"
|
||||||
|
#include "pointStructure.H"
|
||||||
|
#include "repository.H"
|
||||||
|
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
class integration
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
repository& owner_;
|
||||||
|
|
||||||
|
const word baseName_;
|
||||||
|
|
||||||
|
const pointStructure& pStruct_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// type info
|
||||||
|
TypeName("integration");
|
||||||
|
|
||||||
|
//// - Constructors
|
||||||
|
integration(
|
||||||
|
const word& baseName,
|
||||||
|
repository& owner,
|
||||||
|
const pointStructure& pStruct,
|
||||||
|
const word& method);
|
||||||
|
|
||||||
|
virtual ~integration()=default;
|
||||||
|
|
||||||
|
// - add a virtual constructor
|
||||||
|
create_vCtor(
|
||||||
|
integration,
|
||||||
|
word,
|
||||||
|
(const word& baseName,
|
||||||
|
repository& owner,
|
||||||
|
const pointStructure& pStruct,
|
||||||
|
const word& method),
|
||||||
|
(baseName, owner, pStruct, method) );
|
||||||
|
|
||||||
|
|
||||||
|
//// - Methods
|
||||||
|
|
||||||
|
const auto& pStruct()const
|
||||||
|
{
|
||||||
|
return pStruct_;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool predict(real dt, realx3Vector_D& y, realx3Vector_D& dy) = 0;
|
||||||
|
|
||||||
|
virtual bool correct(real dt, realx3Vector_D& y, realx3Vector_D& dy) = 0;
|
||||||
|
|
||||||
|
const word& baseName()const
|
||||||
|
{
|
||||||
|
return baseName_;
|
||||||
|
}
|
||||||
|
|
||||||
|
repository& owner()
|
||||||
|
{
|
||||||
|
return owner_;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
uniquePtr<integration> create(
|
||||||
|
const word& baseName,
|
||||||
|
repository& owner,
|
||||||
|
const pointStructure& pStruct,
|
||||||
|
const word& method);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // pFlow
|
||||||
|
|
||||||
|
|
||||||
|
#endif //__integration_H__
|
28
src/Integration/integration/integrations.H
Normal file
28
src/Integration/integration/integrations.H
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*------------------------------- 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 __integrations_H__
|
||||||
|
#define __integrations_H__
|
||||||
|
|
||||||
|
#include "integration.H"
|
||||||
|
#include "AdamsBashforth2.H"
|
||||||
|
#include "AdamsBashforth3.H"
|
||||||
|
|
||||||
|
#endif
|
16
src/Interaction/CMakeLists.txt
Normal file
16
src/Interaction/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
set(SourceFiles
|
||||||
|
contactSearch/contactSearch/contactSearch.C
|
||||||
|
contactSearch/ContactSearch/ContactSearchs.C
|
||||||
|
interaction/interaction.C
|
||||||
|
sphereInteraction/sphereInteractions.C
|
||||||
|
)
|
||||||
|
|
||||||
|
set(link_libs Kokkos::kokkos phasicFlow Property Particles Geometry)
|
||||||
|
|
||||||
|
pFlow_add_library_install(Interaction SourceFiles link_libs)
|
||||||
|
|
||||||
|
#additional locations
|
||||||
|
target_include_directories(Interaction PUBLIC "./contactSearch")
|
||||||
|
|
||||||
|
|
284
src/Interaction/Models/contactForce/linearCF.H
Normal file
284
src/Interaction/Models/contactForce/linearCF.H
Normal file
@ -0,0 +1,284 @@
|
|||||||
|
/*------------------------------- 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 __linearCF_H__
|
||||||
|
#define __linearCF_H__
|
||||||
|
|
||||||
|
#include "types.H"
|
||||||
|
#include "symArrays.H"
|
||||||
|
|
||||||
|
namespace pFlow::cfModels
|
||||||
|
{
|
||||||
|
|
||||||
|
template<bool limited=true>
|
||||||
|
class linear
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
struct contactForceStorage
|
||||||
|
{
|
||||||
|
realx3 overlap_t_ = 0.0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct linearProperties
|
||||||
|
{
|
||||||
|
real kn_ = 1000.0;
|
||||||
|
real kt_ = 800.0;
|
||||||
|
real ethan_ = 0.0;
|
||||||
|
real ethat_ = 0.0;
|
||||||
|
real mu_ = 0.00001;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
linearProperties(){}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
linearProperties(real kn, real kt, real etha_n, real etha_t, real mu ):
|
||||||
|
kn_(kn), kt_(kt), ethan_(etha_n),ethat_(etha_t), mu_(mu)
|
||||||
|
{}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
linearProperties(const linearProperties&)=default;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
linearProperties& operator=(const linearProperties&)=default;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
~linearProperties() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
using LinearArrayType = symArray<linearProperties>;
|
||||||
|
|
||||||
|
int32 numMaterial_ = 0;
|
||||||
|
|
||||||
|
ViewType1D<real> rho_;
|
||||||
|
|
||||||
|
LinearArrayType linearProperties_;
|
||||||
|
|
||||||
|
/**/
|
||||||
|
|
||||||
|
bool readLinearDictionary(const dictionary& dict)
|
||||||
|
{
|
||||||
|
auto kn = dict.getVal<realVector>("kn");
|
||||||
|
auto kt = dict.getVal<realVector>("kt");
|
||||||
|
auto en = dict.getVal<realVector>("en");
|
||||||
|
auto et = dict.getVal<realVector>("et");
|
||||||
|
auto mu = dict.getVal<realVector>("mu");
|
||||||
|
|
||||||
|
auto nElem = kn.size();
|
||||||
|
|
||||||
|
|
||||||
|
if(nElem != kt.size())
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"sizes of kn("<<nElem<<") and kt("<<kt.size()<<") do not match.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nElem != en.size())
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"sizes of kn("<<nElem<<") and en("<<en.size()<<") do not match.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nElem != et.size())
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"sizes of kn("<<nElem<<") and et("<<et.size()<<") do not match.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nElem != mu.size())
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"sizes of kn("<<nElem<<") and mu("<<mu.size()<<") do not match.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// check if size of vector matchs a symetric array
|
||||||
|
uint32 nMat;
|
||||||
|
if( !LinearArrayType::getN(nElem, nMat) )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"sizes of properties do not match a symetric array with size ("<<
|
||||||
|
numMaterial_<<"x"<<numMaterial_<<").\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if( numMaterial_ != nMat)
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"size mismatch for porperties. \n"<<
|
||||||
|
"you supplied "<< numMaterial_<<" items in materials list and "<<
|
||||||
|
nMat << " for other properties.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
realVector etha_n(nElem);
|
||||||
|
realVector etha_t(nElem);
|
||||||
|
forAll(i , kn)
|
||||||
|
{
|
||||||
|
etha_n[i] = -2.0*log(en[i])*sqrt(kn[i])/
|
||||||
|
sqrt(pow(log(en[i]),2.0)+ pow(Pi,2.0));
|
||||||
|
|
||||||
|
etha_t[i] = -2.0*log( et[i]*sqrt(kt[i]) )/
|
||||||
|
sqrt(pow(log(et[i]),2.0)+ pow(Pi,2.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<linearProperties> prop(nElem);
|
||||||
|
forAll(i,kn)
|
||||||
|
{
|
||||||
|
prop[i] = {kn[i], kt[i], etha_n[i], etha_t[i], mu[i]};
|
||||||
|
}
|
||||||
|
|
||||||
|
linearProperties_.assign(prop);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* modelName()
|
||||||
|
{
|
||||||
|
if constexpr (limited)
|
||||||
|
{
|
||||||
|
return "linearLimited";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "linearNonLimited";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
TypeNameNV(modelName());
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
linear(){}
|
||||||
|
|
||||||
|
linear(int32 nMaterial, const ViewType1D<real>& rho, const dictionary& dict)
|
||||||
|
:
|
||||||
|
numMaterial_(nMaterial),
|
||||||
|
rho_("rho",nMaterial),
|
||||||
|
linearProperties_("linearProperties",nMaterial)
|
||||||
|
{
|
||||||
|
|
||||||
|
Kokkos::deep_copy(rho_,rho);
|
||||||
|
if(!readLinearDictionary(dict))
|
||||||
|
{
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
linear(const linear&) = default;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
linear(linear&&) = default;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
linear& operator=(const linear&) = default;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
linear& operator=(linear&&) = default;
|
||||||
|
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
~linear()=default;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
int32 numMaterial()const
|
||||||
|
{
|
||||||
|
return numMaterial_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//// - Methods
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
void contactForce
|
||||||
|
(
|
||||||
|
const real dt,
|
||||||
|
const int32 i,
|
||||||
|
const int32 j,
|
||||||
|
const int32 propId_i,
|
||||||
|
const int32 propId_j,
|
||||||
|
const real Ri,
|
||||||
|
const real Rj,
|
||||||
|
const real ovrlp_n,
|
||||||
|
const realx3& Vr,
|
||||||
|
const realx3& Nij,
|
||||||
|
contactForceStorage& history,
|
||||||
|
realx3& FCn,
|
||||||
|
realx3& FCt
|
||||||
|
)const
|
||||||
|
{
|
||||||
|
|
||||||
|
auto prop = linearProperties_(propId_i,propId_j);
|
||||||
|
|
||||||
|
|
||||||
|
real vrn = dot(Vr, Nij);
|
||||||
|
realx3 Vt = Vr - vrn*Nij;
|
||||||
|
|
||||||
|
history.overlap_t_ += Vt*dt;
|
||||||
|
|
||||||
|
real mi = 3*Pi/4*pow(Ri,3.0)*rho_[propId_i];
|
||||||
|
real mj = 3*Pi/4*pow(Rj,3.0)*rho_[propId_j];
|
||||||
|
|
||||||
|
real sqrt_meff = sqrt((mi*mj)/(mi+mj));
|
||||||
|
|
||||||
|
FCn = (-prop.kn_ * ovrlp_n - sqrt_meff * prop.ethan_ * vrn)*Nij;
|
||||||
|
FCt = -prop.kt_ * history.overlap_t_ - sqrt_meff * prop.ethat_*Vt;
|
||||||
|
|
||||||
|
real ft = length(FCt);
|
||||||
|
real ft_fric = prop.mu_ * length(FCn);
|
||||||
|
|
||||||
|
if(ft > ft_fric)
|
||||||
|
{
|
||||||
|
if( length(history.overlap_t_) >static_cast<real>(0.0))
|
||||||
|
{
|
||||||
|
if constexpr (limited)
|
||||||
|
{
|
||||||
|
FCt *= (ft_fric/ft);
|
||||||
|
history.overlap_t_ = - (FCt/prop.kt_);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FCt = (FCt/ft)*ft_fric;
|
||||||
|
}
|
||||||
|
//cout<<"friction is applied here \n";
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FCt = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} //pFlow::cfModels
|
||||||
|
|
||||||
|
#endif
|
300
src/Interaction/Models/contactForce/nonLinearCF.H
Normal file
300
src/Interaction/Models/contactForce/nonLinearCF.H
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
/*------------------------------- 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 __nonLinearCF_H__
|
||||||
|
#define __nonLinearCF_H__
|
||||||
|
|
||||||
|
#include "types.H"
|
||||||
|
|
||||||
|
namespace pFlow::cfModels
|
||||||
|
{
|
||||||
|
|
||||||
|
template<bool limited=true>
|
||||||
|
class nonLinear
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
struct contactForceStorage
|
||||||
|
{
|
||||||
|
realx3 overlap_t_ = 0.0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nonLinearProperties
|
||||||
|
{
|
||||||
|
real Yeff_ = 1000000.0;
|
||||||
|
real Geff_ = 8000000.0;
|
||||||
|
real ethan_ = 0.0;
|
||||||
|
real ethat_ = 0.0;
|
||||||
|
real mu_ = 0.00001;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
nonLinearProperties(){}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
nonLinearProperties(real Yeff, real Geff, real etha_n, real etha_t, real mu ):
|
||||||
|
Yeff_(Yeff), Geff_(Geff), ethan_(etha_n),ethat_(etha_t), mu_(mu)
|
||||||
|
{}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
nonLinearProperties(const nonLinearProperties&)=default;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
nonLinearProperties& operator=(const nonLinearProperties&)=default;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
~nonLinearProperties() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
using NonLinearArrayType = symArray<nonLinearProperties>;
|
||||||
|
|
||||||
|
int32 numMaterial_ = 0;
|
||||||
|
|
||||||
|
ViewType1D<real> rho_;
|
||||||
|
|
||||||
|
NonLinearArrayType nonlinearProperties_;
|
||||||
|
|
||||||
|
bool readNonLinearDictionary(const dictionary& dict)
|
||||||
|
{
|
||||||
|
auto Yeff = dict.getVal<realVector>("Yeff");
|
||||||
|
auto Geff = dict.getVal<realVector>("Geff");
|
||||||
|
auto nu = dict.getVal<realVector>("nu");
|
||||||
|
auto en = dict.getVal<realVector>("en");
|
||||||
|
auto et = dict.getVal<realVector>("et");
|
||||||
|
auto mu = dict.getVal<realVector>("mu");
|
||||||
|
|
||||||
|
auto nElem = Yeff.size();
|
||||||
|
|
||||||
|
if(nElem != nu.size())
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"sizes of Yeff("<<nElem<<") and nu("<<nu.size()<<") do not match.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nElem != en.size())
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"sizes of Yeff("<<nElem<<") and en("<<en.size()<<") do not match.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nElem != et.size())
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"sizes of Yeff("<<nElem<<") and et("<<et.size()<<") do not match.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nElem != mu.size())
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"sizes of Yeff("<<nElem<<") and mu("<<mu.size()<<") do not match.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// check if size of vector matchs a symetric array
|
||||||
|
uint32 nMat;
|
||||||
|
if( !NonLinearArrayType::getN(nElem, nMat) )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"sizes of properties do not match a symetric array with size ("<<
|
||||||
|
numMaterial_<<"x"<<numMaterial_<<").\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if( numMaterial_ != nMat)
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"size mismatch for porperties. \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
realVector etha_n(nElem);
|
||||||
|
realVector etha_t(nElem);
|
||||||
|
forAll(i , en)
|
||||||
|
{
|
||||||
|
//K_hertz = 4.0/3.0*Yeff*sqrt(Reff);
|
||||||
|
//-2.2664*log(en)*sqrt(meff*K_hertz)/sqrt( log(en)**2 + 10.1354);
|
||||||
|
|
||||||
|
// we take out sqrt(meff*K_hertz) here and then condier this term
|
||||||
|
// when calculating damping part.
|
||||||
|
etha_n[i] = -2.2664*log(en[i])/
|
||||||
|
sqrt(pow(log(en[i]),2.0)+ pow(Pi,2.0));
|
||||||
|
|
||||||
|
// no damping for tangential part
|
||||||
|
etha_t[i] = 0.0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<nonLinearProperties> prop(nElem);
|
||||||
|
forAll(i,Yeff)
|
||||||
|
{
|
||||||
|
prop[i] = {Yeff[i], Geff[i], etha_n[i], etha_t[i], mu[i]};
|
||||||
|
}
|
||||||
|
|
||||||
|
nonlinearProperties_.assign(prop);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* modelName()
|
||||||
|
{
|
||||||
|
if constexpr (limited)
|
||||||
|
{
|
||||||
|
return "nonLinearLimited";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "nonLinearNonLimited";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeNameNV(modelName());
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
nonLinear(){}
|
||||||
|
|
||||||
|
nonLinear(
|
||||||
|
int32 nMaterial,
|
||||||
|
const ViewType1D<real>& rho,
|
||||||
|
const dictionary& dict)
|
||||||
|
:
|
||||||
|
numMaterial_(nMaterial),
|
||||||
|
rho_("rho",nMaterial),
|
||||||
|
nonlinearProperties_("nonLinearProperties",nMaterial)
|
||||||
|
{
|
||||||
|
|
||||||
|
Kokkos::deep_copy(rho_,rho);
|
||||||
|
if(!readNonLinearDictionary(dict))
|
||||||
|
{
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
nonLinear(const nonLinear&) = default;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
nonLinear(nonLinear&&) = default;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
nonLinear& operator=(const nonLinear&) = default;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
nonLinear& operator=(nonLinear&&) = default;
|
||||||
|
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
~nonLinear()=default;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
int32 numMaterial()const
|
||||||
|
{
|
||||||
|
return numMaterial_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//// - Methods
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
void contactForce
|
||||||
|
(
|
||||||
|
const real dt,
|
||||||
|
const int32 i,
|
||||||
|
const int32 j,
|
||||||
|
const int32 propId_i,
|
||||||
|
const int32 propId_j,
|
||||||
|
const real Ri,
|
||||||
|
const real Rj,
|
||||||
|
const real ovrlp_n,
|
||||||
|
const realx3& Vr,
|
||||||
|
const realx3& Nij,
|
||||||
|
contactForceStorage& history,
|
||||||
|
realx3& FCn,
|
||||||
|
realx3& FCt
|
||||||
|
)const
|
||||||
|
{
|
||||||
|
|
||||||
|
auto prop = nonlinearProperties_(propId_i,propId_j);
|
||||||
|
|
||||||
|
|
||||||
|
real vrn = dot(Vr, Nij);
|
||||||
|
realx3 Vt = Vr - vrn*Nij;
|
||||||
|
|
||||||
|
history.overlap_t_ += Vt*dt;
|
||||||
|
|
||||||
|
real mi = 3*Pi/4*pow(Ri,static_cast<real>(3))*rho_[propId_i];
|
||||||
|
real mj = 3*Pi/4*pow(Rj,static_cast<real>(3))*rho_[propId_j];
|
||||||
|
real Reff = 1.0/(1/Ri + 1/Rj);
|
||||||
|
|
||||||
|
real K_hertz = 4.0/3.0*prop.Yeff_*sqrt(Reff);
|
||||||
|
real sqrt_meff_K_hertz = sqrt((mi*mj)/(mi+mj) * K_hertz);
|
||||||
|
|
||||||
|
|
||||||
|
//FCn = (-prop.kn_ * ovrlp_n - sqrt_meff * prop.ethan_ * vrn)*Nij;
|
||||||
|
//FCt = -prop.kt_ * history.overlap_t_ - sqrt_meff * prop.ethat_*Vt;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FCn = (static_cast<real>(-4.0/3.0) * prop.Yeff_ * sqrt(Reff)* pow(ovrlp_n,static_cast<real>(1.5)) -
|
||||||
|
sqrt_meff_K_hertz*prop.ethan_*pow(ovrlp_n,static_cast<real>(0.25))*vrn)*Nij;
|
||||||
|
|
||||||
|
FCt = (- static_cast<real>(16.0/3.0) * prop.Geff_ * sqrt(Reff*ovrlp_n) ) * history.overlap_t_;
|
||||||
|
|
||||||
|
real ft = length(FCt);
|
||||||
|
real ft_fric = prop.mu_ * length(FCn);
|
||||||
|
|
||||||
|
// apply friction
|
||||||
|
if(ft > ft_fric)
|
||||||
|
{
|
||||||
|
if( length(history.overlap_t_) >0.0)
|
||||||
|
{
|
||||||
|
if constexpr (limited)
|
||||||
|
{
|
||||||
|
real kt = static_cast<real>(16.0/3.0) * prop.Geff_ * sqrt(Reff*ovrlp_n);
|
||||||
|
FCt *= (ft_fric/ft);
|
||||||
|
history.overlap_t_ = - (FCt/kt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FCt = (FCt/ft)*ft_fric;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FCt = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} //pFlow::CFModels
|
||||||
|
|
||||||
|
#endif
|
44
src/Interaction/Models/contactForceModels.H
Normal file
44
src/Interaction/Models/contactForceModels.H
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*------------------------------- 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 __contactForceModels_H__
|
||||||
|
#define __contactForceModels_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "linearCF.H"
|
||||||
|
#include "nonLinearCF.H"
|
||||||
|
#include "normalRolling.H"
|
||||||
|
|
||||||
|
|
||||||
|
namespace pFlow::cfModels
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
using limitedLinearNormalRolling = normalRolling<linear<true>>;
|
||||||
|
using nonLimitedLinearNormalRolling = normalRolling<linear<false>>;
|
||||||
|
|
||||||
|
using limitedNonLinearNormalRolling = normalRolling<nonLinear<true>>;
|
||||||
|
using nonLimitedNonLinearNormalRolling = normalRolling<nonLinear<false>>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif //__contactForceModels_H__
|
117
src/Interaction/Models/rolling/normalRolling.H
Normal file
117
src/Interaction/Models/rolling/normalRolling.H
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __normalRolling_H__
|
||||||
|
#define __normalRolling_H__
|
||||||
|
|
||||||
|
|
||||||
|
namespace pFlow::cfModels
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename contactForceModel>
|
||||||
|
class normalRolling
|
||||||
|
:
|
||||||
|
public contactForceModel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
using contactForceStorage =
|
||||||
|
typename contactForceModel::contactForceStorage;
|
||||||
|
|
||||||
|
|
||||||
|
realSymArray_D mur_;
|
||||||
|
|
||||||
|
bool readNormalDict(const dictionary& dict)
|
||||||
|
{
|
||||||
|
auto mur = dict.getVal<realVector>("mur");
|
||||||
|
|
||||||
|
uint32 nMat;
|
||||||
|
|
||||||
|
if(!realSymArray_D::getN(mur.size(),nMat) || nMat != this->numMaterial())
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"wrong number of values supplied in mur. \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mur_.assign(mur);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeNameNV(word("normal<"+contactForceModel::TYPENAME()+">"));
|
||||||
|
|
||||||
|
|
||||||
|
normalRolling(int32 nMaterial, const ViewType1D<real>& rho, const dictionary& dict)
|
||||||
|
:
|
||||||
|
contactForceModel(nMaterial, rho, dict),
|
||||||
|
mur_("mur", nMaterial)
|
||||||
|
{
|
||||||
|
if(!readNormalDict(dict))
|
||||||
|
{
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
void rollingFriction
|
||||||
|
(
|
||||||
|
const real dt,
|
||||||
|
const int32 i,
|
||||||
|
const int32 j,
|
||||||
|
const int32 propId_i,
|
||||||
|
const int32 propId_j,
|
||||||
|
const real Ri,
|
||||||
|
const real Rj,
|
||||||
|
const realx3& wi,
|
||||||
|
const realx3& wj,
|
||||||
|
const realx3& Nij,
|
||||||
|
const realx3& FCn,
|
||||||
|
realx3& Mri,
|
||||||
|
realx3& Mrj
|
||||||
|
)const
|
||||||
|
{
|
||||||
|
|
||||||
|
realx3 w_hat = wi-wj;
|
||||||
|
real w_hat_mag = length(w_hat);
|
||||||
|
|
||||||
|
if( !equal(w_hat_mag,0.0) )
|
||||||
|
w_hat /= w_hat_mag;
|
||||||
|
else
|
||||||
|
w_hat = 0.0;
|
||||||
|
|
||||||
|
auto Reff = (Ri*Rj)/(Ri+Rj);
|
||||||
|
|
||||||
|
Mri = ( -mur_(propId_i,propId_j) *length(FCn) * Reff ) * w_hat ;
|
||||||
|
|
||||||
|
//removing the normal part
|
||||||
|
// Mri = Mri - ( (Mri .dot. nij)*nij )
|
||||||
|
|
||||||
|
Mrj = -Mri;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
171
src/Interaction/contactLists/sortedContactList.H
Normal file
171
src/Interaction/contactLists/sortedContactList.H
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
/*------------------------------- 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 __sortedContactList_H__
|
||||||
|
#define __sortedContactList_H__
|
||||||
|
|
||||||
|
#include "sortedPairs.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename valueType, typename executionSpace, typename idType>
|
||||||
|
class sortedContactList
|
||||||
|
:
|
||||||
|
public sortedPairs<executionSpace, idType>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
using SortedPairs = sortedPairs<executionSpace, idType>;
|
||||||
|
|
||||||
|
using ValueType = valueType;
|
||||||
|
|
||||||
|
using IdType = typename SortedPairs::IdType;
|
||||||
|
|
||||||
|
using ExecutionSpace = typename SortedPairs::ExecutionSpace;
|
||||||
|
|
||||||
|
using memory_space = typename SortedPairs::memory_space;
|
||||||
|
|
||||||
|
using PairType = typename SortedPairs::PairType;
|
||||||
|
|
||||||
|
using ContainerType = typename SortedPairs::ContainerType;
|
||||||
|
|
||||||
|
class TagReFillPairs{};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
ViewType1D<ValueType,ExecutionSpace> values_;
|
||||||
|
|
||||||
|
int32 size0_ = 0;
|
||||||
|
|
||||||
|
ViewType1D<PairType,ExecutionSpace> sortedPairs0_;
|
||||||
|
|
||||||
|
ViewType1D<ValueType,ExecutionSpace> values0_;
|
||||||
|
|
||||||
|
|
||||||
|
void adjustCapacity()
|
||||||
|
{
|
||||||
|
if(auto s = this->size(); s > values_.size())
|
||||||
|
{
|
||||||
|
reallocNoInit(values_, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
using rpReFillPairs = Kokkos::RangePolicy<
|
||||||
|
ExecutionSpace,
|
||||||
|
Kokkos::Schedule<Kokkos::Static>,
|
||||||
|
Kokkos::IndexType<int32>,
|
||||||
|
TagReFillPairs>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeNameNV("sortedContactList");
|
||||||
|
|
||||||
|
|
||||||
|
sortedContactList(int32 initialSize =1)
|
||||||
|
:
|
||||||
|
SortedPairs(initialSize),
|
||||||
|
values_("values", SortedPairs::capacity()),
|
||||||
|
sortedPairs0_("sortedPairs0", SortedPairs::capacity()),
|
||||||
|
values0_("values0", SortedPairs::capacity())
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool beforeBroadSearch()
|
||||||
|
{
|
||||||
|
swapViews(values0_, values_);
|
||||||
|
swapViews(sortedPairs0_, this->sortedPairs_);
|
||||||
|
size0_ = this->size();
|
||||||
|
return SortedPairs::beforeBroadSearch();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool afterBroadSearch()
|
||||||
|
{
|
||||||
|
SortedPairs::afterBroadSearch();
|
||||||
|
|
||||||
|
adjustCapacity();
|
||||||
|
|
||||||
|
Kokkos::parallel_for(
|
||||||
|
"sortedContactList::reFillPairs",
|
||||||
|
rpReFillPairs(0, this->size() ),
|
||||||
|
*this
|
||||||
|
);
|
||||||
|
Kokkos::fence();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
ValueType getValue(int32 idx)const
|
||||||
|
{
|
||||||
|
return values_[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
void setValue(int32 idx, const ValueType& val)const
|
||||||
|
{
|
||||||
|
values_[idx] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
void operator()(TagReFillPairs, int32 idx)const
|
||||||
|
{
|
||||||
|
|
||||||
|
auto searchLen = max(size0_/1000,10);
|
||||||
|
auto start = max(0,idx-searchLen);
|
||||||
|
auto end = min(size0_,idx+searchLen);
|
||||||
|
auto newPair = this->sortedPairs_[idx];
|
||||||
|
if( auto idx0 = binarySearch(
|
||||||
|
sortedPairs0_,
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
newPair);
|
||||||
|
idx0>=0)
|
||||||
|
{
|
||||||
|
values_[idx] = values0_[idx0];
|
||||||
|
}
|
||||||
|
else if(auto idx0 = binarySearch(
|
||||||
|
sortedPairs0_,
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
newPair);
|
||||||
|
idx0>=0)
|
||||||
|
{
|
||||||
|
values_[idx] = values0_[idx0];
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
values_[idx] = ValueType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}; // sortedContactList
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // pFlow
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif //__sortedContactList_H__
|
258
src/Interaction/contactLists/sortedPairs.H
Normal file
258
src/Interaction/contactLists/sortedPairs.H
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
/*------------------------------- 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 __sortedPairs_H__
|
||||||
|
#define __sortedPairs_H__
|
||||||
|
|
||||||
|
#include "unsortedPairs.H"
|
||||||
|
#include "KokkosUtilities.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
template<typename executionSpace, typename idType>
|
||||||
|
class sortedPairs
|
||||||
|
:
|
||||||
|
public unsortedPairs<executionSpace, idType>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
using UnsortedPairs = unsortedPairs<executionSpace,idType>;
|
||||||
|
|
||||||
|
using IdType = typename UnsortedPairs::IdType;
|
||||||
|
|
||||||
|
using ExecutionSpace = typename UnsortedPairs::ExecutionSpace;
|
||||||
|
|
||||||
|
using memory_space = typename ExecutionSpace::memory_space;
|
||||||
|
|
||||||
|
using PairType = typename UnsortedPairs::PairType;
|
||||||
|
|
||||||
|
using ContainerType = typename UnsortedPairs::ContainerType;
|
||||||
|
|
||||||
|
struct pairAccessor
|
||||||
|
{
|
||||||
|
using PairType = typename sortedPairs::PairType;
|
||||||
|
|
||||||
|
int32 size_;
|
||||||
|
|
||||||
|
ViewType1D<PairType,ExecutionSpace> sortedParis_;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
int32 size()const { return size_; }
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
int32 loopCount()const { return size_; }
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool isValid(int32 i)const { return i<size_; }
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
PairType getPair(int i)const { return sortedParis_[i]; }
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool getPair(int32 i, PairType& pair)const {
|
||||||
|
if(i<size_) {
|
||||||
|
pair = sortedParis_[i];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TagFillFlag{};
|
||||||
|
|
||||||
|
class TagFillPairs{};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/// size of pair list
|
||||||
|
int32 size_ = 0;
|
||||||
|
|
||||||
|
ViewType1D<int32,ExecutionSpace> flags_;
|
||||||
|
|
||||||
|
ViewType1D<PairType,ExecutionSpace> sortedPairs_;
|
||||||
|
|
||||||
|
using rpFillFlag = Kokkos::RangePolicy<
|
||||||
|
ExecutionSpace,
|
||||||
|
Kokkos::Schedule<Kokkos::Static>,
|
||||||
|
Kokkos::IndexType<int32>,
|
||||||
|
TagFillFlag >;
|
||||||
|
|
||||||
|
using rpFillPairs = Kokkos::RangePolicy<
|
||||||
|
ExecutionSpace,
|
||||||
|
Kokkos::Schedule<Kokkos::Static>,
|
||||||
|
Kokkos::IndexType<int32>,
|
||||||
|
TagFillPairs>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// - type info
|
||||||
|
TypeNameNV("sortedPairs");
|
||||||
|
|
||||||
|
|
||||||
|
// constructors
|
||||||
|
sortedPairs(int32 initialSize =1)
|
||||||
|
:
|
||||||
|
UnsortedPairs(initialSize),
|
||||||
|
flags_("flags_",UnsortedPairs::capacity()+1),
|
||||||
|
sortedPairs_("sortedPairs_",UnsortedPairs::capacity())
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
bool beforeBroadSearch()
|
||||||
|
{
|
||||||
|
this->clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool afterBroadSearch()
|
||||||
|
{
|
||||||
|
prepareSorted();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - Device call
|
||||||
|
// return the pair at index idx
|
||||||
|
// perform no check for size and existance
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
PairType getPair(int32 idx)const
|
||||||
|
{
|
||||||
|
return sortedPairs_[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
// - Device/host call
|
||||||
|
// return the pair at index idx
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool getPair(int32 idx, PairType& p)const
|
||||||
|
{
|
||||||
|
if(isValid(idx))
|
||||||
|
{
|
||||||
|
p = getPair(idx);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool isValid(int32 idx)const
|
||||||
|
{
|
||||||
|
return idx < size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//use this when the value of size_ is updated
|
||||||
|
INLINE_FUNCTION_H
|
||||||
|
int32 size()const
|
||||||
|
{
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 loopCount()const
|
||||||
|
{
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
pairAccessor getPairs()const
|
||||||
|
{
|
||||||
|
return {size_, sortedPairs_};
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_H
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
UnsortedPairs::clear();
|
||||||
|
size_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepareSorted()
|
||||||
|
{
|
||||||
|
// first check the size of flags_
|
||||||
|
int32 capacity = UnsortedPairs::capacity();
|
||||||
|
|
||||||
|
if( capacity+1 > flags_.size() )
|
||||||
|
{
|
||||||
|
reallocNoInit(flags_, capacity+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fill the flags
|
||||||
|
Kokkos::parallel_for(
|
||||||
|
"contactPairsSorted::fillFlag",
|
||||||
|
rpFillFlag(0,capacity+1),
|
||||||
|
*this);
|
||||||
|
Kokkos::fence();
|
||||||
|
|
||||||
|
|
||||||
|
// inclusive scan on flags_
|
||||||
|
exclusiveScan(flags_, 0, capacity+1,flags_,0);
|
||||||
|
|
||||||
|
Kokkos::fence(); // Kokkos's scan is blocking I guess. So, this could be removed.
|
||||||
|
|
||||||
|
// get the last value of flags_ to obtain the size of sortedPairs_
|
||||||
|
getNth(size_, flags_, capacity);
|
||||||
|
|
||||||
|
if(size_ == 0 )return;
|
||||||
|
|
||||||
|
// resize sortedPairs_ if necessary;
|
||||||
|
if( size_>sortedPairs_.size() )
|
||||||
|
{
|
||||||
|
// get more space to prevent reallocations in next iterations
|
||||||
|
int32 len = size_*1.1+1;
|
||||||
|
reallocNoInit(sortedPairs_, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
Kokkos::parallel_for(
|
||||||
|
"contactPairsSorted::fillPairs",
|
||||||
|
rpFillPairs(0,this->capacity()),
|
||||||
|
*this);
|
||||||
|
Kokkos::fence();
|
||||||
|
|
||||||
|
// - sort paris based on the first and second
|
||||||
|
sort(sortedPairs_, 0, size_ );
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
void operator()(TagFillFlag, int32 i)const
|
||||||
|
{
|
||||||
|
if(this->container_.valid_at(i) )
|
||||||
|
flags_[i] = 1;
|
||||||
|
else
|
||||||
|
flags_[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
void operator()(TagFillPairs, int32 i)const
|
||||||
|
{
|
||||||
|
auto fi = flags_[i];
|
||||||
|
if(fi!=flags_[i+1])
|
||||||
|
sortedPairs_[fi] = this->container_.key_at(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //__sortedPairs_H__
|
175
src/Interaction/contactLists/unsortedContactList.H
Normal file
175
src/Interaction/contactLists/unsortedContactList.H
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
/*------------------------------- 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 __unsortedContactList_H__
|
||||||
|
#define __unsortedContactList_H__
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
template<typename valueType, typename executionSpace, typename idType>
|
||||||
|
class unsortedContactList
|
||||||
|
:
|
||||||
|
public unsortedPairs<executionSpace, idType>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
using ValueType = valueType;
|
||||||
|
|
||||||
|
using UnsortedPairs = unsortedPairs<executionSpace, idType>;
|
||||||
|
|
||||||
|
using IdType = typename UnsortedPairs::IdType;
|
||||||
|
|
||||||
|
using ExecutionSpace = typename UnsortedPairs::ExecutionSpace;
|
||||||
|
|
||||||
|
using memory_space = typename ExecutionSpace::memory_space;
|
||||||
|
|
||||||
|
using PairType = typename UnsortedPairs::PairType;
|
||||||
|
|
||||||
|
using ContainerType = typename UnsortedPairs::ContainerType;
|
||||||
|
|
||||||
|
class TagReFillPairs{};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/// storage for keeping the values of the current list
|
||||||
|
ViewType1D<ValueType,ExecutionSpace> values_;
|
||||||
|
|
||||||
|
/// storage for keeping pairs from the previous list
|
||||||
|
ContainerType container0_;
|
||||||
|
|
||||||
|
/// storage for keeping values from the previous list
|
||||||
|
ViewType1D<ValueType,ExecutionSpace> values0_;
|
||||||
|
|
||||||
|
void adjustCapacity()
|
||||||
|
{
|
||||||
|
auto cap = this->capacity();
|
||||||
|
if(cap > values_.size())
|
||||||
|
{
|
||||||
|
reallocNoInit(values_, cap);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
using rpFillPairs = Kokkos::RangePolicy<
|
||||||
|
ExecutionSpace,
|
||||||
|
Kokkos::Schedule<Kokkos::Static>,
|
||||||
|
Kokkos::IndexType<int32>,
|
||||||
|
TagReFillPairs>;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeNameNV("unsortedContactList");
|
||||||
|
|
||||||
|
unsortedContactList(int32 capacity=1)
|
||||||
|
:
|
||||||
|
UnsortedPairs(capacity),
|
||||||
|
values_("values", UnsortedPairs::capacity()),
|
||||||
|
container0_(capacity),
|
||||||
|
values0_("values0",container0_.capacity())
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
bool beforeBroadSearch()
|
||||||
|
{
|
||||||
|
// swap conainer and values
|
||||||
|
swapViews(values0_, values_);
|
||||||
|
swapViews(container0_, this->container_);
|
||||||
|
return UnsortedPairs::beforeBroadSearch();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool afterBroadSearch()
|
||||||
|
{
|
||||||
|
|
||||||
|
UnsortedPairs::afterBroadSearch();
|
||||||
|
|
||||||
|
adjustCapacity();
|
||||||
|
|
||||||
|
Kokkos::parallel_for(
|
||||||
|
"reFillPairs",
|
||||||
|
rpFillPairs(0,this->capacity()),
|
||||||
|
*this);
|
||||||
|
Kokkos::fence();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
ValueType getValue(int32 idx)const
|
||||||
|
{
|
||||||
|
return values_[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool getValue(const PairType& p, ValueType& val)const
|
||||||
|
{
|
||||||
|
if(auto idx = this->find(p); idx>=0)
|
||||||
|
{
|
||||||
|
val = getValue(idx);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
void setValue(int32 idx, const ValueType& val)const
|
||||||
|
{
|
||||||
|
values_[idx] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool setValue(const PairType& p, const ValueType& val)const
|
||||||
|
{
|
||||||
|
if(auto idx = this->find(p); idx>=0)
|
||||||
|
{
|
||||||
|
setValue(idx, val);
|
||||||
|
return true;;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
void operator()(TagReFillPairs, int32 idx)const
|
||||||
|
{
|
||||||
|
if( this->isValid(idx) )
|
||||||
|
{
|
||||||
|
if( int32 idx0 =
|
||||||
|
container0_.find(this->getPair(idx));
|
||||||
|
idx0>=0 )
|
||||||
|
{
|
||||||
|
values_[idx] = values0_[idx0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
values_[idx] = ValueType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// invalid locations should not be filled.
|
||||||
|
}
|
||||||
|
|
||||||
|
}; //unsortedContactList
|
||||||
|
|
||||||
|
|
||||||
|
} // pFlow
|
||||||
|
|
||||||
|
|
||||||
|
#endif //__unsortedContactList_H__
|
216
src/Interaction/contactLists/unsortedPairs.H
Normal file
216
src/Interaction/contactLists/unsortedPairs.H
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
/*------------------------------- 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 __unsortedPairs_H__
|
||||||
|
#define __unsortedPairs_H__
|
||||||
|
|
||||||
|
#include "KokkosTypes.H"
|
||||||
|
#include "types.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
template<typename executionSpace, typename idType>
|
||||||
|
class unsortedPairs
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
using UnsortedPairs = unsortedPairs<executionSpace,idType>;
|
||||||
|
|
||||||
|
using IdType = idType;
|
||||||
|
|
||||||
|
using ExecutionSpace = executionSpace;
|
||||||
|
|
||||||
|
using memory_space = typename ExecutionSpace::memory_space;
|
||||||
|
|
||||||
|
using PairType = kPair<idType,idType>;
|
||||||
|
|
||||||
|
using ContainerType = unorderedSet<PairType, ExecutionSpace>;
|
||||||
|
|
||||||
|
struct pairAccessor
|
||||||
|
{
|
||||||
|
using PairType = typename UnsortedPairs::PairType;
|
||||||
|
|
||||||
|
ContainerType Container_;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
int32 size()const { return Container_.size(); }
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
int32 loopCount()const { return Container_.capacity(); }
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool isValid(int32 idx)const { return Container_.valid_at(idx); }
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
PairType getPair(int idx)const { return Container_.key_at(idx); }
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool getPair(int32 idx, PairType& pair)const {
|
||||||
|
if(Container_.valid_at(idx)) {
|
||||||
|
pair = Container_.key_at(idx);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
ContainerType container_;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// - type info
|
||||||
|
TypeNameNV("unsorderedPairs");
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
unsortedPairs(int32 capacity=1)
|
||||||
|
:
|
||||||
|
container_(capacity) // the minimum capacity would be 128
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool beforeBroadSearch()
|
||||||
|
{
|
||||||
|
container_.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool afterBroadSearch()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - Device call
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
int32 insert(idType i, idType j)const
|
||||||
|
{
|
||||||
|
if(auto insertResult = container_.insert(PairType(i,j)); insertResult.failed())
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return insertResult.index();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
int32 insert(const PairType& p)const
|
||||||
|
{
|
||||||
|
if(auto insertResult = container_.insert(p); insertResult.failed())
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return insertResult.index();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// - Device call
|
||||||
|
// return the pair at index idx
|
||||||
|
// perform no check for size and existance
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
PairType getPair(int32 idx)const
|
||||||
|
{
|
||||||
|
return container_.key_at(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - Device call
|
||||||
|
// return the pair at index idx
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool getPair(int32 idx, PairType& p)const
|
||||||
|
{
|
||||||
|
if(container_.valid_at(idx))
|
||||||
|
{
|
||||||
|
p = container_.key_at(idx);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
int32 find(const PairType & p)const
|
||||||
|
{
|
||||||
|
if( auto idx = container_.find(p);
|
||||||
|
idx != Kokkos::UnorderedMapInvalidIndex )
|
||||||
|
return idx;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool isValid(int32 idx)const
|
||||||
|
{
|
||||||
|
return container_.valid_at(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
int32 capacity() const
|
||||||
|
{
|
||||||
|
return container_.capacity();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 loopCount()const
|
||||||
|
{
|
||||||
|
return container_.capacity();
|
||||||
|
}
|
||||||
|
|
||||||
|
//use this when the value of size_ is updated
|
||||||
|
INLINE_FUNCTION_H
|
||||||
|
int32 size()const
|
||||||
|
{
|
||||||
|
return container_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
pairAccessor getPairs()const
|
||||||
|
{
|
||||||
|
return {container_};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// increase the capacity of the container by at-least len
|
||||||
|
/// the content will be erased.
|
||||||
|
INLINE_FUNCTION_H
|
||||||
|
void increaseCapacityBy(int32 len)
|
||||||
|
{
|
||||||
|
uint newCap = container_.capacity()+len;
|
||||||
|
this->clear();
|
||||||
|
container_.rehash(newCap);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_H
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
container_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const ContainerType& container()const
|
||||||
|
{
|
||||||
|
return container_;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //__unsortedPairs_H__
|
250
src/Interaction/contactSearch/ContactSearch/ContactSearch.H
Normal file
250
src/Interaction/contactSearch/ContactSearch/ContactSearch.H
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __ContactSearch_H__
|
||||||
|
#define __ContactSearch_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "contactSearch.H"
|
||||||
|
#include "box.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
template<
|
||||||
|
template<class, class, class> class BaseMethod,
|
||||||
|
template<class, class, class> class WallMapping
|
||||||
|
>
|
||||||
|
class ContactSearch
|
||||||
|
:
|
||||||
|
public contactSearch
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
using IdType = typename contactSearch::IdType;
|
||||||
|
|
||||||
|
using IndexType = typename contactSearch::IndexType;
|
||||||
|
|
||||||
|
using ExecutionSpace = typename contactSearch::ExecutionSpace;
|
||||||
|
|
||||||
|
using PairContainerType = typename contactSearch::PairContainerType;
|
||||||
|
|
||||||
|
using ParticleContactSearchType =
|
||||||
|
BaseMethod<
|
||||||
|
ExecutionSpace,
|
||||||
|
IdType,
|
||||||
|
IndexType
|
||||||
|
>;
|
||||||
|
|
||||||
|
using WallMappingType =
|
||||||
|
WallMapping<
|
||||||
|
ExecutionSpace,
|
||||||
|
IdType,
|
||||||
|
IndexType
|
||||||
|
>;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
uniquePtr<ParticleContactSearchType> particleContactSearch_ = nullptr;
|
||||||
|
|
||||||
|
uniquePtr<WallMappingType> wallMapping_ = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeNameTemplate2("ContactSearch", ParticleContactSearchType, WallMappingType);
|
||||||
|
|
||||||
|
ContactSearch(
|
||||||
|
const dictionary& csDict,
|
||||||
|
const box& domain,
|
||||||
|
const particles& prtcl,
|
||||||
|
const geometry& geom,
|
||||||
|
Timers& timers)
|
||||||
|
:
|
||||||
|
contactSearch(csDict, domain, prtcl, geom, timers)
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
auto method = dict().getVal<word>("method");
|
||||||
|
auto wmMethod = dict().getVal<word>("wallMapping");
|
||||||
|
|
||||||
|
auto nbDict = dict().subDictOrCreate(method+"Info");
|
||||||
|
|
||||||
|
real minD, maxD;
|
||||||
|
this->Particles().boundingSphereMinMax(minD, maxD);
|
||||||
|
|
||||||
|
const auto& position = this->Particles().pointPosition().deviceVectorAll();
|
||||||
|
const auto& diam = this->Particles().boundingSphere().deviceVectorAll();
|
||||||
|
|
||||||
|
particleContactSearch_ =
|
||||||
|
makeUnique<ParticleContactSearchType>
|
||||||
|
(
|
||||||
|
nbDict,
|
||||||
|
this->domain(),
|
||||||
|
maxD,
|
||||||
|
position,
|
||||||
|
diam
|
||||||
|
);
|
||||||
|
Report(2)<<"Contact search algorithm for particle-particle is "<<
|
||||||
|
greenText(particleContactSearch_().typeName())<<endReport;
|
||||||
|
|
||||||
|
|
||||||
|
auto wmDict = dict().subDictOrCreate(wmMethod+"Info");
|
||||||
|
|
||||||
|
int32 wnPoints = this->Geometry().numPoints();
|
||||||
|
int32 wnTri = this->Geometry().size();
|
||||||
|
|
||||||
|
const auto& wPoints = this->Geometry().points().deviceVectorAll();
|
||||||
|
const auto& wVertices = this->Geometry().vertices().deviceVectorAll();
|
||||||
|
|
||||||
|
wallMapping_ =
|
||||||
|
makeUnique<WallMappingType>(
|
||||||
|
wmDict,
|
||||||
|
particleContactSearch_().getCells(),
|
||||||
|
wnPoints,
|
||||||
|
wnTri,
|
||||||
|
wPoints,
|
||||||
|
wVertices
|
||||||
|
);
|
||||||
|
Report(2)<<"Wall mapping algorithm for particle-wall is "<<
|
||||||
|
greenText(wallMapping_().typeName())<< endReport;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
add_vCtor(
|
||||||
|
contactSearch,
|
||||||
|
ContactSearch,
|
||||||
|
dictionary);
|
||||||
|
|
||||||
|
bool broadSearch(
|
||||||
|
PairContainerType& ppPairs,
|
||||||
|
PairContainerType& pwPairs,
|
||||||
|
bool force = false) override
|
||||||
|
{
|
||||||
|
|
||||||
|
//output<<" ContactSearch::broadSearch::PP before.\n";
|
||||||
|
if(particleContactSearch_)
|
||||||
|
{
|
||||||
|
auto activeRange = this->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
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(wallMapping_)
|
||||||
|
{
|
||||||
|
sphereWallTimer_.start();
|
||||||
|
wallMapping_().broadSearch(pwPairs, particleContactSearch_(), force);
|
||||||
|
sphereWallTimer_.end();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ppEnterBroadSearch()const override
|
||||||
|
{
|
||||||
|
if(particleContactSearch_)
|
||||||
|
{
|
||||||
|
return particleContactSearch_().enterBoadSearch();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pwEnterBroadSearch()const override
|
||||||
|
{
|
||||||
|
if(wallMapping_)
|
||||||
|
{
|
||||||
|
return wallMapping_().enterBoadSearch();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //__ContactSearch_H__
|
26
src/Interaction/contactSearch/ContactSearch/ContactSearchs.C
Normal file
26
src/Interaction/contactSearch/ContactSearch/ContactSearchs.C
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*------------------------------- 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 "ContactSearch.H"
|
||||||
|
|
||||||
|
#include "cellsSimple.H"
|
||||||
|
#include "NBS.H"
|
||||||
|
|
||||||
|
template class pFlow::ContactSearch<pFlow::NBS, pFlow::cellsSimple>;
|
233
src/Interaction/contactSearch/cells.H
Normal file
233
src/Interaction/contactSearch/cells.H
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
/*------------------------------- 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 __cells_H__
|
||||||
|
#define __cells_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "types.H"
|
||||||
|
#include "box.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename indexType>
|
||||||
|
class cells
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
using CellType = triple<indexType>;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// - domain
|
||||||
|
box domain_;
|
||||||
|
|
||||||
|
// - cell size
|
||||||
|
real cellSize_;
|
||||||
|
|
||||||
|
CellType numCells_;
|
||||||
|
|
||||||
|
|
||||||
|
// - protected methods
|
||||||
|
INLINE_FUNCTION_H
|
||||||
|
void calculate()
|
||||||
|
{
|
||||||
|
numCells_ = (domain_.maxPoint()-domain_.minPoint())/cellSize_ + realx3(1.0);
|
||||||
|
numCells_ = max( numCells_ , CellType(static_cast<indexType>(1)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
cells()
|
||||||
|
{}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_H
|
||||||
|
cells(const box& domain, real cellSize)
|
||||||
|
:
|
||||||
|
domain_(domain),
|
||||||
|
cellSize_(cellSize)
|
||||||
|
{
|
||||||
|
calculate();
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
cells(const cells&) = default;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
cells& operator = (const cells&) = default;
|
||||||
|
|
||||||
|
cells getCells()const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_H
|
||||||
|
void setCellSize(real cellSize)
|
||||||
|
{
|
||||||
|
cellSize_ = cellSize;
|
||||||
|
calculate();
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
real cellSize()const
|
||||||
|
{
|
||||||
|
return cellSize_;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
const CellType& numCells()const
|
||||||
|
{
|
||||||
|
return numCells_;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
indexType nx()const
|
||||||
|
{
|
||||||
|
return numCells_.x();
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
indexType ny()const
|
||||||
|
{
|
||||||
|
return numCells_.y();
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
indexType nz()const
|
||||||
|
{
|
||||||
|
return numCells_.z();
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
int64 totalCells()const
|
||||||
|
{
|
||||||
|
return static_cast<int64>(numCells_.x())*
|
||||||
|
static_cast<int64>(numCells_.y())*
|
||||||
|
static_cast<int64>(numCells_.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
CellType pointIndex(const realx3& p)const
|
||||||
|
{
|
||||||
|
return CellType( (p - domain_.minPoint())/cellSize_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool pointIndexInDomain(const realx3 p, CellType& index)const
|
||||||
|
{
|
||||||
|
if( !domain_.isInside(p) ) return false;
|
||||||
|
|
||||||
|
index = this->pointIndex(p);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool inDomain(const realx3& p)const
|
||||||
|
{
|
||||||
|
return domain_.isInside(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool isInRange(const CellType& cell)const
|
||||||
|
{
|
||||||
|
if(cell.x()<0)return false;
|
||||||
|
if(cell.y()<0)return false;
|
||||||
|
if(cell.z()<0)return false;
|
||||||
|
if(cell.x()>numCells_.x()-1) return false;
|
||||||
|
if(cell.y()>numCells_.y()-1) return false;
|
||||||
|
if(cell.z()>numCells_.z()-1) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool isInRange(indexType i, indexType j, indexType k)const
|
||||||
|
{
|
||||||
|
if(i<0)return false;
|
||||||
|
if(j<0)return false;
|
||||||
|
if(k<0)return false;
|
||||||
|
if(i>numCells_.x()-1) return false;
|
||||||
|
if(j>numCells_.y()-1) return false;
|
||||||
|
if(k>numCells_.z()-1) return false;
|
||||||
|
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,
|
||||||
|
const realx3& p2,
|
||||||
|
const realx3& p3,
|
||||||
|
real extent,
|
||||||
|
realx3& minP,
|
||||||
|
realx3& maxP)const
|
||||||
|
{
|
||||||
|
minP = min(min(p1,p2),p3) - extent*cellSize_ ;
|
||||||
|
maxP = max(max(p1,p2),p3) + extent*cellSize_ ;
|
||||||
|
|
||||||
|
minP = bound(minP);
|
||||||
|
maxP = bound(maxP);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
CellType bound(CellType p)const
|
||||||
|
{
|
||||||
|
return CellType(
|
||||||
|
min( numCells_.x()-1, max(0,p.x())),
|
||||||
|
min( numCells_.y()-1, max(0,p.y())),
|
||||||
|
min( numCells_.z()-1, max(0,p.z()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
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()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
78
src/Interaction/contactSearch/contactSearch/contactSearch.C
Normal file
78
src/Interaction/contactSearch/contactSearch/contactSearch.C
Normal file
@ -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.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "contactSearch.H"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pFlow::contactSearch::contactSearch(
|
||||||
|
const dictionary& dict,
|
||||||
|
const box& domain,
|
||||||
|
const particles& prtcl,
|
||||||
|
const geometry& geom,
|
||||||
|
Timers& timers)
|
||||||
|
:
|
||||||
|
interactionBase(prtcl, geom),
|
||||||
|
domain_(domain),
|
||||||
|
dict_(dict),
|
||||||
|
sphereSphereTimer_("particle-particle contact search", &timers),
|
||||||
|
sphereWallTimer_("particle-wall contact search", &timers)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pFlow::uniquePtr<pFlow::contactSearch> pFlow::contactSearch::create(
|
||||||
|
const dictionary& dict,
|
||||||
|
const box& domain,
|
||||||
|
const particles& prtcl,
|
||||||
|
const geometry& geom,
|
||||||
|
Timers& timers)
|
||||||
|
{
|
||||||
|
|
||||||
|
word baseMethName = dict.getVal<word>("method");
|
||||||
|
word wallMethod = dict.getVal<word>("wallMapping");
|
||||||
|
|
||||||
|
auto model = angleBracketsNames2("ContactSearch", baseMethName, wallMethod);
|
||||||
|
|
||||||
|
|
||||||
|
Report(1)<<"Selecting contact search model . . ."<<endReport;
|
||||||
|
|
||||||
|
|
||||||
|
if( dictionaryvCtorSelector_.search(model))
|
||||||
|
{
|
||||||
|
auto objPtr = dictionaryvCtorSelector_[model] (dict, domain, prtcl, geom, timers);
|
||||||
|
Report(2)<<"Model "<< greenText(model)<<" is created."<<endReport;
|
||||||
|
return objPtr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printKeys
|
||||||
|
(
|
||||||
|
fatalError << "Ctor Selector "<< model << " dose not exist. \n"
|
||||||
|
<<"Avaiable ones are: \n\n"
|
||||||
|
,
|
||||||
|
dictionaryvCtorSelector_
|
||||||
|
);
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
135
src/Interaction/contactSearch/contactSearch/contactSearch.H
Normal file
135
src/Interaction/contactSearch/contactSearch/contactSearch.H
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
/*------------------------------- 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 __contactSearch_H__
|
||||||
|
#define __contactSearch_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "interactionBase.H"
|
||||||
|
#include "unsortedPairs.H"
|
||||||
|
#include "box.H"
|
||||||
|
#include "dictionary.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
class contactSearch
|
||||||
|
:
|
||||||
|
public interactionBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using IdType = typename interactionBase::IdType;
|
||||||
|
|
||||||
|
using IndexType = typename interactionBase::IndexType;
|
||||||
|
|
||||||
|
using ExecutionSpace = typename interactionBase::ExecutionSpace;
|
||||||
|
|
||||||
|
using PairContainerType = unsortedPairs<ExecutionSpace, IdType>;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
const box& domain_;
|
||||||
|
|
||||||
|
dictionary dict_;
|
||||||
|
|
||||||
|
Timer sphereSphereTimer_;
|
||||||
|
|
||||||
|
Timer sphereWallTimer_;
|
||||||
|
|
||||||
|
auto& dict()
|
||||||
|
{
|
||||||
|
return dict_;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeName("contactSearch");
|
||||||
|
|
||||||
|
contactSearch(
|
||||||
|
const dictionary& dict,
|
||||||
|
const box& domain,
|
||||||
|
const particles& prtcl,
|
||||||
|
const geometry& geom,
|
||||||
|
Timers& timers);
|
||||||
|
|
||||||
|
virtual ~contactSearch()=default;
|
||||||
|
|
||||||
|
|
||||||
|
create_vCtor
|
||||||
|
(
|
||||||
|
contactSearch,
|
||||||
|
dictionary,
|
||||||
|
(
|
||||||
|
const dictionary& dict,
|
||||||
|
const box& domain,
|
||||||
|
const particles& prtcl,
|
||||||
|
const geometry& geom,
|
||||||
|
Timers& timers
|
||||||
|
),
|
||||||
|
(dict, domain, prtcl, geom, timers)
|
||||||
|
);
|
||||||
|
|
||||||
|
const auto& domain()const
|
||||||
|
{
|
||||||
|
return domain_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& dict()const
|
||||||
|
{
|
||||||
|
return dict_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual
|
||||||
|
bool broadSearch(
|
||||||
|
PairContainerType& ppPairs,
|
||||||
|
PairContainerType& pwPairs,
|
||||||
|
bool force = false) = 0;
|
||||||
|
|
||||||
|
virtual
|
||||||
|
bool ppEnterBroadSearch()const = 0;
|
||||||
|
|
||||||
|
virtual
|
||||||
|
bool pwEnterBroadSearch()const = 0;
|
||||||
|
|
||||||
|
virtual
|
||||||
|
bool ppPerformedBroadSearch()const = 0;
|
||||||
|
|
||||||
|
virtual
|
||||||
|
bool pwPerformedBroadSearch()const = 0;
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
uniquePtr<contactSearch> create(
|
||||||
|
const dictionary& dict,
|
||||||
|
const box& domain,
|
||||||
|
const particles& prtcl,
|
||||||
|
const geometry& geom,
|
||||||
|
Timers& timers);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //__ContactSearch_H__
|
112
src/Interaction/contactSearch/contactSearchFunctions.H
Normal file
112
src/Interaction/contactSearch/contactSearchFunctions.H
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/*------------------------------- 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 __broadSearchFunctions_H__
|
||||||
|
#define __broadSearchFunctions_H__
|
||||||
|
|
||||||
|
#include "types.H"
|
||||||
|
#include "iBox.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
uint64_t splitBy3(const uint64_t val){
|
||||||
|
uint64_t x = val;
|
||||||
|
x = (x | x << 32) & 0x1f00000000ffff;
|
||||||
|
x = (x | x << 16) & 0x1f0000ff0000ff;
|
||||||
|
x = (x | x << 8) & 0x100f00f00f00f00f;
|
||||||
|
x = (x | x << 4) & 0x10c30c30c30c30c3;
|
||||||
|
x = (x | x << 2) & 0x1249249249249249;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
uint64_t xyzToMortonCode64(uint64_t x, uint64_t y, uint64_t z)
|
||||||
|
{
|
||||||
|
return splitBy3(x) | (splitBy3(y) << 1) | (splitBy3(z) << 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
uint64_t getThirdBits(uint64_t x)
|
||||||
|
{
|
||||||
|
x = x & 0x9249249249249249;
|
||||||
|
x = (x | (x >> 2)) & 0x30c30c30c30c30c3;
|
||||||
|
x = (x | (x >> 4)) & 0xf00f00f00f00f00f;
|
||||||
|
x = (x | (x >> 8)) & 0x00ff0000ff0000ff;
|
||||||
|
x = (x | (x >> 16)) & 0xffff00000000ffff;
|
||||||
|
x = (x | (x >> 32)) & 0x00000000ffffffff;
|
||||||
|
return x;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
void mortonCode64Toxyz(uint64_t morton, uint64_t& x, uint64_t& y, uint64_t& z)
|
||||||
|
{
|
||||||
|
x = getThirdBits(morton);
|
||||||
|
y = getThirdBits(morton >> 1);
|
||||||
|
z = getThirdBits(morton >> 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename indexType, typename cellIndexType>
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
void indexToCell(const indexType idx, const triple<cellIndexType>& extent, triple<cellIndexType>& cell)
|
||||||
|
{
|
||||||
|
indexType nxny = extent.x()*extent.y();
|
||||||
|
cell.z() = static_cast<cellIndexType>(idx / nxny);
|
||||||
|
auto rem = idx % nxny;
|
||||||
|
cell.y() = static_cast<cellIndexType>(rem / extent.x());
|
||||||
|
cell.x() = static_cast<cellIndexType>(rem % extent.x());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename cellIndexType>
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
triple<cellIndexType> boxExtent( const iBox<cellIndexType>& box)
|
||||||
|
{
|
||||||
|
return triple<cellIndexType>(
|
||||||
|
box.maxPoint().x() - box.minPoint().x() + 1,
|
||||||
|
box.maxPoint().y() - box.minPoint().y() + 1,
|
||||||
|
box.maxPoint().z() - box.minPoint().z() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename indexType, typename cellIndexType>
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
void indexToCell(const indexType idx, const iBox<cellIndexType>& box, triple<cellIndexType>& cell)
|
||||||
|
{
|
||||||
|
auto extent = boxExtent(box);
|
||||||
|
indexToCell(idx, extent, cell);
|
||||||
|
cell+= box.minPoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool sphereSphereCheck(const realx3& p1, const realx3 p2, real d1, real d2)
|
||||||
|
{
|
||||||
|
return length(p2-p1) < 0.5*(d2+d1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //__broadSearchFunctions_H__
|
522
src/Interaction/contactSearch/methods/NBS.H
Normal file
522
src/Interaction/contactSearch/methods/NBS.H
Normal file
@ -0,0 +1,522 @@
|
|||||||
|
/*------------------------------- 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_H__
|
||||||
|
#define __NBS_H__
|
||||||
|
|
||||||
|
#include "cells.H"
|
||||||
|
#include "contactSearchFunctions.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename executionSpace,
|
||||||
|
typename idType,
|
||||||
|
typename indexType=int32
|
||||||
|
>
|
||||||
|
class NBS
|
||||||
|
:
|
||||||
|
public cells<indexType>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
using IdType = idType;
|
||||||
|
|
||||||
|
using IndexType = indexType;
|
||||||
|
|
||||||
|
using Cells = cells<IndexType>;
|
||||||
|
|
||||||
|
using CellType = typename Cells::CellType;
|
||||||
|
|
||||||
|
using ExecutionSpace= executionSpace;
|
||||||
|
|
||||||
|
using memory_space = typename ExecutionSpace::memory_space;
|
||||||
|
|
||||||
|
struct TagBuild{};
|
||||||
|
|
||||||
|
struct TagFindPairs{};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
int32 capacity_ = 1;
|
||||||
|
|
||||||
|
real sizeRatio_ = 1.0;
|
||||||
|
|
||||||
|
int32 updateFrequency_= 1;
|
||||||
|
|
||||||
|
int32 currentIter_ = 0;
|
||||||
|
|
||||||
|
bool performedSearch_ = false;
|
||||||
|
|
||||||
|
ViewType1D<realx3, memory_space> pointPosition_;
|
||||||
|
|
||||||
|
ViewType1D<real, memory_space> diameter_;
|
||||||
|
|
||||||
|
ViewType3D<int32, memory_space> head_;
|
||||||
|
|
||||||
|
ViewType1D<int32, memory_space> next_;
|
||||||
|
|
||||||
|
|
||||||
|
INLINE_FUNCTION_H
|
||||||
|
void nullify()
|
||||||
|
{
|
||||||
|
fill(
|
||||||
|
head_,
|
||||||
|
range(0,this->nx()),
|
||||||
|
range(0,this->ny()),
|
||||||
|
range(0,this->nz()),
|
||||||
|
-1
|
||||||
|
);
|
||||||
|
|
||||||
|
fill(
|
||||||
|
next_,
|
||||||
|
range(0,capacity_),
|
||||||
|
-1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nullify(range nextRng)
|
||||||
|
{
|
||||||
|
fill(
|
||||||
|
head_,
|
||||||
|
range(0,this->nx()),
|
||||||
|
range(0,this->ny()),
|
||||||
|
range(0,this->nz()),
|
||||||
|
-1
|
||||||
|
);
|
||||||
|
|
||||||
|
fill(
|
||||||
|
next_,
|
||||||
|
nextRng,
|
||||||
|
-1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
using mdrPolicyFindPairs =
|
||||||
|
Kokkos::MDRangePolicy<
|
||||||
|
Kokkos::Rank<3>,
|
||||||
|
Kokkos::Schedule<Kokkos::Dynamic>,
|
||||||
|
ExecutionSpace>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void checkAllocateNext(int newCap)
|
||||||
|
{
|
||||||
|
|
||||||
|
if( capacity_ < newCap)
|
||||||
|
{
|
||||||
|
capacity_ = newCap;
|
||||||
|
Kokkos::realloc(next_, capacity_);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void allocateHead()
|
||||||
|
{
|
||||||
|
Kokkos::realloc(head_, this->nx(), this->ny(), this->nz());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool performSearch()
|
||||||
|
{
|
||||||
|
if(currentIter_ % updateFrequency_ == 0)
|
||||||
|
{
|
||||||
|
currentIter_++;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
currentIter_++;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE_FUNCTION_HD
|
||||||
|
void Swap(int32& x, int32& y)
|
||||||
|
{
|
||||||
|
int32 tmp = x;
|
||||||
|
x = y;
|
||||||
|
y = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeNameNV("NBS");
|
||||||
|
|
||||||
|
NBS(
|
||||||
|
const box& domain,
|
||||||
|
real cellSize,
|
||||||
|
const ViewType1D<realx3, memory_space>& position,
|
||||||
|
const ViewType1D<real, memory_space>& diam,
|
||||||
|
int32 initialContainerSize = 1)
|
||||||
|
:
|
||||||
|
Cells(domain, cellSize),
|
||||||
|
pointPosition_(position),
|
||||||
|
diameter_(diam),
|
||||||
|
head_("NBS::head_",1,1,1), //, this->nx(), this->ny(), this->nz()),
|
||||||
|
next_("NBS::next_",1) //,position.size()),
|
||||||
|
{
|
||||||
|
checkAllocateNext(pointPosition_.size());
|
||||||
|
allocateHead();
|
||||||
|
}
|
||||||
|
|
||||||
|
NBS(
|
||||||
|
dictionary dict,
|
||||||
|
const box& domain,
|
||||||
|
real cellSize,
|
||||||
|
const ViewType1D<realx3, memory_space>& position,
|
||||||
|
const ViewType1D<real, memory_space>& diam,
|
||||||
|
int32 initialContainerSize = 1
|
||||||
|
)
|
||||||
|
:
|
||||||
|
Cells(domain, cellSize),
|
||||||
|
pointPosition_(position),
|
||||||
|
diameter_(diam),
|
||||||
|
head_("NBS::head_",1,1,1), //, this->nx(), this->ny(), this->nz()),
|
||||||
|
next_("NBS::next_",1) //,position.size()),
|
||||||
|
{
|
||||||
|
|
||||||
|
updateFrequency_ = max(
|
||||||
|
dict.getVal<int32>("updateFrequency"),1 );
|
||||||
|
|
||||||
|
sizeRatio_ = max(dict.getVal<real>(
|
||||||
|
"sizeRatio"),1.0);
|
||||||
|
|
||||||
|
this->setCellSize(cellSize*sizeRatio_);
|
||||||
|
checkAllocateNext(pointPosition_.size());
|
||||||
|
allocateHead();
|
||||||
|
}
|
||||||
|
|
||||||
|
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_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - 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<typename PairsContainer>
|
||||||
|
bool broadSearch(PairsContainer& pairs, range activeRange, bool force=false)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(force) currentIter_ = 0;
|
||||||
|
performedSearch_ = false;
|
||||||
|
|
||||||
|
if( !performSearch() ) return true;
|
||||||
|
|
||||||
|
build(activeRange);
|
||||||
|
|
||||||
|
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<typename PairsContainer, typename IncludeFunction>
|
||||||
|
bool broadSearch(PairsContainer& pairs, range activeRange, IncludeFunction incld, bool force = false)
|
||||||
|
{
|
||||||
|
if(force) currentIter_ = 0;
|
||||||
|
performedSearch_ = false;
|
||||||
|
|
||||||
|
if( !performSearch() ) return true;
|
||||||
|
|
||||||
|
build(activeRange, incld);
|
||||||
|
|
||||||
|
findPairs(pairs);
|
||||||
|
|
||||||
|
performedSearch_ = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - build based on all points in range [0, numPoints_)
|
||||||
|
INLINE_FUNCTION_H
|
||||||
|
void build(range activeRange)
|
||||||
|
{
|
||||||
|
checkAllocateNext(activeRange.second);
|
||||||
|
nullify(activeRange);
|
||||||
|
|
||||||
|
Cells cellIndex = static_cast<Cells>(*this);
|
||||||
|
auto points = pointPosition_;
|
||||||
|
auto next = next_;
|
||||||
|
auto head = head_;
|
||||||
|
|
||||||
|
Kokkos::RangePolicy<
|
||||||
|
Kokkos::IndexType<int32>,
|
||||||
|
Kokkos::Schedule<Kokkos::Static>,
|
||||||
|
ExecutionSpace> rPolicy(activeRange.first, activeRange.second);
|
||||||
|
|
||||||
|
Kokkos::parallel_for(
|
||||||
|
"NBS::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<typename IncludeFunction>
|
||||||
|
INLINE_FUNCTION_H
|
||||||
|
void build(range activeRange, IncludeFunction incld)
|
||||||
|
{
|
||||||
|
checkAllocateNext(activeRange.second);
|
||||||
|
nullify(activeRange);
|
||||||
|
|
||||||
|
Cells cellIndex = static_cast<Cells>(*this);
|
||||||
|
auto points = pointPosition_;
|
||||||
|
auto next = next_;
|
||||||
|
auto head = head_;
|
||||||
|
|
||||||
|
Kokkos::RangePolicy<
|
||||||
|
Kokkos::IndexType<int32>,
|
||||||
|
Kokkos::Schedule<Kokkos::Dynamic>,
|
||||||
|
ExecutionSpace> rPolicy(activeRange.first, activeRange.second);
|
||||||
|
|
||||||
|
Kokkos::parallel_for(
|
||||||
|
"NBS::build",
|
||||||
|
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();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PairsContainer>
|
||||||
|
INLINE_FUNCTION_H
|
||||||
|
bool findPairs(PairsContainer& pairs)
|
||||||
|
{
|
||||||
|
mdrPolicyFindPairs
|
||||||
|
mdrPolicy(
|
||||||
|
{0,0,0},
|
||||||
|
{this->nx(),this->ny(),this->nz()} );
|
||||||
|
|
||||||
|
int32 getFull = 1;
|
||||||
|
|
||||||
|
// loop until the container size fits the numebr of contact pairs
|
||||||
|
while (getFull > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
getFull = 0;
|
||||||
|
|
||||||
|
Kokkos::parallel_reduce (
|
||||||
|
"NBS::broadSearch",
|
||||||
|
mdrPolicy,
|
||||||
|
CLASS_LAMBDA_HD(int32 i, int32 j, int32 k, int32& getFullUpdate){
|
||||||
|
#include "NBSLoop.H"
|
||||||
|
}, getFull);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
Info<< "The contact pair container capacity increased from "<<
|
||||||
|
oldCap << " to "<<pairs.capacity()<<" in NBS."<<endInfo;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Kokkos::fence();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool objectSizeChanged(int32 newSize)
|
||||||
|
{
|
||||||
|
checkAllocateNext(newSize);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*INLINE_FUNCTION_HD
|
||||||
|
void operator()(
|
||||||
|
TagFindPairs,
|
||||||
|
int32 i,
|
||||||
|
int32 j,
|
||||||
|
int32 k,
|
||||||
|
int32& getFullUpdate)const
|
||||||
|
{
|
||||||
|
|
||||||
|
int32 m = head_(i,j,k);
|
||||||
|
CellType currentCell(i,j,k);
|
||||||
|
int32 n = -1;
|
||||||
|
|
||||||
|
while( m > -1 )
|
||||||
|
{
|
||||||
|
|
||||||
|
auto p_m = pointPosition_[m];
|
||||||
|
auto d_m = sizeRatio_* diameter_[m];
|
||||||
|
|
||||||
|
// the same cell
|
||||||
|
n = next_(m);
|
||||||
|
|
||||||
|
while(n >-1)
|
||||||
|
{
|
||||||
|
|
||||||
|
auto p_n = pointPosition_[n];
|
||||||
|
auto d_n = sizeRatio_*diameter_[n];
|
||||||
|
|
||||||
|
if( sphereSphereCheck(p_m, p_n, d_m, d_n) )
|
||||||
|
{
|
||||||
|
auto ln = n;
|
||||||
|
auto lm = m;
|
||||||
|
if(lm>ln) Swap(lm,ln);
|
||||||
|
if( auto res = pairs_.insert(lm,ln); res <0)
|
||||||
|
{
|
||||||
|
getFullUpdate++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
n = next_(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// neighbor cells
|
||||||
|
CellType neighborCell;
|
||||||
|
for(int32 ni=0; ni<13; ni++)
|
||||||
|
{
|
||||||
|
if(ni==0) neighborCell = currentCell + CellType( 0, 0,-1);
|
||||||
|
else if(ni==1) neighborCell = currentCell + CellType(-1, 0,-1);
|
||||||
|
else if(ni==2) neighborCell = currentCell + CellType(-1, 0, 0);
|
||||||
|
else if(ni==3) neighborCell = currentCell + CellType(-1, 0, 1);
|
||||||
|
else if(ni==4) neighborCell = currentCell + CellType( 0,-1,-1);
|
||||||
|
else if(ni==5) neighborCell = currentCell + CellType( 0,-1, 0);
|
||||||
|
else if(ni==6) neighborCell = currentCell + CellType( 0,-1, 1);
|
||||||
|
else if(ni==7) neighborCell = currentCell + CellType(-1,-1,-1);
|
||||||
|
else if(ni==8) neighborCell = currentCell + CellType(-1,-1, 0);
|
||||||
|
else if(ni==9) neighborCell = currentCell + CellType(-1,-1, 1);
|
||||||
|
else if(ni==10) neighborCell = currentCell + CellType( 1,-1,-1);
|
||||||
|
else if(ni==11) neighborCell = currentCell + CellType( 1,-1, 0);
|
||||||
|
else if(ni==12) neighborCell = currentCell + CellType( 1,-1, 1);
|
||||||
|
|
||||||
|
if( this->isInRange(neighborCell) )
|
||||||
|
{
|
||||||
|
|
||||||
|
n = head_(neighborCell.x(), neighborCell.y(), neighborCell.z());
|
||||||
|
while( n>-1)
|
||||||
|
{
|
||||||
|
|
||||||
|
auto p_n = pointPosition_[n];
|
||||||
|
auto d_n = sizeRatio_*diameter_[n];
|
||||||
|
|
||||||
|
if(sphereSphereCheck(p_m, p_n, d_m, d_n))
|
||||||
|
{
|
||||||
|
auto ln = n;
|
||||||
|
auto lm = m;
|
||||||
|
if(lm>ln) Swap(lm,ln);
|
||||||
|
if( auto res = pairs_.insert(lm,ln); res <0)
|
||||||
|
{
|
||||||
|
getFullUpdate++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n = next_[n];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
m = next_[m];
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
template <typename PairsContainer, typename teamMemberType>
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
int32 addPointsInBoxToList(
|
||||||
|
const teamMemberType& teamMember,
|
||||||
|
IdType id,
|
||||||
|
const iBox<IndexType>& triBox,
|
||||||
|
const PairsContainer& pairs)const
|
||||||
|
{
|
||||||
|
int32 getFull = 0;
|
||||||
|
|
||||||
|
auto bExtent = boxExtent(triBox);
|
||||||
|
int32 numCellBox = bExtent.x()*bExtent.y()*bExtent.z();
|
||||||
|
|
||||||
|
const auto head = head_;
|
||||||
|
const auto next = next_;
|
||||||
|
|
||||||
|
// perform a loop over all cells in the triBox
|
||||||
|
Kokkos::parallel_reduce(
|
||||||
|
Kokkos::TeamThreadRange(teamMember,numCellBox),
|
||||||
|
[=](int32 linIndex, int32& valToUpdate){
|
||||||
|
|
||||||
|
CellType cell;
|
||||||
|
indexToCell(linIndex, triBox, cell);
|
||||||
|
|
||||||
|
int32 n = head(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<IdType>(n), id) < 0 )
|
||||||
|
valToUpdate++;
|
||||||
|
n = next(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
getFull
|
||||||
|
);
|
||||||
|
|
||||||
|
return getFull;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
100
src/Interaction/contactSearch/methods/NBSLoop.H
Normal file
100
src/Interaction/contactSearch/methods/NBSLoop.H
Normal file
@ -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.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
int32 m = head_(i,j,k);
|
||||||
|
CellType currentCell(i,j,k);
|
||||||
|
int32 n = -1;
|
||||||
|
|
||||||
|
while( m > -1 )
|
||||||
|
{
|
||||||
|
|
||||||
|
auto p_m = pointPosition_[m];
|
||||||
|
auto d_m = sizeRatio_* diameter_[m];
|
||||||
|
|
||||||
|
// the same cell
|
||||||
|
n = next_(m);
|
||||||
|
|
||||||
|
while(n >-1)
|
||||||
|
{
|
||||||
|
|
||||||
|
auto p_n = pointPosition_[n];
|
||||||
|
auto d_n = sizeRatio_*diameter_[n];
|
||||||
|
|
||||||
|
if( sphereSphereCheck(p_m, p_n, d_m, d_n) )
|
||||||
|
{
|
||||||
|
auto ln = n;
|
||||||
|
auto lm = m;
|
||||||
|
if(lm>ln) Swap(lm,ln);
|
||||||
|
if( auto res = pairs.insert(lm,ln); res <0)
|
||||||
|
{
|
||||||
|
getFullUpdate++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
n = next_(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// neighbor cells
|
||||||
|
CellType neighborCell;
|
||||||
|
for(int32 ni=0; ni<13; ni++)
|
||||||
|
{
|
||||||
|
if(ni==0) neighborCell = currentCell + CellType( 0, 0,-1);
|
||||||
|
else if(ni==1) neighborCell = currentCell + CellType(-1, 0,-1);
|
||||||
|
else if(ni==2) neighborCell = currentCell + CellType(-1, 0, 0);
|
||||||
|
else if(ni==3) neighborCell = currentCell + CellType(-1, 0, 1);
|
||||||
|
else if(ni==4) neighborCell = currentCell + CellType( 0,-1,-1);
|
||||||
|
else if(ni==5) neighborCell = currentCell + CellType( 0,-1, 0);
|
||||||
|
else if(ni==6) neighborCell = currentCell + CellType( 0,-1, 1);
|
||||||
|
else if(ni==7) neighborCell = currentCell + CellType(-1,-1,-1);
|
||||||
|
else if(ni==8) neighborCell = currentCell + CellType(-1,-1, 0);
|
||||||
|
else if(ni==9) neighborCell = currentCell + CellType(-1,-1, 1);
|
||||||
|
else if(ni==10) neighborCell = currentCell + CellType( 1,-1,-1);
|
||||||
|
else if(ni==11) neighborCell = currentCell + CellType( 1,-1, 0);
|
||||||
|
else if(ni==12) neighborCell = currentCell + CellType( 1,-1, 1);
|
||||||
|
|
||||||
|
if( this->isInRange(neighborCell) )
|
||||||
|
{
|
||||||
|
|
||||||
|
n = head_(neighborCell.x(), neighborCell.y(), neighborCell.z());
|
||||||
|
while( n>-1)
|
||||||
|
{
|
||||||
|
|
||||||
|
auto p_n = pointPosition_[n];
|
||||||
|
auto d_n = sizeRatio_*diameter_[n];
|
||||||
|
|
||||||
|
if(sphereSphereCheck(p_m, p_n, d_m, d_n))
|
||||||
|
{
|
||||||
|
auto ln = n;
|
||||||
|
auto lm = m;
|
||||||
|
if(lm>ln) Swap(lm,ln);
|
||||||
|
if( auto res = pairs.insert(lm,ln); res <0)
|
||||||
|
{
|
||||||
|
getFullUpdate++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n = next_[n];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
m = next_[m];
|
||||||
|
}
|
||||||
|
|
338
src/Interaction/contactSearch/wallMappings/cellsSimple.H
Normal file
338
src/Interaction/contactSearch/wallMappings/cellsSimple.H
Normal file
@ -0,0 +1,338 @@
|
|||||||
|
/*------------------------------- 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 __cellsSimple_H__
|
||||||
|
#define __cellsSimple_H__
|
||||||
|
|
||||||
|
#include "types.H"
|
||||||
|
#include "KokkosTypes.H"
|
||||||
|
#include "cells.H"
|
||||||
|
#include "iBox.H"
|
||||||
|
#include "dictionary.H"
|
||||||
|
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename executionSpace,
|
||||||
|
typename idType,
|
||||||
|
typename indexType = int32
|
||||||
|
>
|
||||||
|
class cellsSimple
|
||||||
|
:
|
||||||
|
public cells<indexType>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
using IdType = idType;
|
||||||
|
|
||||||
|
using IndexType = indexType;
|
||||||
|
|
||||||
|
using Cells = cells<IndexType>;
|
||||||
|
|
||||||
|
using CellType = typename Cells::CellType;
|
||||||
|
|
||||||
|
using ExecutionSpace = executionSpace;
|
||||||
|
|
||||||
|
using memory_space = typename ExecutionSpace::memory_space;
|
||||||
|
|
||||||
|
using iBoxType = iBox<IndexType>;
|
||||||
|
|
||||||
|
bool constexpr static LOOP_ELEMENT_RANGE = true;
|
||||||
|
|
||||||
|
class TagFindCellRange2{};
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// - box extent
|
||||||
|
real cellExtent_ = 0.6;
|
||||||
|
|
||||||
|
// - update frequency
|
||||||
|
int32 updateFrequency_=1;
|
||||||
|
|
||||||
|
|
||||||
|
int32 currentIter_ = 0;
|
||||||
|
|
||||||
|
// - number of triangle elements
|
||||||
|
int32 numElements_ = 0;
|
||||||
|
|
||||||
|
// - number of points
|
||||||
|
int32 numPoints_ = 0;
|
||||||
|
|
||||||
|
/// a broad search has been occured during last pass?
|
||||||
|
bool performedSearch_ = false;
|
||||||
|
|
||||||
|
// - ref to vectices
|
||||||
|
ViewType1D<int32x3, memory_space> vertices_;
|
||||||
|
|
||||||
|
// - ref to points in the trisurface
|
||||||
|
ViewType1D<realx3, memory_space> points_;
|
||||||
|
|
||||||
|
// cell range of element/triangle bounding box
|
||||||
|
ViewType1D<iBoxType, memory_space> elementBox_;
|
||||||
|
|
||||||
|
|
||||||
|
using tpPWContactSearch = Kokkos::TeamPolicy<
|
||||||
|
ExecutionSpace,
|
||||||
|
Kokkos::Schedule<Kokkos::Dynamic>,
|
||||||
|
Kokkos::IndexType<int32>
|
||||||
|
>;
|
||||||
|
|
||||||
|
using rpFindCellRange2Type =
|
||||||
|
Kokkos::RangePolicy<TagFindCellRange2, ExecutionSpace, Kokkos::IndexType<int32>>;
|
||||||
|
|
||||||
|
|
||||||
|
FUNCTION_H
|
||||||
|
void allocateArrays()
|
||||||
|
{
|
||||||
|
Kokkos::realloc( elementBox_, numElements_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool performSearch()
|
||||||
|
{
|
||||||
|
if(currentIter_ % updateFrequency_ == 0)
|
||||||
|
{
|
||||||
|
currentIter_++;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
currentIter_++;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeNameNV("cellsSimple");
|
||||||
|
|
||||||
|
FUNCTION_H
|
||||||
|
cellsSimple(
|
||||||
|
Cells ppCells,
|
||||||
|
real cellExtent,
|
||||||
|
int32 numPoints,
|
||||||
|
int32 numElements,
|
||||||
|
const ViewType1D<realx3,memory_space>& points,
|
||||||
|
const ViewType1D<int32x3,memory_space>& vertices
|
||||||
|
)
|
||||||
|
:
|
||||||
|
Cells(ppCells),
|
||||||
|
cellExtent_( max(cellExtent, 0.6 ) ),
|
||||||
|
numElements_(numElements),
|
||||||
|
numPoints_(numPoints),
|
||||||
|
vertices_(vertices),
|
||||||
|
points_(points)
|
||||||
|
{
|
||||||
|
|
||||||
|
allocateArrays();
|
||||||
|
}
|
||||||
|
|
||||||
|
cellsSimple(
|
||||||
|
dictionary dict,
|
||||||
|
Cells ppCells,
|
||||||
|
int32 numPoints,
|
||||||
|
int32 numElements,
|
||||||
|
const ViewType1D<realx3,memory_space>& points,
|
||||||
|
const ViewType1D<int32x3,memory_space>& vertices
|
||||||
|
)
|
||||||
|
:
|
||||||
|
Cells(ppCells),
|
||||||
|
numElements_(numElements),
|
||||||
|
numPoints_(numPoints),
|
||||||
|
vertices_(vertices),
|
||||||
|
points_(points)
|
||||||
|
{
|
||||||
|
|
||||||
|
updateFrequency_ = dict.getVal<int32>(
|
||||||
|
"updateFrequency" );
|
||||||
|
updateFrequency_ = max(updateFrequency_,1);
|
||||||
|
|
||||||
|
cellExtent_ = dict.getVal<real>(
|
||||||
|
"cellExtent");
|
||||||
|
|
||||||
|
cellExtent_ = max(cellExtent_,0.6);
|
||||||
|
|
||||||
|
allocateArrays();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool loopElementRange()const
|
||||||
|
{
|
||||||
|
return LOOP_ELEMENT_RANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - host call
|
||||||
|
// reset triangle elements if they have changed
|
||||||
|
FUNCTION_H
|
||||||
|
bool resetElements(
|
||||||
|
int32 numElements,
|
||||||
|
int32 numPoints,
|
||||||
|
ViewType1D<realx3, memory_space>& points,
|
||||||
|
ViewType1D<int32x3, memory_space>& 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_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool enterBoadSearch()const
|
||||||
|
{
|
||||||
|
return currentIter_%updateFrequency_==0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool performedSearch()const
|
||||||
|
{
|
||||||
|
return performedSearch_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PairsContainer, typename particleMapType>
|
||||||
|
bool broadSearch(PairsContainer& pairs, particleMapType& particleMap, bool force=false)
|
||||||
|
{
|
||||||
|
if(force) currentIter_ = 0;
|
||||||
|
performedSearch_= false;
|
||||||
|
if(!performSearch())return true;
|
||||||
|
|
||||||
|
// map walls onto the cells
|
||||||
|
this->build();
|
||||||
|
|
||||||
|
this->particleWallFindPairs(pairs, particleMap);
|
||||||
|
|
||||||
|
performedSearch_ = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool build()
|
||||||
|
{
|
||||||
|
Kokkos::parallel_for(
|
||||||
|
"cellsSimple::findcellrange2",
|
||||||
|
rpFindCellRange2Type(0,numElements_),
|
||||||
|
*this);
|
||||||
|
Kokkos::fence();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PairsContainer, typename particleMapType>
|
||||||
|
bool particleWallFindPairs(PairsContainer& pairs, particleMapType& particleMap)
|
||||||
|
{
|
||||||
|
|
||||||
|
int32 getFull = 1;
|
||||||
|
|
||||||
|
while (getFull)
|
||||||
|
{
|
||||||
|
|
||||||
|
getFull = findPairsElementRange(pairs, particleMap);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
Info<<"Contact pair container capacity increased from "<<
|
||||||
|
oldCap << " to "
|
||||||
|
<< pairs.capacity() <<" in cellsSimple."<<endInfo;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Kokkos::fence();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PairsContainer, typename particleMapType>
|
||||||
|
int32 findPairsElementRange(PairsContainer& pairs, particleMapType& particleMap)
|
||||||
|
{
|
||||||
|
int32 getFull =0;
|
||||||
|
|
||||||
|
const auto pwPairs = pairs;
|
||||||
|
const auto elementBox = elementBox_;
|
||||||
|
|
||||||
|
|
||||||
|
Kokkos::parallel_reduce(
|
||||||
|
"cellsSimple::findPairsElementRange",
|
||||||
|
tpPWContactSearch(numElements_, Kokkos::AUTO),
|
||||||
|
LAMBDA_HD(
|
||||||
|
const typename tpPWContactSearch::member_type & teamMember,
|
||||||
|
int32& valueToUpdate){
|
||||||
|
int32 i = teamMember.league_rank();
|
||||||
|
IdType id = i;
|
||||||
|
const auto triBox = elementBox[i];
|
||||||
|
|
||||||
|
valueToUpdate +=
|
||||||
|
particleMap.addPointsInBoxToList(
|
||||||
|
teamMember,
|
||||||
|
id,
|
||||||
|
triBox,
|
||||||
|
pwPairs
|
||||||
|
);
|
||||||
|
},
|
||||||
|
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);
|
||||||
|
//output<< minP << " maxP "<< maxP<<endl;
|
||||||
|
elementBox_[i] = iBoxType(this->pointIndex(minP), this->pointIndex(maxP));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
59
src/Interaction/interaction/demInteraction.H
Normal file
59
src/Interaction/interaction/demInteraction.H
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __demInteraction_H__
|
||||||
|
#define __demInteraction_H__
|
||||||
|
|
||||||
|
#include "property.H"
|
||||||
|
#include "demComponent.H"
|
||||||
|
#include "pointFields.H"
|
||||||
|
#include "triSurfaceFields.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
class demInteraction
|
||||||
|
:
|
||||||
|
public property,
|
||||||
|
public demComponent
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
public:
|
||||||
|
demInteraction(systemControl& control)
|
||||||
|
:
|
||||||
|
property(),
|
||||||
|
demComponent("interaction", control)
|
||||||
|
{}
|
||||||
|
|
||||||
|
demInteraction(systemControl& control, const fileSystem& file)
|
||||||
|
:
|
||||||
|
property(file),
|
||||||
|
demComponent("interaction", control)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //__interaction_H__
|
107
src/Interaction/interaction/interaction.C
Normal file
107
src/Interaction/interaction/interaction.C
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "interaction.H"
|
||||||
|
|
||||||
|
|
||||||
|
pFlow::interaction::interaction
|
||||||
|
(
|
||||||
|
systemControl& control,
|
||||||
|
const particles& prtcl,
|
||||||
|
const geometry& geom
|
||||||
|
)
|
||||||
|
:
|
||||||
|
demInteraction(control, control.caseSetup().path()+interactionFile__),
|
||||||
|
interactionBase(prtcl, geom),
|
||||||
|
fileDict_(control.caseSetup().emplaceObject<dictionary>(
|
||||||
|
objectFile(
|
||||||
|
interactionFile__,
|
||||||
|
"",
|
||||||
|
objectFile::READ_ALWAYS,
|
||||||
|
objectFile::WRITE_NEVER),
|
||||||
|
interactionFile__,
|
||||||
|
true ))
|
||||||
|
{
|
||||||
|
this->subscribe(prtcl.pStruct());
|
||||||
|
|
||||||
|
contactSearch_ = contactSearch::create(
|
||||||
|
fileDict_.subDict("contactSearch"),
|
||||||
|
this->control().domain(),
|
||||||
|
prtcl,
|
||||||
|
geom,
|
||||||
|
timers()
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pFlow::uniquePtr<pFlow::interaction> pFlow::interaction::create
|
||||||
|
(
|
||||||
|
systemControl& control,
|
||||||
|
const particles& prtcl,
|
||||||
|
const geometry& geom
|
||||||
|
)
|
||||||
|
{
|
||||||
|
word shapeTypeName = prtcl.shapeTypeName();
|
||||||
|
word motionTypeName = geom.motionModelTypeName();
|
||||||
|
|
||||||
|
fileSystem file = control.caseSetup().path()+interactionFile__;
|
||||||
|
|
||||||
|
dictionary dict(interactionFile__, file);
|
||||||
|
auto interactionDict= dict.subDict("model");
|
||||||
|
|
||||||
|
word clType = dict.getVal<word>("contactListType");
|
||||||
|
word cfModel = interactionDict.getVal<word>("contactForceModel");
|
||||||
|
word rfModel = interactionDict.getVal<word>("rollingFrictionModel");
|
||||||
|
|
||||||
|
|
||||||
|
auto interactionModel = angleBracketsNames3(
|
||||||
|
shapeTypeName+"Interaction",
|
||||||
|
angleBracketsNames(rfModel,cfModel),
|
||||||
|
motionTypeName,
|
||||||
|
clType);
|
||||||
|
|
||||||
|
|
||||||
|
Report(1)<< "Selecting interaction model..."<<endReport;
|
||||||
|
if( systemControlvCtorSelector_.search(interactionModel) )
|
||||||
|
{
|
||||||
|
auto objPtr =
|
||||||
|
systemControlvCtorSelector_[interactionModel]
|
||||||
|
(control, prtcl, geom);
|
||||||
|
|
||||||
|
Report(2)<<"Model "<<greenText(interactionModel)<<" is created."<<endReport;
|
||||||
|
return objPtr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printKeys
|
||||||
|
(
|
||||||
|
fatalError << "Ctor Selector "<<
|
||||||
|
interactionModel << " dose not exist. \n"
|
||||||
|
<<"Avaiable ones are: \n\n"
|
||||||
|
,
|
||||||
|
systemControlvCtorSelector_
|
||||||
|
);
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
}
|
109
src/Interaction/interaction/interaction.H
Normal file
109
src/Interaction/interaction/interaction.H
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*------------------------------- 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 __interaction_H__
|
||||||
|
#define __interaction_H__
|
||||||
|
|
||||||
|
#include "demInteraction.H"
|
||||||
|
#include "eventObserver.H"
|
||||||
|
#include "interactionBase.H"
|
||||||
|
#include "contactSearch.H"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
class interaction
|
||||||
|
:
|
||||||
|
public demInteraction,
|
||||||
|
public eventObserver,
|
||||||
|
public interactionBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
using IdType = typename interactionBase::IdType;
|
||||||
|
|
||||||
|
using IndexType = typename interactionBase::IndexType;
|
||||||
|
|
||||||
|
using ExecutionSpace = typename interactionBase::ExecutionSpace;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/// interaction file dictionary
|
||||||
|
dictionary& fileDict_;
|
||||||
|
|
||||||
|
/// contact search object for pp and pw interactions
|
||||||
|
uniquePtr<contactSearch> contactSearch_ = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeName("interaction");
|
||||||
|
|
||||||
|
|
||||||
|
//// - constructors
|
||||||
|
|
||||||
|
interaction(
|
||||||
|
systemControl& control,
|
||||||
|
const particles& prtcl,
|
||||||
|
const geometry& geom );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
virtual ~interaction() = default;
|
||||||
|
|
||||||
|
create_vCtor(
|
||||||
|
interaction,
|
||||||
|
systemControl,
|
||||||
|
(
|
||||||
|
systemControl& control,
|
||||||
|
const particles& prtcl,
|
||||||
|
const geometry& geom
|
||||||
|
),
|
||||||
|
(control, prtcl, geom)
|
||||||
|
);
|
||||||
|
|
||||||
|
auto& contactSearchPtr()
|
||||||
|
{
|
||||||
|
return contactSearch_;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& contactSearchRef()
|
||||||
|
{
|
||||||
|
return contactSearch_();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& fileDict()const
|
||||||
|
{
|
||||||
|
return fileDict_;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
uniquePtr<interaction> create(
|
||||||
|
systemControl& control,
|
||||||
|
const particles& prtcl,
|
||||||
|
const geometry& geom);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //__interaction_H__
|
84
src/Interaction/interaction/interactionBase.H
Normal file
84
src/Interaction/interaction/interactionBase.H
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/*------------------------------- 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 __interactionBase_H__
|
||||||
|
#define __interactionBase_H__
|
||||||
|
|
||||||
|
#include "interactionTypes.H"
|
||||||
|
#include "particles.H"
|
||||||
|
#include "geometry.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
class interactionBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
using IndexType = CELL_INDEX_TYPE;
|
||||||
|
|
||||||
|
using IdType = ID_TYPE;
|
||||||
|
|
||||||
|
using ExecutionSpace = DefaultExecutionSpace;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
const particles& particles_;
|
||||||
|
|
||||||
|
const geometry& geometry_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
interactionBase(
|
||||||
|
const particles& prtcl,
|
||||||
|
const geometry& geom)
|
||||||
|
:
|
||||||
|
particles_(prtcl),
|
||||||
|
geometry_(geom)
|
||||||
|
{}
|
||||||
|
|
||||||
|
inline
|
||||||
|
const auto& pStruct()const
|
||||||
|
{
|
||||||
|
return particles_.pStruct();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
const auto& surface()const
|
||||||
|
{
|
||||||
|
return geometry_.surface();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
const auto& Particles()const
|
||||||
|
{
|
||||||
|
return particles_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto& Geometry()const
|
||||||
|
{
|
||||||
|
return geometry_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //__interactionBase_H__
|
45
src/Interaction/interaction/interactionTypes.H
Normal file
45
src/Interaction/interaction/interactionTypes.H
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __interactionTypes_H__
|
||||||
|
#define __interactionTypes_H__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "types.H"
|
||||||
|
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
// always use signed types
|
||||||
|
using CELL_INDEX_TYPE = int32;
|
||||||
|
|
||||||
|
using ID_TYPE = int32;
|
||||||
|
|
||||||
|
//constexpr int32 minCellIndex = largestNegative<CELL_INDEX_TYPE>();
|
||||||
|
|
||||||
|
//constexpr int32 maxCellIndex = largestPositive<CELL_INDEX_TYPE>();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //__interactionTypes_H__
|
107
src/Interaction/sphereInteraction/pLine.H
Normal file
107
src/Interaction/sphereInteraction/pLine.H
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __pLine_H__
|
||||||
|
#define __pLine_H__
|
||||||
|
|
||||||
|
#include "types.H"
|
||||||
|
|
||||||
|
namespace pFlow::sphTriInteraction
|
||||||
|
{
|
||||||
|
|
||||||
|
struct pLine
|
||||||
|
{
|
||||||
|
|
||||||
|
realx3 p1_; // point 1
|
||||||
|
realx3 p2_; // piont 2
|
||||||
|
realx3 v_; // direction vector
|
||||||
|
real L_; // line lenght
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
pLine(){}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
pLine(const realx3 &p1, const realx3 &p2)
|
||||||
|
:
|
||||||
|
p1_(p1),
|
||||||
|
p2_(p2),
|
||||||
|
v_(p2-p1),
|
||||||
|
L_(length(v_))
|
||||||
|
{}
|
||||||
|
|
||||||
|
// get a point on the line based on input 0<= t <= 1
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
realx3 point(real t)const {
|
||||||
|
return v_ * t + p1_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the projected point of point p on line
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
realx3 projectPoint(const realx3 &p) const
|
||||||
|
{
|
||||||
|
return point(projectNormLength(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculates the normalized distance between projected p and p1
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
real projectNormLength(realx3 p) const
|
||||||
|
{
|
||||||
|
realx3 w = p - p1_;
|
||||||
|
return dot(w,v_) / (L_*L_);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool lineSphereCheck(
|
||||||
|
const realx3 pos,
|
||||||
|
real Rad,
|
||||||
|
realx3 &nv,
|
||||||
|
realx3 &cp,
|
||||||
|
real &ovrlp)const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
real t = projectNormLength(pos);
|
||||||
|
|
||||||
|
if(t >= 0.0 && t <= 1.0) cp = point(t);
|
||||||
|
else if(t >= (-Rad / L_) && t < 0.0) cp = point(0.0);
|
||||||
|
else if(t>1.0 && t >= (1.0 + Rad / L_)) cp = point(1.0);
|
||||||
|
else return false;
|
||||||
|
|
||||||
|
realx3 vec = pos - cp; // from cp to pos
|
||||||
|
|
||||||
|
real dist = length(vec);
|
||||||
|
ovrlp = Rad - dist;
|
||||||
|
|
||||||
|
if (ovrlp >= 0.0)
|
||||||
|
{
|
||||||
|
if (dist > 0)
|
||||||
|
nv = vec / dist;
|
||||||
|
else
|
||||||
|
nv = v_;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} //pFlow::sphTriInteractio
|
||||||
|
|
||||||
|
#endif
|
128
src/Interaction/sphereInteraction/sphereInteraction.C
Normal file
128
src/Interaction/sphereInteraction/sphereInteraction.C
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename contactForceModel,
|
||||||
|
typename geometryMotionModel,
|
||||||
|
template <class, class, class> class contactListType >
|
||||||
|
bool pFlow::sphereInteraction<contactForceModel,geometryMotionModel, contactListType>::
|
||||||
|
createSphereInteraction()
|
||||||
|
{
|
||||||
|
|
||||||
|
realVector_D rhoD(this->densities());
|
||||||
|
|
||||||
|
auto modelDict = this->fileDict().subDict("model");
|
||||||
|
|
||||||
|
Report(1)<<"Createing contact force model . . ."<<endReport;
|
||||||
|
forceModel_ = makeUnique<ContactForceModel>(
|
||||||
|
this->numMaterials(),
|
||||||
|
rhoD.deviceVector(),
|
||||||
|
modelDict );
|
||||||
|
|
||||||
|
|
||||||
|
uint32 nPrtcl = sphParticles_.size();
|
||||||
|
|
||||||
|
ppContactList_ = makeUnique<ContactListType>(nPrtcl+1);
|
||||||
|
|
||||||
|
pwContactList_ = makeUnique<ContactListType>(nPrtcl/4+1);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename contactForceModel,
|
||||||
|
typename geometryMotionModel,
|
||||||
|
template <class, class, class> class contactListType >
|
||||||
|
bool pFlow::sphereInteraction<contactForceModel,geometryMotionModel, contactListType>::
|
||||||
|
sphereSphereInteraction()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
auto lastItem = ppContactList_().loopCount();
|
||||||
|
|
||||||
|
// create the kernel functor
|
||||||
|
pFlow::sphereInteractionKernels::ppInteractionFunctor
|
||||||
|
ppInteraction(
|
||||||
|
this->dt(),
|
||||||
|
this->forceModel_(),
|
||||||
|
ppContactList_(), // to be read
|
||||||
|
sphParticles_.diameter().deviceVectorAll(),
|
||||||
|
sphParticles_.propertyId().deviceVectorAll(),
|
||||||
|
sphParticles_.pointPosition().deviceVectorAll(),
|
||||||
|
sphParticles_.velocity().deviceVectorAll(),
|
||||||
|
sphParticles_.rVelocity().deviceVectorAll(),
|
||||||
|
sphParticles_.contactForce().deviceVectorAll(),
|
||||||
|
sphParticles_.contactTorque().deviceVectorAll()
|
||||||
|
);
|
||||||
|
|
||||||
|
Kokkos::parallel_for(
|
||||||
|
"",
|
||||||
|
rpPPInteraction(0,lastItem),
|
||||||
|
ppInteraction
|
||||||
|
);
|
||||||
|
|
||||||
|
Kokkos::fence();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename contactForceModel,
|
||||||
|
typename geometryMotionModel,
|
||||||
|
template <class, class, class> class contactListType >
|
||||||
|
bool pFlow::sphereInteraction<contactForceModel,geometryMotionModel, contactListType>::
|
||||||
|
sphereWallInteraction()
|
||||||
|
{
|
||||||
|
|
||||||
|
int32 lastItem = pwContactList_().loopCount();
|
||||||
|
|
||||||
|
pFlow::sphereInteractionKernels::pwInteractionFunctor
|
||||||
|
pwInteraction(
|
||||||
|
this->dt(),
|
||||||
|
this->forceModel_(),
|
||||||
|
pwContactList_(),
|
||||||
|
geometryMotion_.getTriangleAccessor(),
|
||||||
|
geometryMotion_.getModel() ,
|
||||||
|
sphParticles_.diameter().deviceVectorAll() ,
|
||||||
|
sphParticles_.propertyId().deviceVectorAll(),
|
||||||
|
sphParticles_.pointPosition().deviceVectorAll(),
|
||||||
|
sphParticles_.velocity().deviceVectorAll(),
|
||||||
|
sphParticles_.rVelocity().deviceVectorAll() ,
|
||||||
|
sphParticles_.contactForce().deviceVectorAll(),
|
||||||
|
sphParticles_.contactTorque().deviceVectorAll() ,
|
||||||
|
geometryMotion_.triMotionIndex().deviceVectorAll(),
|
||||||
|
geometryMotion_.propertyId().deviceVectorAll(),
|
||||||
|
geometryMotion_.contactForceWall().deviceVectorAll()
|
||||||
|
);
|
||||||
|
|
||||||
|
Kokkos::parallel_for(
|
||||||
|
"",
|
||||||
|
rpPWInteraction(0,lastItem),
|
||||||
|
pwInteraction
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
Kokkos::fence();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
207
src/Interaction/sphereInteraction/sphereInteraction.H
Normal file
207
src/Interaction/sphereInteraction/sphereInteraction.H
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __sphereInteraction_H__
|
||||||
|
#define __sphereInteraction_H__
|
||||||
|
|
||||||
|
#include "interaction.H"
|
||||||
|
#include "sphereParticles.H"
|
||||||
|
|
||||||
|
#include "sphereInteractionKernels.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename contactForceModel,
|
||||||
|
typename geometryMotionModel,
|
||||||
|
template <class, class, class> class contactListType>
|
||||||
|
class sphereInteraction
|
||||||
|
:
|
||||||
|
public interaction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
using GeometryMotionModel = geometryMotionModel;
|
||||||
|
|
||||||
|
using ContactForceModel = contactForceModel;
|
||||||
|
|
||||||
|
using MotionModel = typename geometryMotionModel::MotionModel;
|
||||||
|
|
||||||
|
using ModelStorage = typename ContactForceModel::contactForceStorage;
|
||||||
|
|
||||||
|
using IdType = typename interaction::IdType;
|
||||||
|
|
||||||
|
using IndexType = typename interaction::IndexType;
|
||||||
|
|
||||||
|
using ExecutionSpace = typename interaction::ExecutionSpace;
|
||||||
|
|
||||||
|
using ContactListType =
|
||||||
|
contactListType<ModelStorage, ExecutionSpace, IdType>;
|
||||||
|
|
||||||
|
using PairsContainerType= typename contactSearch::PairContainerType;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/// const reference to geometry
|
||||||
|
const GeometryMotionModel& geometryMotion_;
|
||||||
|
|
||||||
|
/// const reference to particles
|
||||||
|
const sphereParticles& sphParticles_;
|
||||||
|
|
||||||
|
|
||||||
|
/// contact force model
|
||||||
|
uniquePtr<ContactForceModel> forceModel_ = nullptr;
|
||||||
|
|
||||||
|
/// contact list for particle-particle interactoins (keeps the history)
|
||||||
|
uniquePtr<ContactListType> ppContactList_ = nullptr;
|
||||||
|
|
||||||
|
/// contact list for particle-wall interactions (keeps the history)
|
||||||
|
uniquePtr<ContactListType> pwContactList_ = nullptr;
|
||||||
|
|
||||||
|
/// timer for particle-particle interaction computations
|
||||||
|
Timer ppInteractionTimer_;
|
||||||
|
|
||||||
|
/// timer for particle-wall interaction computations
|
||||||
|
Timer pwInteractionTimer_;
|
||||||
|
|
||||||
|
bool createSphereInteraction();
|
||||||
|
|
||||||
|
bool managePPContactLists();
|
||||||
|
|
||||||
|
bool managePWContactLists();
|
||||||
|
|
||||||
|
/// range policy for p-p interaction execution
|
||||||
|
using rpPPInteraction =
|
||||||
|
Kokkos::RangePolicy<Kokkos::IndexType<int32>, Kokkos::Schedule<Kokkos::Dynamic>>;
|
||||||
|
|
||||||
|
/// range policy for p-w interaction execution
|
||||||
|
using rpPWInteraction = rpPPInteraction;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeNameTemplate3("sphereInteraction", ContactForceModel, MotionModel, ContactListType);
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
|
||||||
|
sphereInteraction(
|
||||||
|
systemControl& control,
|
||||||
|
const particles& prtcl,
|
||||||
|
const geometry& geom)
|
||||||
|
:
|
||||||
|
interaction(control, prtcl, geom),
|
||||||
|
geometryMotion_(dynamic_cast<const GeometryMotionModel&>(geom)),
|
||||||
|
sphParticles_(dynamic_cast<const sphereParticles&>(prtcl)),
|
||||||
|
ppInteractionTimer_("sphere-sphere interaction", &this->timers()),
|
||||||
|
pwInteractionTimer_("sphere-wall interaction", &this->timers())
|
||||||
|
{
|
||||||
|
if(!createSphereInteraction())
|
||||||
|
{
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
add_vCtor
|
||||||
|
(
|
||||||
|
interaction,
|
||||||
|
sphereInteraction,
|
||||||
|
systemControl
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
bool beforeIteration() override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool iterate() override
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this->contactSearch_)
|
||||||
|
{
|
||||||
|
if( this->contactSearch_().ppEnterBroadSearch())
|
||||||
|
{
|
||||||
|
ppContactList_().beforeBroadSearch();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this->contactSearch_().pwEnterBroadSearch())
|
||||||
|
{
|
||||||
|
pwContactList_().beforeBroadSearch();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !contactSearch_().broadSearch(
|
||||||
|
ppContactList_(),
|
||||||
|
pwContactList_()) )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"unable to perform broadSearch.\n";
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this->contactSearch_().ppPerformedBroadSearch())
|
||||||
|
{
|
||||||
|
ppContactList_().afterBroadSearch();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this->contactSearch_().pwPerformedBroadSearch())
|
||||||
|
{
|
||||||
|
pwContactList_().afterBroadSearch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sphParticles_.numActive()<=0)return true;
|
||||||
|
|
||||||
|
ppInteractionTimer_.start();
|
||||||
|
sphereSphereInteraction();
|
||||||
|
ppInteractionTimer_.end();
|
||||||
|
|
||||||
|
pwInteractionTimer_.start();
|
||||||
|
sphereWallInteraction();
|
||||||
|
pwInteractionTimer_.end();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool afterIteration() override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool update(const eventMessage& msg)override
|
||||||
|
{
|
||||||
|
// it requires not action regarding any changes in the
|
||||||
|
// point structure
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sphereSphereInteraction();
|
||||||
|
|
||||||
|
bool sphereWallInteraction();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "sphereInteraction.C"
|
||||||
|
|
||||||
|
#endif //__sphereInteraction_H__
|
325
src/Interaction/sphereInteraction/sphereInteractionKernels.H
Normal file
325
src/Interaction/sphereInteraction/sphereInteractionKernels.H
Normal file
@ -0,0 +1,325 @@
|
|||||||
|
/*------------------------------- 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 __sphereInteractionKernels_H__
|
||||||
|
#define __sphereInteractionKernels_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "sphereTriSurfaceContact.H"
|
||||||
|
|
||||||
|
namespace pFlow::sphereInteractionKernels
|
||||||
|
{
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename ContactForceModel,
|
||||||
|
typename ContactListType>
|
||||||
|
struct ppInteractionFunctor
|
||||||
|
{
|
||||||
|
|
||||||
|
using PairType = typename ContactListType::PairType;
|
||||||
|
using ValueType = typename ContactListType::ValueType;
|
||||||
|
|
||||||
|
real dt_;
|
||||||
|
|
||||||
|
ContactForceModel forceModel_;
|
||||||
|
ContactListType tobeFilled_;
|
||||||
|
|
||||||
|
deviceViewType1D<real> diam_;
|
||||||
|
deviceViewType1D<int8> propId_;
|
||||||
|
deviceViewType1D<realx3> pos_;
|
||||||
|
deviceViewType1D<realx3> lVel_;
|
||||||
|
deviceViewType1D<realx3> rVel_;
|
||||||
|
deviceViewType1D<realx3> cForce_;
|
||||||
|
deviceViewType1D<realx3> cTorque_;
|
||||||
|
|
||||||
|
|
||||||
|
ppInteractionFunctor(
|
||||||
|
real dt,
|
||||||
|
ContactForceModel forceModel,
|
||||||
|
ContactListType tobeFilled,
|
||||||
|
deviceViewType1D<real> diam,
|
||||||
|
deviceViewType1D<int8> propId,
|
||||||
|
deviceViewType1D<realx3> pos,
|
||||||
|
deviceViewType1D<realx3> lVel,
|
||||||
|
deviceViewType1D<realx3> rVel,
|
||||||
|
deviceViewType1D<realx3> cForce,
|
||||||
|
deviceViewType1D<realx3> cTorque )
|
||||||
|
:
|
||||||
|
dt_(dt),
|
||||||
|
forceModel_(forceModel),
|
||||||
|
tobeFilled_(tobeFilled),
|
||||||
|
diam_(diam),
|
||||||
|
propId_(propId),
|
||||||
|
pos_(pos),
|
||||||
|
lVel_(lVel),
|
||||||
|
rVel_(rVel),
|
||||||
|
cForce_(cForce), // this is converted to an atomic vector
|
||||||
|
cTorque_(cTorque) // this is converted to an atomic vector
|
||||||
|
{}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
void operator()(const int32 n)const
|
||||||
|
{
|
||||||
|
|
||||||
|
if(!tobeFilled_.isValid(n))return;
|
||||||
|
|
||||||
|
auto [i,j] = tobeFilled_.getPair(n);
|
||||||
|
|
||||||
|
real Ri = 0.5*diam_[i];
|
||||||
|
real Rj = 0.5*diam_[j];
|
||||||
|
realx3 xi = pos_[i];
|
||||||
|
realx3 xj = pos_[j];
|
||||||
|
real dist = length(xj-xi);
|
||||||
|
real ovrlp = (Ri+Rj) - dist;
|
||||||
|
|
||||||
|
if( ovrlp >0.0 )
|
||||||
|
{
|
||||||
|
|
||||||
|
auto Vi = lVel_[i];
|
||||||
|
auto Vj = lVel_[j];
|
||||||
|
auto wi = rVel_[i];
|
||||||
|
auto wj = rVel_[j];
|
||||||
|
auto Nij = (xj-xi)/dist;
|
||||||
|
auto Vr = Vi - Vj + cross((Ri*wi+Rj*wj), Nij);
|
||||||
|
|
||||||
|
auto history = tobeFilled_.getValue(n);
|
||||||
|
|
||||||
|
int32 propId_i = propId_[i];
|
||||||
|
int32 propId_j = propId_[j];
|
||||||
|
|
||||||
|
realx3 FCn, FCt, Mri, Mrj, Mij, Mji;
|
||||||
|
|
||||||
|
// calculates contact force
|
||||||
|
forceModel_.contactForce(
|
||||||
|
dt_, i, j,
|
||||||
|
propId_i, propId_j,
|
||||||
|
Ri, Rj,
|
||||||
|
ovrlp,
|
||||||
|
Vr, Nij,
|
||||||
|
history,
|
||||||
|
FCn, FCt
|
||||||
|
);
|
||||||
|
|
||||||
|
forceModel_.rollingFriction(
|
||||||
|
dt_, i, j,
|
||||||
|
propId_i, propId_j,
|
||||||
|
Ri, Rj,
|
||||||
|
wi, wj,
|
||||||
|
Nij,
|
||||||
|
FCn,
|
||||||
|
Mri, Mrj
|
||||||
|
);
|
||||||
|
|
||||||
|
auto M = cross(Nij,FCt);
|
||||||
|
Mij = Ri*M+Mri;
|
||||||
|
Mji = Rj*M+Mrj;
|
||||||
|
|
||||||
|
auto FC = FCn + FCt;
|
||||||
|
|
||||||
|
Kokkos::atomic_add(&cForce_[i].x_,FC.x_);
|
||||||
|
Kokkos::atomic_add(&cForce_[i].y_,FC.y_);
|
||||||
|
Kokkos::atomic_add(&cForce_[i].z_,FC.z_);
|
||||||
|
|
||||||
|
Kokkos::atomic_add(&cForce_[j].x_,-FC.x_);
|
||||||
|
Kokkos::atomic_add(&cForce_[j].y_,-FC.y_);
|
||||||
|
Kokkos::atomic_add(&cForce_[j].z_,-FC.z_);
|
||||||
|
|
||||||
|
Kokkos::atomic_add(&cTorque_[i].x_, Mij.x_);
|
||||||
|
Kokkos::atomic_add(&cTorque_[i].y_, Mij.y_);
|
||||||
|
Kokkos::atomic_add(&cTorque_[i].z_, Mij.z_);
|
||||||
|
|
||||||
|
Kokkos::atomic_add(&cTorque_[j].x_, Mji.x_);
|
||||||
|
Kokkos::atomic_add(&cTorque_[j].y_, Mji.y_);
|
||||||
|
Kokkos::atomic_add(&cTorque_[j].z_, Mji.z_);
|
||||||
|
|
||||||
|
|
||||||
|
tobeFilled_.setValue(n,history);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tobeFilled_.setValue(n, ValueType());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename ContactForceModel,
|
||||||
|
typename ContactListType,
|
||||||
|
typename TraingleAccessor,
|
||||||
|
typename MotionModel>
|
||||||
|
struct pwInteractionFunctor
|
||||||
|
{
|
||||||
|
using PairType = typename ContactListType::PairType;
|
||||||
|
using ValueType = typename ContactListType::ValueType;
|
||||||
|
|
||||||
|
real dt_;
|
||||||
|
|
||||||
|
ContactForceModel forceModel_;
|
||||||
|
ContactListType tobeFilled_;
|
||||||
|
|
||||||
|
TraingleAccessor triangles_;
|
||||||
|
MotionModel motionModel_;
|
||||||
|
|
||||||
|
deviceViewType1D<real> diam_;
|
||||||
|
deviceViewType1D<int8> propId_;
|
||||||
|
deviceViewType1D<realx3> pos_;
|
||||||
|
deviceViewType1D<realx3> lVel_;
|
||||||
|
deviceViewType1D<realx3> rVel_;
|
||||||
|
deviceViewType1D<realx3> cForce_;
|
||||||
|
deviceViewType1D<realx3> cTorque_;
|
||||||
|
deviceViewType1D<int8> wTriMotionIndex_;
|
||||||
|
deviceViewType1D<int8> wPropId_;
|
||||||
|
deviceViewType1D<realx3> wCForce_;
|
||||||
|
|
||||||
|
|
||||||
|
pwInteractionFunctor(
|
||||||
|
real dt,
|
||||||
|
ContactForceModel forceModel,
|
||||||
|
ContactListType tobeFilled,
|
||||||
|
TraingleAccessor triangles,
|
||||||
|
MotionModel motionModel ,
|
||||||
|
deviceViewType1D<real> diam ,
|
||||||
|
deviceViewType1D<int8> propId,
|
||||||
|
deviceViewType1D<realx3> pos ,
|
||||||
|
deviceViewType1D<realx3> lVel,
|
||||||
|
deviceViewType1D<realx3> rVel,
|
||||||
|
deviceViewType1D<realx3> cForce,
|
||||||
|
deviceViewType1D<realx3> cTorque ,
|
||||||
|
deviceViewType1D<int8> wTriMotionIndex,
|
||||||
|
deviceViewType1D<int8> wPropId,
|
||||||
|
deviceViewType1D<realx3> wCForce)
|
||||||
|
:
|
||||||
|
dt_(dt),
|
||||||
|
forceModel_(forceModel),
|
||||||
|
tobeFilled_(tobeFilled),
|
||||||
|
triangles_(triangles) ,
|
||||||
|
motionModel_(motionModel) ,
|
||||||
|
diam_(diam) ,
|
||||||
|
propId_(propId),
|
||||||
|
pos_(pos) ,
|
||||||
|
lVel_(lVel),
|
||||||
|
rVel_(rVel) ,
|
||||||
|
cForce_(cForce),
|
||||||
|
cTorque_(cTorque) ,
|
||||||
|
wTriMotionIndex_(wTriMotionIndex) ,
|
||||||
|
wPropId_(wPropId),
|
||||||
|
wCForce_(wCForce)
|
||||||
|
{}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
void operator()(const int32 n)const
|
||||||
|
{
|
||||||
|
|
||||||
|
if(!tobeFilled_.isValid(n))return;
|
||||||
|
|
||||||
|
auto [i,tj] = tobeFilled_.getPair(n);
|
||||||
|
|
||||||
|
real Ri = 0.5*diam_[i];
|
||||||
|
real Rj = 10000.0;
|
||||||
|
realx3 xi = pos_[i];
|
||||||
|
|
||||||
|
realx3x3 tri = triangles_(tj);
|
||||||
|
real ovrlp;
|
||||||
|
realx3 Nij, cp;
|
||||||
|
|
||||||
|
if( pFlow::sphTriInteraction::isSphereInContactBothSides(
|
||||||
|
tri, xi, Ri, ovrlp, Nij, cp) )
|
||||||
|
{
|
||||||
|
auto Vi = lVel_[i];
|
||||||
|
auto wi = rVel_[i];
|
||||||
|
|
||||||
|
int32 mInd = wTriMotionIndex_[tj];
|
||||||
|
|
||||||
|
auto Vw = motionModel_(mInd, cp);
|
||||||
|
|
||||||
|
//output<< "par-wall index "<< i<<" - "<< tj<<endl;
|
||||||
|
|
||||||
|
auto Vr = Vi - Vw + cross(Ri*wi, Nij);
|
||||||
|
|
||||||
|
auto history = tobeFilled_.getValue(n);
|
||||||
|
|
||||||
|
int32 propId_i = propId_[i];
|
||||||
|
int32 wPropId_j = wPropId_[tj];
|
||||||
|
|
||||||
|
realx3 FCn, FCt, Mri, Mrj, Mij, Mji;
|
||||||
|
//output<< "before "<<history.overlap_t_<<endl;
|
||||||
|
// calculates contact force
|
||||||
|
forceModel_.contactForce(
|
||||||
|
dt_, i, tj,
|
||||||
|
propId_i, wPropId_j,
|
||||||
|
Ri, Rj,
|
||||||
|
ovrlp,
|
||||||
|
Vr, Nij,
|
||||||
|
history,
|
||||||
|
FCn, FCt
|
||||||
|
);
|
||||||
|
|
||||||
|
//output<< "after "<<history.overlap_t_<<endl;
|
||||||
|
|
||||||
|
forceModel_.rollingFriction(
|
||||||
|
dt_, i, tj,
|
||||||
|
propId_i, wPropId_j,
|
||||||
|
Ri, Rj,
|
||||||
|
wi, 0.0,
|
||||||
|
Nij,
|
||||||
|
FCn,
|
||||||
|
Mri, Mrj
|
||||||
|
);
|
||||||
|
|
||||||
|
auto M = cross(Nij,FCt);
|
||||||
|
Mij = Ri*M+Mri;
|
||||||
|
//output<< "FCt = "<<FCt <<endl;
|
||||||
|
//output<< "FCn = "<<FCn <<endl;
|
||||||
|
//output<<"propId i, tj"<< propId_i << " "<<wPropId_j<<endl;
|
||||||
|
//output<<"par i , wj"<< i<<" "<< tj<<endl;
|
||||||
|
|
||||||
|
auto FC = FCn + FCt;
|
||||||
|
|
||||||
|
Kokkos::atomic_add(&cForce_[i].x_,FC.x_);
|
||||||
|
Kokkos::atomic_add(&cForce_[i].y_,FC.y_);
|
||||||
|
Kokkos::atomic_add(&cForce_[i].z_,FC.z_);
|
||||||
|
|
||||||
|
Kokkos::atomic_add(&wCForce_[tj].x_,-FC.x_);
|
||||||
|
Kokkos::atomic_add(&wCForce_[tj].y_,-FC.y_);
|
||||||
|
Kokkos::atomic_add(&wCForce_[tj].z_,-FC.z_);
|
||||||
|
|
||||||
|
|
||||||
|
Kokkos::atomic_add(&cTorque_[i].x_, Mij.x_);
|
||||||
|
Kokkos::atomic_add(&cTorque_[i].y_, Mij.y_);
|
||||||
|
Kokkos::atomic_add(&cTorque_[i].z_, Mij.z_);
|
||||||
|
|
||||||
|
tobeFilled_.setValue(n,history);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tobeFilled_.setValue(n,ValueType());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //__sphereInteractionKernels_H__
|
116
src/Interaction/sphereInteraction/sphereInteractions.C
Normal file
116
src/Interaction/sphereInteraction/sphereInteractions.C
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "sphereInteraction.H"
|
||||||
|
|
||||||
|
#include "geometryMotions.H"
|
||||||
|
|
||||||
|
#include "contactForceModels.H"
|
||||||
|
#include "unsortedContactList.H"
|
||||||
|
#include "sortedContactList.H"
|
||||||
|
|
||||||
|
template class pFlow::sphereInteraction<
|
||||||
|
pFlow::cfModels::limitedLinearNormalRolling,
|
||||||
|
pFlow::fixedGeometry,
|
||||||
|
pFlow::unsortedContactList>;
|
||||||
|
|
||||||
|
template class pFlow::sphereInteraction<
|
||||||
|
pFlow::cfModels::limitedLinearNormalRolling,
|
||||||
|
pFlow::fixedGeometry,
|
||||||
|
pFlow::sortedContactList>;
|
||||||
|
|
||||||
|
template class pFlow::sphereInteraction<
|
||||||
|
pFlow::cfModels::nonLimitedLinearNormalRolling,
|
||||||
|
pFlow::fixedGeometry,
|
||||||
|
pFlow::unsortedContactList>;
|
||||||
|
|
||||||
|
template class pFlow::sphereInteraction<
|
||||||
|
pFlow::cfModels::nonLimitedLinearNormalRolling,
|
||||||
|
pFlow::fixedGeometry,
|
||||||
|
pFlow::sortedContactList>;
|
||||||
|
|
||||||
|
template class pFlow::sphereInteraction<
|
||||||
|
pFlow::cfModels::limitedLinearNormalRolling,
|
||||||
|
pFlow::rotationAxisMotionGeometry,
|
||||||
|
pFlow::unsortedContactList>;
|
||||||
|
|
||||||
|
template class pFlow::sphereInteraction<
|
||||||
|
pFlow::cfModels::limitedLinearNormalRolling,
|
||||||
|
pFlow::rotationAxisMotionGeometry,
|
||||||
|
pFlow::sortedContactList>;
|
||||||
|
|
||||||
|
template class pFlow::sphereInteraction<
|
||||||
|
pFlow::cfModels::nonLimitedLinearNormalRolling,
|
||||||
|
pFlow::rotationAxisMotionGeometry,
|
||||||
|
pFlow::unsortedContactList>;
|
||||||
|
|
||||||
|
template class pFlow::sphereInteraction<
|
||||||
|
pFlow::cfModels::nonLimitedLinearNormalRolling,
|
||||||
|
pFlow::rotationAxisMotionGeometry,
|
||||||
|
pFlow::sortedContactList>;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// non-linear models
|
||||||
|
|
||||||
|
template class pFlow::sphereInteraction<
|
||||||
|
pFlow::cfModels::limitedNonLinearNormalRolling,
|
||||||
|
pFlow::fixedGeometry,
|
||||||
|
pFlow::unsortedContactList>;
|
||||||
|
|
||||||
|
template class pFlow::sphereInteraction<
|
||||||
|
pFlow::cfModels::limitedNonLinearNormalRolling,
|
||||||
|
pFlow::fixedGeometry,
|
||||||
|
pFlow::sortedContactList>;
|
||||||
|
|
||||||
|
template class pFlow::sphereInteraction<
|
||||||
|
pFlow::cfModels::nonLimitedNonLinearNormalRolling,
|
||||||
|
pFlow::fixedGeometry,
|
||||||
|
pFlow::unsortedContactList>;
|
||||||
|
|
||||||
|
template class pFlow::sphereInteraction<
|
||||||
|
pFlow::cfModels::nonLimitedNonLinearNormalRolling,
|
||||||
|
pFlow::fixedGeometry,
|
||||||
|
pFlow::sortedContactList>;
|
||||||
|
|
||||||
|
template class pFlow::sphereInteraction<
|
||||||
|
pFlow::cfModels::limitedNonLinearNormalRolling,
|
||||||
|
pFlow::rotationAxisMotionGeometry,
|
||||||
|
pFlow::unsortedContactList>;
|
||||||
|
|
||||||
|
template class pFlow::sphereInteraction<
|
||||||
|
pFlow::cfModels::limitedNonLinearNormalRolling,
|
||||||
|
pFlow::rotationAxisMotionGeometry,
|
||||||
|
pFlow::sortedContactList>;
|
||||||
|
|
||||||
|
template class pFlow::sphereInteraction<
|
||||||
|
pFlow::cfModels::nonLimitedNonLinearNormalRolling,
|
||||||
|
pFlow::rotationAxisMotionGeometry,
|
||||||
|
pFlow::unsortedContactList>;
|
||||||
|
|
||||||
|
template class pFlow::sphereInteraction<
|
||||||
|
pFlow::cfModels::nonLimitedNonLinearNormalRolling,
|
||||||
|
pFlow::rotationAxisMotionGeometry,
|
||||||
|
pFlow::sortedContactList>;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
231
src/Interaction/sphereInteraction/sphereTriSurfaceContact.H
Normal file
231
src/Interaction/sphereInteraction/sphereTriSurfaceContact.H
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
/*------------------------------- 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 __sphereTriSurfaceContact_H__
|
||||||
|
#define __sphereTriSurfaceContact_H__
|
||||||
|
|
||||||
|
#include "triWall.H"
|
||||||
|
#include "pLine.H"
|
||||||
|
|
||||||
|
namespace pFlow::sphTriInteraction
|
||||||
|
{
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool pointInPlane(
|
||||||
|
const realx3& p1,
|
||||||
|
const realx3& p2,
|
||||||
|
const realx3& p3,
|
||||||
|
const realx3& p )
|
||||||
|
{
|
||||||
|
|
||||||
|
realx3 p1p = p1 - p;
|
||||||
|
realx3 p2p = p2 - p;
|
||||||
|
realx3 p3p = p3 - p;
|
||||||
|
|
||||||
|
real p1p2 = dot(p1p, p2p);
|
||||||
|
real p2p3 = dot(p2p, p3p);
|
||||||
|
real p2p2 = dot(p2p, p2p);
|
||||||
|
real p1p3 = dot(p1p, p3p);
|
||||||
|
|
||||||
|
// first condition u.v < 0
|
||||||
|
// u.v = [(p1-p)x(p2-p)].[(p2-p)x(p3-p)] = (p1p.p2p)(p2p.p3p) - (p2p.p2p)(p1p.p3p)
|
||||||
|
if (p1p2*p2p3 - p2p2*p1p3 < 0.0) return false;
|
||||||
|
|
||||||
|
|
||||||
|
// second condition u.w < 0
|
||||||
|
// u.w = [(p1-p)x(p2-p)].[(p3-p)x(p1-p)] = (p1p.p3p)(p2p.p1p) - (p2p.p3p)(p1p.p1p)
|
||||||
|
real p1p1 = dot(p1p, p1p);
|
||||||
|
if (p1p3*p1p2 - p2p3*p1p1 < (0.0)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
void cramerRule2(real A[2][2], real B[2], real & x1, real &x2)
|
||||||
|
{
|
||||||
|
real det = (A[0][0] * A[1][1] - A[1][0]*A[0][1]);
|
||||||
|
x1 = (B[0]*A[1][1] - B[1]*A[0][1]) / det;
|
||||||
|
x2 = (A[0][0] * B[1] - A[1][0] * B[0])/ det;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool pointInPlane(
|
||||||
|
const realx3& p1,
|
||||||
|
const realx3& p2,
|
||||||
|
const realx3& p3,
|
||||||
|
const realx3 &p,
|
||||||
|
int32 &Ln)
|
||||||
|
{
|
||||||
|
realx3 v0 = p2 - p1;
|
||||||
|
realx3 v1 = p3 - p1;
|
||||||
|
realx3 v2 = p - p1;
|
||||||
|
|
||||||
|
real A[2][2] = { dot(v0, v0), dot(v0, v1), dot(v1, v0), dot(v1, v1) };
|
||||||
|
real B[2] = { dot(v0, v2), dot(v1, v2) };
|
||||||
|
real nu, w;
|
||||||
|
|
||||||
|
cramerRule2(A, B, nu, w);
|
||||||
|
real nuW = nu + w;
|
||||||
|
|
||||||
|
|
||||||
|
if (nuW > 1)
|
||||||
|
{
|
||||||
|
Ln = 2; return true;
|
||||||
|
}
|
||||||
|
else if (nuW >= 0)
|
||||||
|
{
|
||||||
|
if (nu >= 0 && w >= 0)
|
||||||
|
{
|
||||||
|
Ln = 0; return true;
|
||||||
|
}
|
||||||
|
if (nu > 0 && w < 0)
|
||||||
|
{
|
||||||
|
Ln = 1; return true;
|
||||||
|
}
|
||||||
|
if (nu < 0 && w > 0)
|
||||||
|
{
|
||||||
|
Ln = 3; return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Ln = 1; return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool isSphereInContactActiveSide(
|
||||||
|
const realx3& p1,
|
||||||
|
const realx3& p2,
|
||||||
|
const realx3& p3,
|
||||||
|
const realx3& cntr,
|
||||||
|
real rad,
|
||||||
|
real& ovrlp,
|
||||||
|
realx3& norm,
|
||||||
|
realx3& cp)
|
||||||
|
{
|
||||||
|
|
||||||
|
triWall wall(true, p1,p2,p3);
|
||||||
|
|
||||||
|
real dist = wall.normalDistFromWall(cntr);
|
||||||
|
|
||||||
|
if(dist < 0.0 )return false;
|
||||||
|
|
||||||
|
ovrlp = rad - dist;
|
||||||
|
|
||||||
|
if (ovrlp > 0)
|
||||||
|
{
|
||||||
|
realx3 ptOnPlane = wall.nearestPointOnWall(cntr);
|
||||||
|
|
||||||
|
if (pointInPlane(p1, p2, p3, ptOnPlane))
|
||||||
|
{
|
||||||
|
cp = ptOnPlane;
|
||||||
|
norm = -wall.n_;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
realx3 lnv;
|
||||||
|
|
||||||
|
if (pLine(p1,p2).lineSphereCheck(cntr, rad, lnv, cp, ovrlp))
|
||||||
|
{
|
||||||
|
norm = -lnv;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pLine(p2,p3).lineSphereCheck(cntr, rad, lnv, cp, ovrlp))
|
||||||
|
{
|
||||||
|
norm = -lnv;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pLine(p3,p1).lineSphereCheck(cntr, rad, lnv, cp, ovrlp))
|
||||||
|
{
|
||||||
|
norm = -lnv;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool isSphereInContactBothSides(
|
||||||
|
const realx3x3& tri,
|
||||||
|
const realx3& cntr,
|
||||||
|
real Rad,
|
||||||
|
real& ovrlp,
|
||||||
|
realx3& norm,
|
||||||
|
realx3& cp)
|
||||||
|
{
|
||||||
|
|
||||||
|
triWall wall(true, tri.x_,tri.y_,tri.z_);
|
||||||
|
|
||||||
|
real dist = wall.normalDistFromWall(cntr);
|
||||||
|
|
||||||
|
|
||||||
|
ovrlp = Rad - abs(dist);
|
||||||
|
|
||||||
|
if (ovrlp > 0)
|
||||||
|
{
|
||||||
|
realx3 ptOnPlane = wall.nearestPointOnWall(cntr);
|
||||||
|
|
||||||
|
if (pointInPlane(tri.x_,tri.y_,tri.z_,ptOnPlane))
|
||||||
|
{
|
||||||
|
cp = ptOnPlane;
|
||||||
|
|
||||||
|
if(dist >= 0.0)
|
||||||
|
norm = -wall.n_;
|
||||||
|
else
|
||||||
|
norm = wall.n_;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
realx3 lnv;
|
||||||
|
|
||||||
|
if (pLine(tri.x_, tri.y_).lineSphereCheck(cntr, Rad, lnv, cp, ovrlp))
|
||||||
|
{
|
||||||
|
norm = -lnv;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pLine(tri.y_, tri.z_).lineSphereCheck(cntr, Rad, lnv, cp, ovrlp))
|
||||||
|
{
|
||||||
|
norm = -lnv;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pLine(tri.z_, tri.x_).lineSphereCheck(cntr, Rad, lnv, cp, ovrlp))
|
||||||
|
{
|
||||||
|
norm = -lnv;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // pFlow::sphTriInteraction
|
||||||
|
|
||||||
|
|
||||||
|
#endif //__sphereTriSurfaceContact_H__
|
108
src/Interaction/sphereInteraction/triWall.H
Normal file
108
src/Interaction/sphereInteraction/triWall.H
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __triWall_H__
|
||||||
|
#define __triWall_H__
|
||||||
|
|
||||||
|
#include "types.H"
|
||||||
|
|
||||||
|
namespace pFlow::sphTriInteraction
|
||||||
|
{
|
||||||
|
|
||||||
|
struct triWall
|
||||||
|
{
|
||||||
|
|
||||||
|
realx3 n_;
|
||||||
|
real offset_;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_H
|
||||||
|
triWall(const realx3& p1, const realx3& p2, const realx3& p3)
|
||||||
|
{
|
||||||
|
if(!makeWall(p1,p2,p3, n_, offset_))
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"bad input for the wall.\n";
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
triWall(bool, const realx3& p1, const realx3& p2, const realx3& p3)
|
||||||
|
{
|
||||||
|
makeWall(p1,p2,p3,n_,offset_);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
triWall(const realx3x3& tri)
|
||||||
|
{
|
||||||
|
makeWall(tri.x_, tri.y_, tri.z_, n_, offset_);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
triWall(const triWall&) = default;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
triWall& operator=(const triWall&) = default;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
triWall(triWall&&) = default;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
triWall& operator=(triWall&&) = default;
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
~triWall()=default;
|
||||||
|
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
real normalDistFromWall(const realx3 &p) const
|
||||||
|
{
|
||||||
|
return dot(n_, p) + offset_;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
realx3 nearestPointOnWall(const realx3 &p) const
|
||||||
|
{
|
||||||
|
real t = -(dot(n_, p) + offset_);
|
||||||
|
return realx3(n_.x_*t + p.x_, n_.y_*t + p.y_, n_.z_*t + p.z_);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD static
|
||||||
|
bool makeWall(
|
||||||
|
const realx3& p1,
|
||||||
|
const realx3& p2,
|
||||||
|
const realx3& p3,
|
||||||
|
realx3& n, real& offset)
|
||||||
|
{
|
||||||
|
n = cross(p2 - p1, p3 - p1);
|
||||||
|
real len = length(n);
|
||||||
|
|
||||||
|
if (len < 0.00000000001) return false;
|
||||||
|
n /= len;
|
||||||
|
offset = -dot(n, p1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
13
src/MotionModel/CMakeLists.txt
Normal file
13
src/MotionModel/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
list(APPEND SourceFiles
|
||||||
|
entities/rotatingAxis/rotatingAxis.C
|
||||||
|
fixedWall/fixedWall.C
|
||||||
|
rotatingAxisMotion/rotatingAxisMotion.C
|
||||||
|
)
|
||||||
|
|
||||||
|
set(link_libs Kokkos::kokkos phasicFlow)
|
||||||
|
|
||||||
|
pFlow_add_library_install(MotionModel SourceFiles link_libs)
|
||||||
|
|
||||||
|
|
||||||
|
|
144
src/MotionModel/entities/rotatingAxis/rotatingAxis.C
Normal file
144
src/MotionModel/entities/rotatingAxis/rotatingAxis.C
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/*------------------------------- 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 "rotatingAxis.H"
|
||||||
|
#include "dictionary.H"
|
||||||
|
|
||||||
|
/*FUNCTION_HD
|
||||||
|
pFlow::rotatingAxis::rotatingAxis()
|
||||||
|
:
|
||||||
|
line(),
|
||||||
|
omega_(0.0),
|
||||||
|
rotating_(false)
|
||||||
|
{}*/
|
||||||
|
|
||||||
|
FUNCTION_H
|
||||||
|
pFlow::rotatingAxis::rotatingAxis
|
||||||
|
(
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(!read(dict))
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in reading rotatingAxis from dictionary "<< dict.globalName()<<endl;
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FUNCTION_HD
|
||||||
|
pFlow::rotatingAxis::rotatingAxis
|
||||||
|
(
|
||||||
|
const realx3& p1,
|
||||||
|
const realx3& p2,
|
||||||
|
real omega
|
||||||
|
)
|
||||||
|
:
|
||||||
|
line(p1, p2),
|
||||||
|
omega_(omega),
|
||||||
|
rotating_(!equal(omega,0.0))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//rotatingAxis(const dictionary& dict);
|
||||||
|
FUNCTION_HD
|
||||||
|
pFlow::real pFlow::rotatingAxis::setOmega(real omega)
|
||||||
|
{
|
||||||
|
auto tmp = omega_;
|
||||||
|
omega_ = omega;
|
||||||
|
rotating_ = !equal(omega, 0.0);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
FUNCTION_H
|
||||||
|
bool pFlow::rotatingAxis::read
|
||||||
|
(
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if(!line::read(dict)) return false;
|
||||||
|
|
||||||
|
real omega = dict.getValOrSet("omega", static_cast<real>(0.0));
|
||||||
|
|
||||||
|
setOmega(omega);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FUNCTION_H
|
||||||
|
bool pFlow::rotatingAxis::write
|
||||||
|
(
|
||||||
|
dictionary& dict
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if( !line::write(dict) ) return false;
|
||||||
|
|
||||||
|
if( !dict.add("omega", omega_) )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in writing omega to dictionary "<< dict.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FUNCTION_H
|
||||||
|
bool pFlow::rotatingAxis::read
|
||||||
|
(
|
||||||
|
iIstream& is
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if( !rotatingAxis::line::read(is)) return false;
|
||||||
|
|
||||||
|
word omegaw;
|
||||||
|
real omega;
|
||||||
|
|
||||||
|
is >> omegaw >> omega;
|
||||||
|
if( !is.check(FUNCTION_NAME))
|
||||||
|
{
|
||||||
|
ioErrorInFile(is.name(), is.lineNumber());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(omegaw != "omega")
|
||||||
|
{
|
||||||
|
ioErrorInFile(is.name(), is.lineNumber())<<
|
||||||
|
" expected omega but found "<< omegaw <<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
is.readEndStatement(FUNCTION_NAME);
|
||||||
|
|
||||||
|
setOmega(omega);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FUNCTION_H
|
||||||
|
bool pFlow::rotatingAxis::write
|
||||||
|
(
|
||||||
|
iOstream& os
|
||||||
|
)const
|
||||||
|
{
|
||||||
|
if( !rotatingAxis::line::write(os) ) return false;
|
||||||
|
|
||||||
|
os.writeWordEntry("omega", omega());
|
||||||
|
return os.check(FUNCTION_NAME);
|
||||||
|
}
|
112
src/MotionModel/entities/rotatingAxis/rotatingAxis.H
Normal file
112
src/MotionModel/entities/rotatingAxis/rotatingAxis.H
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/*------------------------------- 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 __rotatingAxis_H__
|
||||||
|
#define __rotatingAxis_H__
|
||||||
|
|
||||||
|
#include "line.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
class dictionary;
|
||||||
|
class rotatingAxis;
|
||||||
|
|
||||||
|
#include "rotatingAxisFwd.H"
|
||||||
|
|
||||||
|
class rotatingAxis
|
||||||
|
:
|
||||||
|
public line
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// rotation speed
|
||||||
|
real omega_ = 0;
|
||||||
|
|
||||||
|
bool rotating_ = false;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FUNCTION_HD
|
||||||
|
rotatingAxis(){}
|
||||||
|
|
||||||
|
FUNCTION_H
|
||||||
|
rotatingAxis(const dictionary& dict);
|
||||||
|
|
||||||
|
FUNCTION_HD
|
||||||
|
rotatingAxis(const realx3& p1, const realx3& p2, real omega = 0.0);
|
||||||
|
|
||||||
|
FUNCTION_HD
|
||||||
|
rotatingAxis(const rotatingAxis&) = default;
|
||||||
|
|
||||||
|
rotatingAxis& operator=(const rotatingAxis&) = default;
|
||||||
|
|
||||||
|
FUNCTION_HD
|
||||||
|
real setOmega(real omega);
|
||||||
|
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
real omega()const
|
||||||
|
{
|
||||||
|
return omega_;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
realx3 linTangentialVelocityPoint(const realx3 &p)const;
|
||||||
|
|
||||||
|
// - IO operation
|
||||||
|
FUNCTION_H
|
||||||
|
bool read(const dictionary& dict);
|
||||||
|
|
||||||
|
FUNCTION_H
|
||||||
|
bool write(dictionary& dict) const;
|
||||||
|
|
||||||
|
FUNCTION_H
|
||||||
|
bool read(iIstream& is);
|
||||||
|
|
||||||
|
FUNCTION_H
|
||||||
|
bool write(iOstream& os)const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
inline iOstream& operator <<(iOstream& os, const rotatingAxis& ax)
|
||||||
|
{
|
||||||
|
if(!ax.write(os))
|
||||||
|
{
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline iIstream& operator >>(iIstream& is, rotatingAxis& ax)
|
||||||
|
{
|
||||||
|
if( !ax.read(is) )
|
||||||
|
{
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#include "rotatingAxisI.H"
|
||||||
|
|
||||||
|
#endif
|
34
src/MotionModel/entities/rotatingAxis/rotatingAxisFwd.H
Executable file
34
src/MotionModel/entities/rotatingAxis/rotatingAxisFwd.H
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
/*------------------------------- 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.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
realx3 rotate(const realx3 &p, const line& ln, real theta);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
void rotate(realx3* p, size_t n, const rotatingAxis& ax, real dt);
|
||||||
|
|
||||||
|
|
||||||
|
|
164
src/MotionModel/entities/rotatingAxis/rotatingAxisI.H
Executable file
164
src/MotionModel/entities/rotatingAxis/rotatingAxisI.H
Executable file
@ -0,0 +1,164 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
pFlow::realx3 pFlow::rotatingAxis::linTangentialVelocityPoint(const realx3 &p)const
|
||||||
|
{
|
||||||
|
realx3 L = p - projectPoint(p);
|
||||||
|
return cross(omega_*unitVector(),L);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
pFlow::realx3 pFlow::rotate(const realx3& p, const rotatingAxis& ax, real dt)
|
||||||
|
{
|
||||||
|
realx3 nv = ax.unitVector();
|
||||||
|
real cos_tet = cos(ax.omega()*dt);
|
||||||
|
real sin_tet = sin(ax.omega()*dt);
|
||||||
|
real u2 = nv.x()*nv.x();
|
||||||
|
real v2 = nv.y()*nv.y();
|
||||||
|
real w2 = nv.z()*nv.z();
|
||||||
|
realx3 lp1 = ax.point1();
|
||||||
|
|
||||||
|
// (a(v2+w2) - u( bv + cw - ux - vy - wz)) (1-cos_tet) + x cos_tet + (- cv + bw - wy + vz) sin_tet
|
||||||
|
realx3 res;
|
||||||
|
|
||||||
|
res.x_ = (lp1.x_*(v2 + w2) - (nv.x_*(lp1.y_*nv.y_ + lp1.z_*nv.z_ - nv.x_*p.x_ - nv.y_*p.y_ - nv.z_*p.z_)))*(1 - cos_tet) +
|
||||||
|
p.x_ * cos_tet +
|
||||||
|
(-lp1.z_*nv.y_ + lp1.y_*nv.z_ - nv.z_*p.y_ + nv.y_*p.z_) * sin_tet;
|
||||||
|
|
||||||
|
|
||||||
|
// ( b(u2+w2) - v( au + cw - ux - vy - wz))(1-cos_tet) + y cos_tet + ( cu - aw + wx - uz ) sin_tet
|
||||||
|
res.y_ = (lp1.y_*(u2 + w2) - (nv.y_*(lp1.x_*nv.x_ + lp1.z_*nv.z_ - nv.x_*p.x_ - nv.y_*p.y_ - nv.z_*p.z_)))*(1 - cos_tet) +
|
||||||
|
p.y_ * cos_tet +
|
||||||
|
(lp1.z_*nv.x_ - lp1.x_*nv.z_ + nv.z_*p.x_ - nv.x_*p.z_) * sin_tet;
|
||||||
|
|
||||||
|
// (c(u2+v2) - w( au + bv - ux - vy - wz ))(1-cos_tet) + z cos_tet + (-bu + av - vx + uy) sin_tet
|
||||||
|
res.z_ = (lp1.z_*(u2 + v2) - (nv.z_*(lp1.x_*nv.x_ + lp1.y_*nv.y_ - nv.x_*p.x_ - nv.y_*p.y_ - nv.z_*p.z_)))*(1 - cos_tet) +
|
||||||
|
p.z_ * cos_tet +
|
||||||
|
(-lp1.y_*nv.x_ + lp1.x_*nv.y_ - nv.y_*p.x_ + nv.x_*p.y_) * sin_tet;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
pFlow::realx3 pFlow::rotate(const realx3 &p, const line& ln, real theta)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
realx3 nv = ln.unitVector();
|
||||||
|
real cos_tet = cos(theta);
|
||||||
|
real sin_tet = sin(theta);
|
||||||
|
real u2 = nv.x()*nv.x();
|
||||||
|
real v2 = nv.y()*nv.y();
|
||||||
|
real w2 = nv.z()*nv.z();
|
||||||
|
realx3 lp1 = ln.point1();
|
||||||
|
|
||||||
|
// (a(v2+w2) - u( bv + cw - ux - vy - wz)) (1-cos_tet) + x cos_tet + (- cv + bw - wy + vz) sin_tet
|
||||||
|
realx3 res;
|
||||||
|
|
||||||
|
res.x_ = (lp1.x_*(v2 + w2) - (nv.x_*(lp1.y_*nv.y_ + lp1.z_*nv.z_ - nv.x_*p.x_ - nv.y_*p.y_ - nv.z_*p.z_)))*(1 - cos_tet) +
|
||||||
|
p.x_ * cos_tet +
|
||||||
|
(-lp1.z_*nv.y_ + lp1.y_*nv.z_ - nv.z_*p.y_ + nv.y_*p.z_) * sin_tet;
|
||||||
|
|
||||||
|
|
||||||
|
// ( b(u2+w2) - v( au + cw - ux - vy - wz))(1-cos_tet) + y cos_tet + ( cu - aw + wx - uz ) sin_tet
|
||||||
|
res.y_ = (lp1.y_*(u2 + w2) - (nv.y_*(lp1.x_*nv.x_ + lp1.z_*nv.z_ - nv.x_*p.x_ - nv.y_*p.y_ - nv.z_*p.z_)))*(1 - cos_tet) +
|
||||||
|
p.y_ * cos_tet +
|
||||||
|
(lp1.z_*nv.x_ - lp1.x_*nv.z_ + nv.z_*p.x_ - nv.x_*p.z_) * sin_tet;
|
||||||
|
|
||||||
|
// (c(u2+v2) - w( au + bv - ux - vy - wz ))(1-cos_tet) + z cos_tet + (-bu + av - vx + uy) sin_tet
|
||||||
|
res.z_ = (lp1.z_*(u2 + v2) - (nv.z_*(lp1.x_*nv.x_ + lp1.y_*nv.y_ - nv.x_*p.x_ - nv.y_*p.y_ - nv.z_*p.z_)))*(1 - cos_tet) +
|
||||||
|
p.z_ * cos_tet +
|
||||||
|
(-lp1.y_*nv.x_ + lp1.x_*nv.y_ - nv.y_*p.x_ + nv.x_*p.y_) * sin_tet;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
void pFlow::rotate(realx3* p, size_t n, const line& ln, real theta)
|
||||||
|
{
|
||||||
|
realx3 nv = ln.unitVector();
|
||||||
|
real cos_tet = cos(theta);
|
||||||
|
real sin_tet = sin(theta);
|
||||||
|
real u2 = nv.x()*nv.x();
|
||||||
|
real v2 = nv.y()*nv.y();
|
||||||
|
real w2 = nv.z()*nv.z();
|
||||||
|
realx3 lp1 = ln.point1();
|
||||||
|
|
||||||
|
// (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<n; i++ )
|
||||||
|
{
|
||||||
|
res.x_ = (lp1.x_*(v2 + w2) - (nv.x_*(lp1.y_*nv.y_ + lp1.z_*nv.z_ - nv.x_*p[i].x_ - nv.y_*p[i].y_ - nv.z_*p[i].z_)))*(1 - cos_tet) +
|
||||||
|
p[i].x_ * cos_tet +
|
||||||
|
(-lp1.z_*nv.y_ + lp1.y_*nv.z_ - nv.z_*p[i].y_ + nv.y_*p[i].z_) * sin_tet;
|
||||||
|
|
||||||
|
|
||||||
|
// ( b(u2+w2) - v( au + cw - ux - vy - wz))(1-cos_tet) + y cos_tet + ( cu - aw + wx - uz ) sin_tet
|
||||||
|
res.y_ = (lp1.y_*(u2 + w2) - (nv.y_*(lp1.x_*nv.x_ + lp1.z_*nv.z_ - nv.x_*p[i].x_ - nv.y_*p[i].y_ - nv.z_*p[i].z_)))*(1 - cos_tet) +
|
||||||
|
p[i].y_ * cos_tet +
|
||||||
|
(lp1.z_*nv.x_ - lp1.x_*nv.z_ + nv.z_*p[i].x_ - nv.x_*p[i].z_) * sin_tet;
|
||||||
|
|
||||||
|
// (c(u2+v2) - w( au + bv - ux - vy - wz ))(1-cos_tet) + z cos_tet + (-bu + av - vx + uy) sin_tet
|
||||||
|
res.z_ = (lp1.z_*(u2 + v2) - (nv.z_*(lp1.x_*nv.x_ + lp1.y_*nv.y_ - nv.x_*p[i].x_ - nv.y_*p[i].y_ - nv.z_*p[i].z_)))*(1 - cos_tet) +
|
||||||
|
p[i].z_ * cos_tet +
|
||||||
|
(-lp1.y_*nv.x_ + lp1.x_*nv.y_ - nv.y_*p[i].x_ + nv.x_*p[i].y_) * sin_tet;
|
||||||
|
|
||||||
|
p[i] = res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
void pFlow::rotate(realx3* p, size_t n, const rotatingAxis& ax, real dt)
|
||||||
|
{
|
||||||
|
realx3 nv = ax.unitVector();
|
||||||
|
real cos_tet = cos(ax.omega()*dt);
|
||||||
|
real sin_tet = sin(ax.omega()*dt);
|
||||||
|
real u2 = nv.x()*nv.x();
|
||||||
|
real v2 = nv.y()*nv.y();
|
||||||
|
real w2 = nv.z()*nv.z();
|
||||||
|
realx3 lp1 = ax.point1();
|
||||||
|
|
||||||
|
// (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<n; i++ )
|
||||||
|
{
|
||||||
|
res.x_ = (lp1.x_*(v2 + w2) - (nv.x_*(lp1.y_*nv.y_ + lp1.z_*nv.z_ - nv.x_*p[i].x_ - nv.y_*p[i].y_ - nv.z_*p[i].z_)))*(1 - cos_tet) +
|
||||||
|
p[i].x_ * cos_tet +
|
||||||
|
(-lp1.z_*nv.y_ + lp1.y_*nv.z_ - nv.z_*p[i].y_ + nv.y_*p[i].z_) * sin_tet;
|
||||||
|
|
||||||
|
|
||||||
|
// ( b(u2+w2) - v( au + cw - ux - vy - wz))(1-cos_tet) + y cos_tet + ( cu - aw + wx - uz ) sin_tet
|
||||||
|
res.y_ = (lp1.y_*(u2 + w2) - (nv.y_*(lp1.x_*nv.x_ + lp1.z_*nv.z_ - nv.x_*p[i].x_ - nv.y_*p[i].y_ - nv.z_*p[i].z_)))*(1 - cos_tet) +
|
||||||
|
p[i].y_ * cos_tet +
|
||||||
|
(lp1.z_*nv.x_ - lp1.x_*nv.z_ + nv.z_*p[i].x_ - nv.x_*p[i].z_) * sin_tet;
|
||||||
|
|
||||||
|
// (c(u2+v2) - w( au + bv - ux - vy - wz ))(1-cos_tet) + z cos_tet + (-bu + av - vx + uy) sin_tet
|
||||||
|
res.z_ = (lp1.z_*(u2 + v2) - (nv.z_*(lp1.x_*nv.x_ + lp1.y_*nv.y_ - nv.x_*p[i].x_ - nv.y_*p[i].y_ - nv.z_*p[i].z_)))*(1 - cos_tet) +
|
||||||
|
p[i].z_ * cos_tet +
|
||||||
|
(-lp1.y_*nv.x_ + lp1.x_*nv.y_ - nv.y_*p[i].x_ + nv.x_*p[i].y_) * sin_tet;
|
||||||
|
|
||||||
|
p[i] = res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
110
src/MotionModel/fixedWall/fixedWall.C
Normal file
110
src/MotionModel/fixedWall/fixedWall.C
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/*------------------------------- 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.H"
|
||||||
|
#include "dictionary.H"
|
||||||
|
#include "vocabs.H"
|
||||||
|
|
||||||
|
bool pFlow::fixedWall::readDictionary
|
||||||
|
(
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
auto motionModel = dict.getVal<word>("motionModel");
|
||||||
|
|
||||||
|
if(motionModel != "fixedWall")
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" motionModel should be fixedWall, but found " << motionModel <<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::fixedWall::writeDictionary
|
||||||
|
(
|
||||||
|
dictionary& dict
|
||||||
|
)const
|
||||||
|
{
|
||||||
|
dict.add("motionModel", "fixedWall");
|
||||||
|
|
||||||
|
auto& motionInfo = dict.subDictOrCreate("fixedWallInfo");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pFlow::fixedWall::fixedWall()
|
||||||
|
{}
|
||||||
|
|
||||||
|
pFlow::fixedWall::fixedWall
|
||||||
|
(
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if(! readDictionary(dict) )
|
||||||
|
{
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::fixedWall::read
|
||||||
|
(
|
||||||
|
iIstream& is
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// create an empty file dictionary
|
||||||
|
dictionary motionInfo(motionModelFile__, true);
|
||||||
|
|
||||||
|
// read dictionary from stream
|
||||||
|
if( !motionInfo.read(is) )
|
||||||
|
{
|
||||||
|
ioErrorInFile(is.name(), is.lineNumber()) <<
|
||||||
|
" error in reading dictionray " << motionModelFile__ <<" from file. \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !readDictionary(motionInfo) ) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::fixedWall::write
|
||||||
|
(
|
||||||
|
iOstream& os
|
||||||
|
)const
|
||||||
|
{
|
||||||
|
// create an empty file dictionary
|
||||||
|
dictionary motionInfo(motionModelFile__, true);
|
||||||
|
|
||||||
|
if( !writeDictionary(motionInfo))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !motionInfo.write(os) )
|
||||||
|
{
|
||||||
|
ioErrorInFile( os.name(), os.lineNumber() )<<
|
||||||
|
" error in writing dictionray to file. \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
170
src/MotionModel/fixedWall/fixedWall.H
Normal file
170
src/MotionModel/fixedWall/fixedWall.H
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
/*------------------------------- 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 __fixedWall_H__
|
||||||
|
#define __fixedWall_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "types.H"
|
||||||
|
#include "typeInfo.H"
|
||||||
|
#include "Vectors.H"
|
||||||
|
#include "uniquePtr.H"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
class dictionary;
|
||||||
|
|
||||||
|
class fixedWall
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// - this class shuold be decleared in every motion model with
|
||||||
|
// exact methods
|
||||||
|
class Model
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
Model(){}
|
||||||
|
|
||||||
|
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 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
realx3 operator()(int32 n, const realx3& p)const
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
realx3 transferPoint(int32 n, const realx3 p, real dt)const
|
||||||
|
{
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD int32 numComponents()const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
const word name_ = "none";
|
||||||
|
|
||||||
|
bool readDictionary(const dictionary& dict);
|
||||||
|
|
||||||
|
bool writeDictionary(dictionary& dict)const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeNameNV("fixedWall");
|
||||||
|
|
||||||
|
// empty
|
||||||
|
fixedWall();
|
||||||
|
|
||||||
|
// construct with dictionary
|
||||||
|
fixedWall(const dictionary& dict);
|
||||||
|
|
||||||
|
fixedWall(const fixedWall&) = default;
|
||||||
|
|
||||||
|
fixedWall(fixedWall&&) = default;
|
||||||
|
|
||||||
|
fixedWall& operator=(const fixedWall&) = default;
|
||||||
|
|
||||||
|
fixedWall& operator=(fixedWall&&) = default;
|
||||||
|
|
||||||
|
~fixedWall() = default;
|
||||||
|
|
||||||
|
Model getModel()const
|
||||||
|
{
|
||||||
|
return Model();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 nameToIndex(const word& name)const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
word indexToName(label i)const
|
||||||
|
{
|
||||||
|
return name_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
realx3 pointVelocity(label n, const realx3& p)const
|
||||||
|
{
|
||||||
|
return zero3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
realx3 transferPoint(label n, const realx3 p, real dt)const
|
||||||
|
{
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool transferPoint(label n, realx3* pVec, size_t numP, real dt)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool isMoving()const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool move(real dt)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FUNCTION_H
|
||||||
|
bool read(iIstream& is);
|
||||||
|
|
||||||
|
FUNCTION_H
|
||||||
|
bool write(iOstream& os)const;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // pFlow
|
||||||
|
|
||||||
|
#endif //__fixed_H__
|
170
src/MotionModel/rotatingAxisMotion/rotatingAxisMotion.C
Normal file
170
src/MotionModel/rotatingAxisMotion/rotatingAxisMotion.C
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
/*------------------------------- 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 "rotatingAxisMotion.H"
|
||||||
|
#include "dictionary.H"
|
||||||
|
#include "vocabs.H"
|
||||||
|
|
||||||
|
|
||||||
|
bool pFlow::rotatingAxisMotion::readDictionary
|
||||||
|
(
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
auto motionModel = dict.getVal<word>("motionModel");
|
||||||
|
|
||||||
|
if(motionModel != "rotatingAxisMotion")
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" motionModel should be rotatingAxisMotion, but found "
|
||||||
|
<< motionModel <<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& motionInfo = dict.subDict("rotatingAxisMotionInfo");
|
||||||
|
auto axisNames = motionInfo.dictionaryKeywords();
|
||||||
|
|
||||||
|
axis_.reserve(axisNames.size()+1);
|
||||||
|
|
||||||
|
|
||||||
|
axis_.clear();
|
||||||
|
axisName_.clear();
|
||||||
|
|
||||||
|
|
||||||
|
for(auto& aName: axisNames)
|
||||||
|
{
|
||||||
|
auto& axDict = motionInfo.subDict(aName);
|
||||||
|
|
||||||
|
if(auto axPtr = makeUnique<rotatingAxis>(axDict); axPtr)
|
||||||
|
{
|
||||||
|
axis_.push_back(axPtr());
|
||||||
|
axisName_.push_back(aName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"could not read rotating axis from "<< axDict.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if( !axisName_.search("none") )
|
||||||
|
{
|
||||||
|
axis_.push_back
|
||||||
|
(
|
||||||
|
rotatingAxis(
|
||||||
|
realx3(0.0,0.0,0.0),
|
||||||
|
realx3(1.0,0.0,0.0),
|
||||||
|
0.0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
axisName_.push_back("none");
|
||||||
|
}
|
||||||
|
|
||||||
|
axis_.syncViews();
|
||||||
|
numAxis_ = axis_.size();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::rotatingAxisMotion::writeDictionary
|
||||||
|
(
|
||||||
|
dictionary& dict
|
||||||
|
)const
|
||||||
|
{
|
||||||
|
dict.add("motionModel", "rotatingAxisMotion");
|
||||||
|
|
||||||
|
auto& motionInfo = dict.subDictOrCreate("rotatingAxisMotionInfo");
|
||||||
|
|
||||||
|
forAll(i, axis_)
|
||||||
|
{
|
||||||
|
|
||||||
|
auto& axDict = motionInfo.subDictOrCreate(axisName_[i]);
|
||||||
|
if( !axis_.hostVectorAll()[i].write(axDict))
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in writing axis "<< axisName_[i] << " to dicrionary "
|
||||||
|
<< motionInfo.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pFlow::rotatingAxisMotion::rotatingAxisMotion()
|
||||||
|
{}
|
||||||
|
|
||||||
|
pFlow::rotatingAxisMotion::rotatingAxisMotion
|
||||||
|
(
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if(! readDictionary(dict) )
|
||||||
|
{
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::rotatingAxisMotion::read
|
||||||
|
(
|
||||||
|
iIstream& is
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// create an empty file dictionary
|
||||||
|
dictionary motionInfo(motionModelFile__, true);
|
||||||
|
|
||||||
|
// read dictionary from stream
|
||||||
|
if( !motionInfo.read(is) )
|
||||||
|
{
|
||||||
|
ioErrorInFile(is.name(), is.lineNumber()) <<
|
||||||
|
" error in reading dictionray " << motionModelFile__ <<" from file. \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !readDictionary(motionInfo) ) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::rotatingAxisMotion::write
|
||||||
|
(
|
||||||
|
iOstream& os
|
||||||
|
)const
|
||||||
|
{
|
||||||
|
// create an empty file dictionary
|
||||||
|
dictionary motionInfo(motionModelFile__, true);
|
||||||
|
|
||||||
|
if( !writeDictionary(motionInfo))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !motionInfo.write(os) )
|
||||||
|
{
|
||||||
|
ioErrorInFile( os.name(), os.lineNumber() )<<
|
||||||
|
" error in writing dictionray to file. \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
218
src/MotionModel/rotatingAxisMotion/rotatingAxisMotion.H
Normal file
218
src/MotionModel/rotatingAxisMotion/rotatingAxisMotion.H
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
/*------------------------------- 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 __rotatingAxisMotion_H__
|
||||||
|
#define __rotatingAxisMotion_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "types.H"
|
||||||
|
#include "typeInfo.H"
|
||||||
|
#include "VectorDual.H"
|
||||||
|
#include "Vectors.H"
|
||||||
|
#include "List.H"
|
||||||
|
#include "rotatingAxis.H"
|
||||||
|
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
class dictionary;
|
||||||
|
|
||||||
|
class rotatingAxisMotion
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// - this class shuold be decleared in every motion model with
|
||||||
|
// exact methods
|
||||||
|
class Model
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
deviceViewType1D<rotatingAxis> axis_;
|
||||||
|
int32 numAxis_=0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
Model(deviceViewType1D<rotatingAxis> 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<rotatingAxis>;
|
||||||
|
|
||||||
|
axisVector_HD axis_;
|
||||||
|
|
||||||
|
wordList axisName_;
|
||||||
|
|
||||||
|
label numAxis_= 0;
|
||||||
|
|
||||||
|
bool readDictionary(const dictionary& dict);
|
||||||
|
|
||||||
|
bool writeDictionary(dictionary& dict)const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeNameNV("rotatingAxisMotion");
|
||||||
|
|
||||||
|
// empty
|
||||||
|
FUNCTION_H
|
||||||
|
rotatingAxisMotion();
|
||||||
|
|
||||||
|
// construct with dictionary
|
||||||
|
FUNCTION_H
|
||||||
|
rotatingAxisMotion(const dictionary& dict);
|
||||||
|
|
||||||
|
// copy
|
||||||
|
FUNCTION_H
|
||||||
|
rotatingAxisMotion(const rotatingAxisMotion&) = default;
|
||||||
|
|
||||||
|
rotatingAxisMotion(rotatingAxisMotion&&) = delete;
|
||||||
|
|
||||||
|
FUNCTION_H
|
||||||
|
rotatingAxisMotion& operator=(const rotatingAxisMotion&) = default;
|
||||||
|
|
||||||
|
rotatingAxisMotion& operator=(rotatingAxisMotion&&) = delete;
|
||||||
|
|
||||||
|
FUNCTION_H
|
||||||
|
~rotatingAxisMotion() = default;
|
||||||
|
|
||||||
|
|
||||||
|
Model getModel()const
|
||||||
|
{
|
||||||
|
return Model(axis_.deviceVector(), numAxis_);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_H
|
||||||
|
int32 nameToIndex(const word& name)const
|
||||||
|
{
|
||||||
|
if( auto i = axisName_.findi(name); i == -1)
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"axis name " << name << " does not exist. \n";
|
||||||
|
fatalExit;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_H
|
||||||
|
word indexToName(label i)const
|
||||||
|
{
|
||||||
|
if(i < numAxis_ )
|
||||||
|
return axisName_[i];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"out of range access to the list of axes " << i <<endl<<
|
||||||
|
" size of axes_ is "<<numAxis_<<endl;
|
||||||
|
fatalExit;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
INLINE_FUNCTION_D
|
||||||
|
realx3 pointVelocity(label n, const realx3& p)const
|
||||||
|
{
|
||||||
|
return axis_.deviceVectorAll()[n].linTangentialVelocityPoint(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
INLINE_FUNCTION_D
|
||||||
|
realx3 transferPoint(label n, const realx3 p, real dt)const
|
||||||
|
{
|
||||||
|
return rotate(p, axis_.deviceVectorAll()[n], dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
INLINE_FUNCTION_D
|
||||||
|
bool transferPoint(label n, realx3* pVec, size_t numP, real dt)
|
||||||
|
{
|
||||||
|
if( n>=numAxis_)return false;
|
||||||
|
|
||||||
|
rotate( pVec, numP, axis_.deviceVectorAll()[n], dt);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_HD
|
||||||
|
bool isMoving()const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_FUNCTION_H
|
||||||
|
bool move(real dt)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FUNCTION_H
|
||||||
|
bool read(iIstream& is);
|
||||||
|
|
||||||
|
FUNCTION_H
|
||||||
|
bool write(iOstream& os)const;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // pFlow
|
||||||
|
|
||||||
|
#endif //__rotatingAxisMotion_H__
|
19
src/Particles/CMakeLists.txt
Normal file
19
src/Particles/CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
set(SourceFiles
|
||||||
|
dynamicPointStructure/dynamicPointStructure.C
|
||||||
|
particles/particles.C
|
||||||
|
SphereParticles/sphereShape/sphereShape.C
|
||||||
|
SphereParticles/sphereParticles/sphereParticles.C
|
||||||
|
Insertion/shapeMixture/shapeMixture.C
|
||||||
|
Insertion/insertion/insertion.C
|
||||||
|
Insertion/Insertion/Insertions.C
|
||||||
|
Insertion/insertionRegion/insertionRegion.C
|
||||||
|
Insertion/insertionRegion/timeFlowControl.C
|
||||||
|
)
|
||||||
|
|
||||||
|
set(link_libs Kokkos::kokkos phasicFlow Integration Property)
|
||||||
|
|
||||||
|
pFlow_add_library_install(Particles SourceFiles link_libs)
|
||||||
|
|
||||||
|
|
||||||
|
|
204
src/Particles/Insertion/Insertion/Insertion.C
Normal file
204
src/Particles/Insertion/Insertion/Insertion.C
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template<typename ShapeType>
|
||||||
|
bool pFlow::Insertion<ShapeType>::readInsertionDict
|
||||||
|
(
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if(!insertion::readInsertionDict(dict)) return false;
|
||||||
|
|
||||||
|
regions_.clear();
|
||||||
|
|
||||||
|
if( !this->isActive() )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
wordList regionDicNames = dict.dictionaryKeywords();
|
||||||
|
|
||||||
|
for(auto& name:regionDicNames)
|
||||||
|
{
|
||||||
|
Report(2)<<"reading insertion region "<< greenText(name)<<endReport;
|
||||||
|
regions_.push_backSafe(dict.subDict(name), shapes_);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ShapeType>
|
||||||
|
bool pFlow::Insertion<ShapeType>::writeInsertionDict
|
||||||
|
(
|
||||||
|
dictionary& dict
|
||||||
|
)const
|
||||||
|
{
|
||||||
|
if( !insertion::writeInsertionDict(dict) ) return false;
|
||||||
|
|
||||||
|
if( !this->isActive() ) return true;
|
||||||
|
|
||||||
|
forAll(i,regions_)
|
||||||
|
{
|
||||||
|
auto& rgnDict = dict.subDictOrCreate(regions_[i].name());
|
||||||
|
|
||||||
|
if( !regions_[i].write(rgnDict) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ShapeType>
|
||||||
|
pFlow::Insertion<ShapeType>::Insertion
|
||||||
|
(
|
||||||
|
particles& prtcl,
|
||||||
|
const ShapeType& shapes
|
||||||
|
)
|
||||||
|
:
|
||||||
|
insertion(prtcl),
|
||||||
|
shapes_(shapes)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename ShapeType>
|
||||||
|
bool pFlow::Insertion<ShapeType>::insertParticles
|
||||||
|
(
|
||||||
|
real currentTime,
|
||||||
|
real dt
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if(!isActive()) return true;
|
||||||
|
|
||||||
|
|
||||||
|
forAll(i,regions_)
|
||||||
|
{
|
||||||
|
bool insertionOccured = false;
|
||||||
|
auto& rgn = regions_[i];
|
||||||
|
if( rgn.insertionTime(currentTime, dt) )
|
||||||
|
{
|
||||||
|
|
||||||
|
realx3Vector pos;
|
||||||
|
wordVector shapes;
|
||||||
|
if( rgn.insertParticles(currentTime, dt, shapes, pos, insertionOccured) )
|
||||||
|
{
|
||||||
|
|
||||||
|
if(insertionOccured)
|
||||||
|
{
|
||||||
|
Report(0)<<"\nParticle insertion from "<< greenText(rgn.name())<<endReport;
|
||||||
|
Report(1)<< cyanText(pos.size()) << " new particles is being inserted at Time: "<<
|
||||||
|
cyanText(currentTime) <<" s."<<endReport;
|
||||||
|
|
||||||
|
if(!particles_.insertParticles(pos, shapes, rgn.setFields()))
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" Cannot add "<< pos.size() << " particles from region "<< rgn.name() <<
|
||||||
|
" to particles. \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Report(1)<<"Total number of particles inserted from this region is "<<
|
||||||
|
cyanText(rgn.totalInserted())<<'\n'<<endReport;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(insertionOccured)
|
||||||
|
{
|
||||||
|
Warning<< "\n fewer number of particles are inserted from region "<< rgn.name() <<
|
||||||
|
" than expected. You may stop the simulation to change settings."<<endWarning;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in inserting particles from region "<< rgn.name()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename ShapeType>
|
||||||
|
bool pFlow::Insertion<ShapeType>::read
|
||||||
|
(
|
||||||
|
iIstream& is
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
// create an empty dictionary
|
||||||
|
dictionary dict(is.name(), true);
|
||||||
|
|
||||||
|
if(!dict.read(is))
|
||||||
|
{
|
||||||
|
ioErrorInFile( is.name(), is.lineNumber() )<<
|
||||||
|
" error in reading "<< insertionFile__ << "dictionary from file."<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!readInsertionDict(dict))
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in reading from dictionary "<<dict.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ShapeType>
|
||||||
|
bool pFlow::Insertion<ShapeType>::write
|
||||||
|
(
|
||||||
|
iOstream& os
|
||||||
|
)const
|
||||||
|
{
|
||||||
|
|
||||||
|
dictionary dict(insertionFile__,true);
|
||||||
|
|
||||||
|
if(! writeInsertionDict(dict) )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in writing to " << dict.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !dict.write(os) )
|
||||||
|
{
|
||||||
|
ioErrorInFile(os.name(), os.lineNumber())<<
|
||||||
|
" erro in writing to "<< os.name()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
70
src/Particles/Insertion/Insertion/Insertion.H
Normal file
70
src/Particles/Insertion/Insertion/Insertion.H
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/*------------------------------- 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 __Insertion_H__
|
||||||
|
#define __Insertion_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "insertion.H"
|
||||||
|
#include "ListPtr.H"
|
||||||
|
#include "InsertionRegion.H"
|
||||||
|
#include "particles.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename ShapeType>
|
||||||
|
class Insertion
|
||||||
|
:
|
||||||
|
public insertion
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
const ShapeType& shapes_;
|
||||||
|
|
||||||
|
// - insertion regions
|
||||||
|
ListPtr<InsertionRegion<ShapeType>> regions_;
|
||||||
|
|
||||||
|
|
||||||
|
bool readInsertionDict(const dictionary& dict);
|
||||||
|
|
||||||
|
bool writeInsertionDict(dictionary& dict)const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeNameTemplateNV("Insertion",ShapeType);
|
||||||
|
|
||||||
|
Insertion(particles& prtcl, const ShapeType& shapes);
|
||||||
|
|
||||||
|
|
||||||
|
bool insertParticles(real currentTime, real dt);
|
||||||
|
|
||||||
|
virtual bool read(iIstream& is) override;
|
||||||
|
|
||||||
|
virtual bool write(iOstream& os)const override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "Insertion.C"
|
||||||
|
|
||||||
|
#endif
|
24
src/Particles/Insertion/Insertion/Insertions.C
Normal file
24
src/Particles/Insertion/Insertion/Insertions.C
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*------------------------------- 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 "Insertions.H"
|
||||||
|
|
||||||
|
template class pFlow::Insertion<pFlow::sphereShape>;
|
35
src/Particles/Insertion/Insertion/Insertions.H
Normal file
35
src/Particles/Insertion/Insertion/Insertions.H
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*------------------------------- 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 __Insertions_H__
|
||||||
|
#define __Insertions_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "Insertion.H"
|
||||||
|
#include "sphereShape.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
using sphereInsertion = Insertion<sphereShape> ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
115
src/Particles/Insertion/InsertionRegion/InsertionRegion.C
Normal file
115
src/Particles/Insertion/InsertionRegion/InsertionRegion.C
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template<typename ShapeType>
|
||||||
|
bool pFlow::InsertionRegion<ShapeType>::checkForContact
|
||||||
|
(
|
||||||
|
const realx3Vector& pos,
|
||||||
|
const realVector& diams,
|
||||||
|
const realx3& p,
|
||||||
|
const real& d
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
forAll(i, pos)
|
||||||
|
{
|
||||||
|
if( length(pos[i]-p) < 0.5*(diams[i]+d) ) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ShapeType>
|
||||||
|
pFlow::InsertionRegion<ShapeType>::InsertionRegion
|
||||||
|
(
|
||||||
|
const dictionary& dict,
|
||||||
|
const ShapeType& shapes
|
||||||
|
)
|
||||||
|
:
|
||||||
|
insertionRegion(dict),
|
||||||
|
shapes_(shapes)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename ShapeType>
|
||||||
|
bool pFlow::InsertionRegion<ShapeType>::insertParticles
|
||||||
|
(
|
||||||
|
real currentTime,
|
||||||
|
real dt,
|
||||||
|
wordVector& names,
|
||||||
|
realx3Vector& pos,
|
||||||
|
bool& insertionOccured
|
||||||
|
)
|
||||||
|
{
|
||||||
|
insertionOccured = false;
|
||||||
|
|
||||||
|
if(!insertionTime( currentTime, dt)) return true;
|
||||||
|
|
||||||
|
size_t newNum = numberToBeInserted(currentTime);
|
||||||
|
|
||||||
|
if(newNum == 0) return true;
|
||||||
|
|
||||||
|
names.reserve(max(newNum,names.capacity()));
|
||||||
|
pos.reserve(max(newNum,pos.capacity()));
|
||||||
|
names.clear();
|
||||||
|
pos.clear();
|
||||||
|
|
||||||
|
realVector diams(newNum, RESERVE());
|
||||||
|
|
||||||
|
mixture_->getNextShapeNameN(newNum, names);
|
||||||
|
|
||||||
|
if(!shapes_.shapeToDiameter(names,diams))
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error occured in insertion region "<< name() <<
|
||||||
|
" while converting shapes to diameter. \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t n = 0;
|
||||||
|
|
||||||
|
for(label iter=0; iter< 10*newNum ; ++iter)
|
||||||
|
{
|
||||||
|
if( !(n < newNum) )
|
||||||
|
{
|
||||||
|
addToNumInserted(newNum);
|
||||||
|
insertionOccured = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
realx3 p = pRegion_().peek();
|
||||||
|
real d = diams[pos.size()];
|
||||||
|
if( !checkForContact(pos, diams, p, d) )
|
||||||
|
{
|
||||||
|
pos.push_back(p);
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" Cannot insert "<< newNum << " new particles from region "<< name()<<". \n"
|
||||||
|
" pFlow could position only "<< n<< " particles in this region. \n";
|
||||||
|
addToNumInserted(n);
|
||||||
|
insertionOccured = false;
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
95
src/Particles/Insertion/InsertionRegion/InsertionRegion.H
Normal file
95
src/Particles/Insertion/InsertionRegion/InsertionRegion.H
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __InsertionRegion_H__
|
||||||
|
#define __InsertionRegion_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "insertionRegion.H"
|
||||||
|
#include "dictionary.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename ShapeType>
|
||||||
|
class InsertionRegion
|
||||||
|
:
|
||||||
|
public insertionRegion
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
// - type of particle shapes
|
||||||
|
const ShapeType& shapes_;
|
||||||
|
|
||||||
|
static bool checkForContact(
|
||||||
|
const realx3Vector& pos,
|
||||||
|
const realVector& diams,
|
||||||
|
const realx3& p,
|
||||||
|
const real& d);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// - type info
|
||||||
|
TypeNameTemplateNV("insertionRegion", ShapeType);
|
||||||
|
|
||||||
|
InsertionRegion(const dictionary& dict, const ShapeType& shapes);
|
||||||
|
|
||||||
|
InsertionRegion(const InsertionRegion<ShapeType>& ) = default;
|
||||||
|
|
||||||
|
InsertionRegion(InsertionRegion<ShapeType>&&) = default;
|
||||||
|
|
||||||
|
InsertionRegion<ShapeType>& operator=(const InsertionRegion<ShapeType>& ) = default;
|
||||||
|
|
||||||
|
InsertionRegion<ShapeType>& operator=(InsertionRegion<ShapeType>&&) = default;
|
||||||
|
|
||||||
|
|
||||||
|
auto clone()const
|
||||||
|
{
|
||||||
|
return makeUnique<InsertionRegion<ShapeType>>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto clonePtr()const
|
||||||
|
{
|
||||||
|
return new InsertionRegion<ShapeType>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool insertParticles
|
||||||
|
(
|
||||||
|
real currentTime,
|
||||||
|
real dt,
|
||||||
|
wordVector& names,
|
||||||
|
realx3Vector& pos,
|
||||||
|
bool& insertionOccured
|
||||||
|
);
|
||||||
|
|
||||||
|
//bool read(const dictionary& dict);
|
||||||
|
|
||||||
|
//bool write(dictionary& dict)const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // pFlow
|
||||||
|
|
||||||
|
|
||||||
|
#include "InsertionRegion.C"
|
||||||
|
|
||||||
|
#endif
|
74
src/Particles/Insertion/insertion/insertion.C
Normal file
74
src/Particles/Insertion/insertion/insertion.C
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/*------------------------------- 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 "particles.H"
|
||||||
|
#include "dictionary.H"
|
||||||
|
#include "insertion.H"
|
||||||
|
#include "streams.H"
|
||||||
|
|
||||||
|
bool pFlow::insertion::readInsertionDict
|
||||||
|
(
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
active_ = dict.getVal<Logical>("active");
|
||||||
|
|
||||||
|
if(active_)
|
||||||
|
Report(1)<< "Particle insertion mechanism is "<<
|
||||||
|
yellowText("active")<<" in the simulation."<<endReport;
|
||||||
|
else
|
||||||
|
Report(1)<< "Particle insertion mechanism is "<<
|
||||||
|
yellowText("not active")<<" in the simulation."<<endReport;
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::insertion::writeInsertionDict
|
||||||
|
(
|
||||||
|
dictionary& dict
|
||||||
|
)const
|
||||||
|
{
|
||||||
|
if(!dict.add("active", active_) )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in writing active to dictionary "<<dict.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!dict.add("checkForCollision", checkForCollision_) )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in writing checkForCollision to dictionary "<<dict.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pFlow::insertion::insertion
|
||||||
|
(
|
||||||
|
particles& prtcl
|
||||||
|
)
|
||||||
|
:
|
||||||
|
particles_(prtcl)
|
||||||
|
{}
|
72
src/Particles/Insertion/insertion/insertion.H
Normal file
72
src/Particles/Insertion/insertion/insertion.H
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*------------------------------- 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 __insertion_H__
|
||||||
|
#define __insertion_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "streams.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
class particles;
|
||||||
|
class dictionary;
|
||||||
|
|
||||||
|
class insertion
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
// - insertion active
|
||||||
|
Logical active_ = "No";
|
||||||
|
|
||||||
|
// - check for collision / desabled for now
|
||||||
|
Logical checkForCollision_ = "No";
|
||||||
|
|
||||||
|
// - particles
|
||||||
|
particles& particles_;
|
||||||
|
|
||||||
|
|
||||||
|
bool readInsertionDict(const dictionary& dict);
|
||||||
|
|
||||||
|
bool writeInsertionDict(dictionary& dict)const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// type info
|
||||||
|
TypeName("insertion");
|
||||||
|
|
||||||
|
insertion(particles& prtcl);
|
||||||
|
|
||||||
|
virtual ~insertion() = default;
|
||||||
|
|
||||||
|
bool isActive()const {
|
||||||
|
return active_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual bool read(iIstream& is) = 0;
|
||||||
|
|
||||||
|
virtual bool write(iOstream& os)const = 0;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
139
src/Particles/Insertion/insertionRegion/insertionRegion.C
Normal file
139
src/Particles/Insertion/insertionRegion/insertionRegion.C
Normal file
@ -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.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "insertionRegion.H"
|
||||||
|
#include "dictionary.H"
|
||||||
|
|
||||||
|
bool pFlow::insertionRegion::readInsertionRegion
|
||||||
|
(
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
name_ = dict.name();
|
||||||
|
type_ = dict.getVal<word>("type");
|
||||||
|
|
||||||
|
pRegion_ = peakableRegion::create(type_, dict.subDict(type_+"Info"));
|
||||||
|
|
||||||
|
mixture_ = makeUnique<shapeMixture>(dict.subDict("mixture"));
|
||||||
|
|
||||||
|
addToNumInserted(mixture_().totalInserted());
|
||||||
|
|
||||||
|
if( !dict.containsDictionay("setFields"))
|
||||||
|
{
|
||||||
|
output<<"\n insertion region "<< name_ << " does not contain setFields dictionary."
|
||||||
|
" An empty dictoiinary is created for it. \n";
|
||||||
|
setFields_ = makeUnique<setFieldList>( dictionary("setFields") );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setFields_ = makeUnique<setFieldList>( dict.subDict("setFields") );
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto& sfEntry:setFields_())
|
||||||
|
{
|
||||||
|
if(!sfEntry.checkForTypeAndValueAll())
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in setFields dictionary "<< dict.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::insertionRegion::writeInsertionRegion
|
||||||
|
(
|
||||||
|
dictionary& dict
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
|
||||||
|
if(!dict.add("type", type_)) return false;
|
||||||
|
|
||||||
|
|
||||||
|
if(pRegion_)
|
||||||
|
{
|
||||||
|
auto& prDict = dict.subDictOrCreate(type_+"Info");
|
||||||
|
if(!pRegion_().write(prDict)) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mixture_)
|
||||||
|
{
|
||||||
|
auto& mixDict = dict.subDictOrCreate("mixture");
|
||||||
|
if(!mixture_().write(mixDict)) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(setFields_)
|
||||||
|
{
|
||||||
|
auto& sfDict = dict.subDictOrCreate("setFields");
|
||||||
|
setFields_().write(sfDict);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pFlow::insertionRegion::insertionRegion
|
||||||
|
(
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
timeFlowControl(dict)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(!readInsertionRegion(dict))
|
||||||
|
{
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pFlow::insertionRegion::insertionRegion
|
||||||
|
(
|
||||||
|
const insertionRegion& src
|
||||||
|
)
|
||||||
|
:
|
||||||
|
timeFlowControl(src),
|
||||||
|
name_(src.name_),
|
||||||
|
type_(src.type_),
|
||||||
|
pRegion_( src.pRegion_? src.pRegion_->clone(): nullptr),
|
||||||
|
mixture_( src.mixture_? src.mixture_->clone(): nullptr),
|
||||||
|
setFields_( src.setFields_? src.setFields_->clone(): nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
pFlow::insertionRegion& pFlow::insertionRegion::operator=
|
||||||
|
(
|
||||||
|
const insertionRegion& src
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(&src == this)return *this;
|
||||||
|
timeFlowControl::operator=(src);
|
||||||
|
|
||||||
|
name_ = src.name_;
|
||||||
|
type_ = src.type_;
|
||||||
|
pRegion_ = (src.pRegion_? src.pRegion_->clone(): nullptr);
|
||||||
|
mixture_ = (src.mixture_? src.mixture_->clone(): nullptr);
|
||||||
|
setFields_ = (src.setFields_? src.setFields_->clone(): nullptr);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
114
src/Particles/Insertion/insertionRegion/insertionRegion.H
Normal file
114
src/Particles/Insertion/insertionRegion/insertionRegion.H
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/*------------------------------- 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 __insertionRegion_H__
|
||||||
|
#define __insertionRegion_H__
|
||||||
|
|
||||||
|
#include "timeFlowControl.H"
|
||||||
|
#include "shapeMixture.H"
|
||||||
|
#include "peakableRegions.H"
|
||||||
|
#include "setFieldList.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
class dictionary;
|
||||||
|
|
||||||
|
class insertionRegion
|
||||||
|
:
|
||||||
|
public timeFlowControl
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// - name of the region
|
||||||
|
word name_;
|
||||||
|
|
||||||
|
// - type of insertion region
|
||||||
|
word type_;
|
||||||
|
|
||||||
|
// peakable region of points
|
||||||
|
uniquePtr<peakableRegion> pRegion_ = nullptr;
|
||||||
|
|
||||||
|
// mixture of shapes
|
||||||
|
uniquePtr<shapeMixture> mixture_ = nullptr;
|
||||||
|
|
||||||
|
// setFields for insertion region
|
||||||
|
uniquePtr<setFieldList> setFields_ = nullptr;
|
||||||
|
|
||||||
|
|
||||||
|
bool readInsertionRegion(const dictionary& dict);
|
||||||
|
|
||||||
|
bool writeInsertionRegion(dictionary& dict) const;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeNameNV("insertionRegion");
|
||||||
|
|
||||||
|
//// - Constructors
|
||||||
|
|
||||||
|
insertionRegion(const dictionary& dict);
|
||||||
|
|
||||||
|
insertionRegion(const insertionRegion& src);
|
||||||
|
|
||||||
|
insertionRegion(insertionRegion&&) = default;
|
||||||
|
|
||||||
|
insertionRegion& operator=(const insertionRegion&);
|
||||||
|
|
||||||
|
insertionRegion& operator=(insertionRegion&&) = default;
|
||||||
|
|
||||||
|
|
||||||
|
~insertionRegion() = default;
|
||||||
|
|
||||||
|
|
||||||
|
//// - Methods
|
||||||
|
const auto& setFields()const
|
||||||
|
{
|
||||||
|
return setFields_();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& name()const
|
||||||
|
{
|
||||||
|
return name_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//// - IO operation
|
||||||
|
|
||||||
|
bool read(const dictionary& dict)
|
||||||
|
{
|
||||||
|
if(!timeFlowControl::read(dict))return false;
|
||||||
|
|
||||||
|
return readInsertionRegion(dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool write(dictionary& dict)const
|
||||||
|
{
|
||||||
|
if(!timeFlowControl::write(dict)) return false;
|
||||||
|
|
||||||
|
return writeInsertionRegion(dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} //pFlow
|
||||||
|
|
||||||
|
#endif //__insertionRegion_H__
|
62
src/Particles/Insertion/insertionRegion/timeFlowControl.C
Normal file
62
src/Particles/Insertion/insertionRegion/timeFlowControl.C
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "timeFlowControl.H"
|
||||||
|
#include "dictionary.H"
|
||||||
|
|
||||||
|
bool pFlow::timeFlowControl::readTimeFlowControl
|
||||||
|
(
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
rate_ = dict.getVal<real>("rate");
|
||||||
|
startTime_ = dict.getVal<real>("startTime");
|
||||||
|
endTime_ = dict.getVal<real>("endTime");
|
||||||
|
interval_ = dict.getVal<real>("interval");
|
||||||
|
numInserted_=0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::timeFlowControl::writeTimeFlowControl
|
||||||
|
(
|
||||||
|
dictionary& dict
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if(!dict.add("rate", rate_)) return false;
|
||||||
|
if(!dict.add("startTime", startTime_)) return false;
|
||||||
|
if(!dict.add("endTime", endTime_)) return false;
|
||||||
|
if(!dict.add("interval", interval_)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pFlow::timeFlowControl::timeFlowControl
|
||||||
|
(
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(!readTimeFlowControl(dict))
|
||||||
|
{
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
98
src/Particles/Insertion/insertionRegion/timeFlowControl.H
Normal file
98
src/Particles/Insertion/insertionRegion/timeFlowControl.H
Normal file
@ -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 __timeFlowControl_H__
|
||||||
|
#define __timeFlowControl_H__
|
||||||
|
|
||||||
|
#include "types.H"
|
||||||
|
#include "streams.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
class dictionary;
|
||||||
|
|
||||||
|
class timeFlowControl
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
real startTime_;
|
||||||
|
|
||||||
|
real endTime_;
|
||||||
|
|
||||||
|
real interval_;
|
||||||
|
|
||||||
|
real rate_;
|
||||||
|
|
||||||
|
size_t numInserted_ = 0;
|
||||||
|
|
||||||
|
bool readTimeFlowControl(const dictionary& dict);
|
||||||
|
|
||||||
|
bool writeTimeFlowControl(dictionary& dict) const;
|
||||||
|
|
||||||
|
size_t numberToBeInserted(real currentTime)
|
||||||
|
{
|
||||||
|
if(currentTime<startTime_)return 0;
|
||||||
|
if(currentTime>endTime_) return 0;
|
||||||
|
|
||||||
|
return static_cast<size_t>( (currentTime - startTime_ + interval_)*rate_ - numInserted_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t addToNumInserted(size_t newInserted)
|
||||||
|
{
|
||||||
|
return numInserted_ += newInserted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
timeFlowControl(const dictionary& dict);
|
||||||
|
|
||||||
|
|
||||||
|
bool insertionTime( real currentTime, real dt)
|
||||||
|
{
|
||||||
|
if(currentTime < startTime_) return false;
|
||||||
|
|
||||||
|
if(currentTime > endTime_) return false;
|
||||||
|
if( mod(abs(currentTime-startTime_),interval_)/dt < 1 ) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t totalInserted()const
|
||||||
|
{
|
||||||
|
return numInserted_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool read(const dictionary& dict)
|
||||||
|
{
|
||||||
|
return readTimeFlowControl(dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool write(dictionary& dict)const
|
||||||
|
{
|
||||||
|
return writeTimeFlowControl(dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //__timeFlowControl_H__
|
151
src/Particles/Insertion/shapeMixture/shapeMixture.C
Executable file
151
src/Particles/Insertion/shapeMixture/shapeMixture.C
Executable file
@ -0,0 +1,151 @@
|
|||||||
|
/*------------------------------- 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 "shapeMixture.H"
|
||||||
|
#include "dictionary.H"
|
||||||
|
|
||||||
|
|
||||||
|
pFlow::shapeMixture::shapeMixture
|
||||||
|
(
|
||||||
|
const dictionary & dict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if( !read(dict))
|
||||||
|
{
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pFlow::word pFlow::shapeMixture::getNextShapeName()
|
||||||
|
{
|
||||||
|
|
||||||
|
forAll(i, names_)
|
||||||
|
{
|
||||||
|
if(current_[i]< number_[i])
|
||||||
|
{
|
||||||
|
current_[i]++;
|
||||||
|
numberInserted_[i]++;
|
||||||
|
return names_[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fill(current_, static_cast<uint32>(0));
|
||||||
|
return getNextShapeName();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pFlow::shapeMixture::getNextShapeNameN
|
||||||
|
(
|
||||||
|
size_t n,
|
||||||
|
wordVector& names
|
||||||
|
)
|
||||||
|
{
|
||||||
|
names.clear();
|
||||||
|
|
||||||
|
|
||||||
|
for(label i=0; i<n; ++i)
|
||||||
|
{
|
||||||
|
names.push_back( getNextShapeName() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::shapeMixture::read(const dictionary& dict)
|
||||||
|
{
|
||||||
|
|
||||||
|
bool containNumberIneserted = false;
|
||||||
|
|
||||||
|
auto shNames = dict.dataEntryKeywords();
|
||||||
|
|
||||||
|
for (auto nm = shNames.begin(); nm != shNames.end(); )
|
||||||
|
{
|
||||||
|
if ( *nm == "numberInserted")
|
||||||
|
{
|
||||||
|
nm = shNames.erase(nm);
|
||||||
|
containNumberIneserted = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++nm;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const auto& nm:shNames)
|
||||||
|
{
|
||||||
|
names_.push_back(nm);
|
||||||
|
uint32 num = dict.getVal<uint32>(nm);
|
||||||
|
if( num <= 0 )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" number inserte in front of "<< nm << " is invalid: "<< num<<endl<<
|
||||||
|
" in dictionary "<<dict.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
number_.push_back( num );
|
||||||
|
}
|
||||||
|
|
||||||
|
if(containNumberIneserted)
|
||||||
|
{
|
||||||
|
numberInserted_ = dict.getVal<uint32Vector>("numberInserted");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
numberInserted_ = uint32Vector(size(), static_cast<uint32>(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(numberInserted_.size() != names_.size() )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" number of elements in numberInserted ("<<numberInserted_.size()<<
|
||||||
|
") is not equal to the number of shape names: "<< names_<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_.clear();
|
||||||
|
forAll(i, numberInserted_)
|
||||||
|
{
|
||||||
|
current_.push_back(numberInserted_[i]%number_[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::shapeMixture::write
|
||||||
|
(
|
||||||
|
dictionary& dict
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
|
||||||
|
forAll(i, names_)
|
||||||
|
{
|
||||||
|
if(!dict.add(names_[i],number_[i]))
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in writing "<< names_[i] << " to dictionary "<<dict.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!dict.add("numberInserted", numberInserted_))
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in writing numberInserted to dictionary "<< dict.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
104
src/Particles/Insertion/shapeMixture/shapeMixture.H
Executable file
104
src/Particles/Insertion/shapeMixture/shapeMixture.H
Executable file
@ -0,0 +1,104 @@
|
|||||||
|
/*------------------------------- 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 __shapeMixture_H__
|
||||||
|
#define __shapeMixture_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "Vectors.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
class dictionary;
|
||||||
|
|
||||||
|
class shapeMixture
|
||||||
|
{
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// - list of shape names
|
||||||
|
wordVector names_;
|
||||||
|
|
||||||
|
// - number composition
|
||||||
|
uint32Vector number_;
|
||||||
|
|
||||||
|
// - number inserted of each shape
|
||||||
|
uint32Vector numberInserted_;
|
||||||
|
|
||||||
|
uint32Vector current_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- type Info
|
||||||
|
TypeNameNV("shapeMixture");
|
||||||
|
|
||||||
|
//// - constrcutores
|
||||||
|
|
||||||
|
//
|
||||||
|
shapeMixture(const dictionary & dict);
|
||||||
|
|
||||||
|
shapeMixture(const shapeMixture&) = default;
|
||||||
|
|
||||||
|
shapeMixture(shapeMixture&&) = default;
|
||||||
|
|
||||||
|
shapeMixture& operator=(const shapeMixture&) = default;
|
||||||
|
|
||||||
|
shapeMixture& operator=(shapeMixture&&) = default;
|
||||||
|
|
||||||
|
|
||||||
|
uniquePtr<shapeMixture> clone()const
|
||||||
|
{
|
||||||
|
return makeUnique<shapeMixture>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
shapeMixture* clonePtr()const
|
||||||
|
{
|
||||||
|
return new shapeMixture(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
~shapeMixture() = default;
|
||||||
|
|
||||||
|
//// - Methods
|
||||||
|
word getNextShapeName();
|
||||||
|
|
||||||
|
|
||||||
|
void getNextShapeNameN(size_t n, wordVector& names);
|
||||||
|
|
||||||
|
|
||||||
|
auto size()const {
|
||||||
|
return names_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto totalInserted()const {
|
||||||
|
return sum(numberInserted_);
|
||||||
|
}
|
||||||
|
|
||||||
|
//// - IO operatoins
|
||||||
|
bool read(const dictionary& dict);
|
||||||
|
|
||||||
|
bool write(dictionary& dict) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // pFlow
|
||||||
|
|
||||||
|
#endif //__shapeMixture_H__
|
353
src/Particles/SphereParticles/sphereParticles/sphereParticles.C
Normal file
353
src/Particles/SphereParticles/sphereParticles/sphereParticles.C
Normal file
@ -0,0 +1,353 @@
|
|||||||
|
/*------------------------------- 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 "sphereParticles.H"
|
||||||
|
#include "setFieldList.H"
|
||||||
|
#include "sphereParticlesKernels.H"
|
||||||
|
|
||||||
|
pFlow::uniquePtr<pFlow::List<pFlow::eventObserver*>>
|
||||||
|
pFlow::sphereParticles::getFieldObjectList()const
|
||||||
|
{
|
||||||
|
auto objListPtr = particles::getFieldObjectList();
|
||||||
|
|
||||||
|
objListPtr().push_back(
|
||||||
|
static_cast<eventObserver*>(&I_) );
|
||||||
|
|
||||||
|
return objListPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::sphereParticles::diameterMassInertiaPropId
|
||||||
|
(
|
||||||
|
const word& shName,
|
||||||
|
real& diam,
|
||||||
|
real& mass,
|
||||||
|
real& I,
|
||||||
|
int8& propIdx
|
||||||
|
)
|
||||||
|
{
|
||||||
|
uint32 idx;
|
||||||
|
if( !shapes_.nameToIndex(shName, idx) )
|
||||||
|
{
|
||||||
|
printKeys(fatalErrorInFunction<<
|
||||||
|
" wrong shape name in the input: "<< shName<<endl<<
|
||||||
|
" available shape names are: ", shapes_.names())<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
diam = shapes_.diameter(idx);
|
||||||
|
word materialName = shapes_.material(idx);
|
||||||
|
uint32 pIdx;
|
||||||
|
if( !property_.nameToIndex(materialName, pIdx) )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction <<
|
||||||
|
" wrong material name "<< materialName <<" specified for shape "<< shName<<
|
||||||
|
" in the sphereShape dictionary.\n"<<
|
||||||
|
" available materials are "<< property_.materials()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
real rho = property_.density(pIdx);
|
||||||
|
|
||||||
|
mass = Pi/6.0*pow(diam,3.0)*rho;
|
||||||
|
I = 0.4 * mass * pow(diam/2.0,2.0);
|
||||||
|
propIdx= static_cast<int8>(pIdx);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::sphereParticles::initializeParticles()
|
||||||
|
{
|
||||||
|
|
||||||
|
int32IndexContainer indices(0, shapeName_.size());
|
||||||
|
return insertSphereParticles(shapeName_, indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool pFlow::sphereParticles::beforeIteration()
|
||||||
|
{
|
||||||
|
particles::beforeIteration();
|
||||||
|
|
||||||
|
intPredictTimer_.start();
|
||||||
|
dynPointStruct_.predict(this->dt(), accelertion_);
|
||||||
|
rVelIntegration_().predict(this->dt(),rVelocity_, rAcceleration_);
|
||||||
|
intPredictTimer_.end();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool pFlow::sphereParticles::iterate()
|
||||||
|
{
|
||||||
|
accelerationTimer_.start();
|
||||||
|
pFlow::sphereParticlesKernels::acceleration(
|
||||||
|
control().g(),
|
||||||
|
mass().deviceVectorAll(),
|
||||||
|
contactForce().deviceVectorAll(),
|
||||||
|
I().deviceVectorAll(),
|
||||||
|
contactTorque().deviceVectorAll(),
|
||||||
|
pStruct().activePointsMaskD(),
|
||||||
|
accelertion().deviceVectorAll(),
|
||||||
|
rAcceleration().deviceVectorAll()
|
||||||
|
);
|
||||||
|
accelerationTimer_.end();
|
||||||
|
|
||||||
|
intCorrectTimer_.start();
|
||||||
|
dynPointStruct_.correct(this->dt(), accelertion_);
|
||||||
|
rVelIntegration_().correct(this->dt(), rVelocity_, rAcceleration_);
|
||||||
|
intCorrectTimer_.end();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool pFlow::sphereParticles::afterIteration()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool pFlow::sphereParticles::insertSphereParticles(
|
||||||
|
const wordVector& names,
|
||||||
|
const int32IndexContainer& indices
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(names.size()!= indices.size())
|
||||||
|
{
|
||||||
|
fatalErrorInFunction <<
|
||||||
|
"sizes of names ("<<names.size()<<") and indices ("
|
||||||
|
<< indices.size()<<") do not match \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto len = names.size();
|
||||||
|
|
||||||
|
realVector diamVec(len, RESERVE());
|
||||||
|
realVector massVec(len, RESERVE());
|
||||||
|
realVector IVec(len, RESERVE());
|
||||||
|
int8Vector pIdVec(len, RESERVE());
|
||||||
|
int32Vector IdVec(len, RESERVE());
|
||||||
|
|
||||||
|
real d, m, I;
|
||||||
|
int8 pId;
|
||||||
|
|
||||||
|
forAll(i, names )
|
||||||
|
{
|
||||||
|
if (diameterMassInertiaPropId(names[i], d, m, I, pId))
|
||||||
|
{
|
||||||
|
diamVec.push_back(d);
|
||||||
|
massVec.push_back(m);
|
||||||
|
IVec.push_back(I);
|
||||||
|
pIdVec.push_back(pId);
|
||||||
|
IdVec.push_back(idHandler_.getNextId());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<< "failed to calculate properties of shape " <<
|
||||||
|
names[i]<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!diameter_.insertSetElement(indices, diamVec))
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<< " failed to insert diameters to the diameter field. \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!mass_.insertSetElement(indices, massVec))
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<< " failed to insert mass to the mass field. \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!I_.insertSetElement(indices, IVec))
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<< " failed to insert I to the I field. \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!propertyId_.insertSetElement(indices, pIdVec))
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<< " failed to insert propertyId to the propertyId field. \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!id_.insertSetElement(indices, IdVec))
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<< " failed to insert id to the id field. \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pFlow::sphereParticles::sphereParticles(
|
||||||
|
systemControl &control,
|
||||||
|
const property& prop
|
||||||
|
)
|
||||||
|
:
|
||||||
|
particles(
|
||||||
|
control,
|
||||||
|
control.settingsDict().getValOrSet(
|
||||||
|
"integrationMethod",
|
||||||
|
word("AdamsBashforth3")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
property_(prop),
|
||||||
|
shapes_(
|
||||||
|
control.caseSetup().emplaceObjectOrGet<sphereShape>(
|
||||||
|
objectFile(
|
||||||
|
sphereShapeFile__,
|
||||||
|
"",
|
||||||
|
objectFile::READ_ALWAYS,
|
||||||
|
objectFile::WRITE_NEVER
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
I_(
|
||||||
|
this->time().emplaceObject<realPointField_D>(
|
||||||
|
objectFile(
|
||||||
|
"I",
|
||||||
|
"",
|
||||||
|
objectFile::READ_NEVER,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
),
|
||||||
|
pStruct(),
|
||||||
|
static_cast<real>(0.0000000001)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
rVelocity_(
|
||||||
|
this->time().emplaceObject<realx3PointField_D>(
|
||||||
|
objectFile(
|
||||||
|
"rVelocity",
|
||||||
|
"",
|
||||||
|
objectFile::READ_IF_PRESENT,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
),
|
||||||
|
pStruct(),
|
||||||
|
zero3
|
||||||
|
)
|
||||||
|
),
|
||||||
|
rAcceleration_(
|
||||||
|
this->time().emplaceObject<realx3PointField_D>(
|
||||||
|
objectFile(
|
||||||
|
"rAcceleration",
|
||||||
|
"",
|
||||||
|
objectFile::READ_IF_PRESENT,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
),
|
||||||
|
pStruct(),
|
||||||
|
zero3
|
||||||
|
)
|
||||||
|
),
|
||||||
|
accelerationTimer_(
|
||||||
|
"Acceleration", &this->timers() ),
|
||||||
|
intPredictTimer_(
|
||||||
|
"Integration-predict", &this->timers() ),
|
||||||
|
intCorrectTimer_(
|
||||||
|
"Integration-correct", &this->timers() )
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
Report(1)<<"Creating integration method "<<greenText(this->integrationMethod())
|
||||||
|
<< " for rotational velocity."<<endReport;
|
||||||
|
|
||||||
|
rVelIntegration_ =
|
||||||
|
integration::create(
|
||||||
|
"rVelocity",
|
||||||
|
this->time().integration(),
|
||||||
|
this->pStruct(),
|
||||||
|
this->integrationMethod());
|
||||||
|
|
||||||
|
if( !rVelIntegration_ )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in creating integration object for rVelocity. \n";
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(!initializeParticles())
|
||||||
|
{
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool pFlow::sphereParticles::insertParticles
|
||||||
|
(
|
||||||
|
const realx3Vector& position,
|
||||||
|
const wordVector& shapes,
|
||||||
|
const setFieldList& setField
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
if( position.size() != shapes.size() )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" size of vectors position ("<<position.size()<<
|
||||||
|
") and shapes ("<<shapes.size()<<") are not the same. \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto exclusionListAllPtr = getFieldObjectList();
|
||||||
|
|
||||||
|
auto newInsertedPtr = pStruct().insertPoints( position, exclusionListAllPtr());
|
||||||
|
|
||||||
|
if(!newInsertedPtr)
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in inserting points into pStruct. \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& newInserted = newInsertedPtr();
|
||||||
|
|
||||||
|
if(!shapeName_.insertSetElement(newInserted, shapes))
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in inserting shapes into sphereParticles system.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !insertSphereParticles(shapes, newInserted) )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
"error in inserting shapes into the sphereParticles. \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto sfEntry:setField)
|
||||||
|
{
|
||||||
|
if(!sfEntry.setPointFieldSelectedAll( time(), newInserted, false ))return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto activeR = this->activeRange();
|
||||||
|
|
||||||
|
Report(1)<< "Active range is "<<yellowText("["<<activeR.first<<", "<<activeR.second<<")")<<
|
||||||
|
" and number of active points is "<< cyanText(this->numActive())<<
|
||||||
|
" and pointStructure capacity is "<<cyanText(this->capacity())<<endReport;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
191
src/Particles/SphereParticles/sphereParticles/sphereParticles.H
Normal file
191
src/Particles/SphereParticles/sphereParticles/sphereParticles.H
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
/*------------------------------- 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.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@class pFlow::sphereParticles
|
||||||
|
|
||||||
|
@brief Class for managing spherical particles
|
||||||
|
|
||||||
|
This is a top-level class that contains the essential components for
|
||||||
|
defining spherical prticles in a DEM simulation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __sphereParticles_H__
|
||||||
|
#define __sphereParticles_H__
|
||||||
|
|
||||||
|
#include "systemControl.H"
|
||||||
|
#include "particles.H"
|
||||||
|
#include "sphereShape.H"
|
||||||
|
#include "property.H"
|
||||||
|
#include "indexContainer.H"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
class sphereParticles
|
||||||
|
:
|
||||||
|
public particles
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/// reference to material properties
|
||||||
|
const property& property_;
|
||||||
|
|
||||||
|
/// reference to shapes
|
||||||
|
sphereShape& shapes_;
|
||||||
|
|
||||||
|
/// pointField of inertial of particles
|
||||||
|
realPointField_D& I_;
|
||||||
|
|
||||||
|
/// pointField of rotational Velocity of particles on device
|
||||||
|
realx3PointField_D& rVelocity_;
|
||||||
|
|
||||||
|
/// pointField of rotational acceleration of particles on device
|
||||||
|
realx3PointField_D& rAcceleration_;
|
||||||
|
|
||||||
|
/// rotational velocity integrator
|
||||||
|
uniquePtr<integration> rVelIntegration_ = nullptr;
|
||||||
|
|
||||||
|
/// timer for acceleration computations
|
||||||
|
Timer accelerationTimer_;
|
||||||
|
|
||||||
|
/// timer for integration computations (prediction step)
|
||||||
|
Timer intPredictTimer_;
|
||||||
|
|
||||||
|
/// timer for integration computations (correction step)
|
||||||
|
Timer intCorrectTimer_;
|
||||||
|
|
||||||
|
bool diameterMassInertiaPropId(const word& shName, real& diam, real& mass, real& I, int8& propIdx);
|
||||||
|
|
||||||
|
bool initializeParticles();
|
||||||
|
|
||||||
|
bool insertSphereParticles(const wordVector& names, const int32IndexContainer& indices);
|
||||||
|
|
||||||
|
virtual uniquePtr<List<eventObserver*>> getFieldObjectList()const override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// construct from systemControl and property
|
||||||
|
sphereParticles(systemControl &control, const property& prop);
|
||||||
|
|
||||||
|
/// no copy constructor
|
||||||
|
sphereParticles(const sphereParticles&) = delete;
|
||||||
|
|
||||||
|
/// move constructor
|
||||||
|
sphereParticles(sphereParticles&&) = default;
|
||||||
|
|
||||||
|
/// no copy-assignement
|
||||||
|
sphereParticles& operator=(const sphereParticles&) = delete;
|
||||||
|
|
||||||
|
/// move-assignement
|
||||||
|
sphereParticles& operator=(sphereParticles&&) = default;
|
||||||
|
|
||||||
|
virtual ~sphereParticles()=default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert new particles in position with specified shapes
|
||||||
|
*
|
||||||
|
* This function is involked by inserted object to insert new set of particles
|
||||||
|
* into the simulation.
|
||||||
|
* \param position position of new particles
|
||||||
|
* \param shape shape of new particles
|
||||||
|
* \param setField initial value of the selected fields for new particles
|
||||||
|
*/
|
||||||
|
bool insertParticles
|
||||||
|
(
|
||||||
|
const realx3Vector& position,
|
||||||
|
const wordVector& shapes,
|
||||||
|
const setFieldList& setField
|
||||||
|
) override ;
|
||||||
|
|
||||||
|
/// const reference to shapes object
|
||||||
|
const auto& shapes()const
|
||||||
|
{
|
||||||
|
return shapes_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// const reference to inertia pointField
|
||||||
|
const auto& I()const
|
||||||
|
{
|
||||||
|
return I_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// reference to inertia pointField
|
||||||
|
auto& I()
|
||||||
|
{
|
||||||
|
return I_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const realx3Vector_D rVelocity()const
|
||||||
|
{
|
||||||
|
return rVelocity_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const realVector_D& boundingSphere()const override
|
||||||
|
{
|
||||||
|
return this->diameter();
|
||||||
|
}
|
||||||
|
|
||||||
|
word shapeTypeName() const override
|
||||||
|
{
|
||||||
|
return "sphere";
|
||||||
|
}
|
||||||
|
|
||||||
|
void boundingSphereMinMax(
|
||||||
|
real& minDiam,
|
||||||
|
real& maxDiam )const override
|
||||||
|
{
|
||||||
|
shapes_.diameterMinMax(minDiam, maxDiam);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool update(const eventMessage& msg) override
|
||||||
|
{
|
||||||
|
CONSUME_PARAM(msg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
realx3PointField_D& rAcceleration() override
|
||||||
|
{
|
||||||
|
return rAcceleration_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const realx3PointField_D& rAcceleration() const override
|
||||||
|
{
|
||||||
|
return rAcceleration_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// before iteration step
|
||||||
|
bool beforeIteration() override;
|
||||||
|
|
||||||
|
/// iterate particles
|
||||||
|
bool iterate() override;
|
||||||
|
|
||||||
|
/// after iteration step
|
||||||
|
bool afterIteration() override;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}; //sphereParticles
|
||||||
|
|
||||||
|
} // pFlow
|
||||||
|
|
||||||
|
#endif //__sphereParticles_H__
|
@ -0,0 +1,77 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __sphereParticlesKernels_H__
|
||||||
|
#define __sphereParticlesKernels_H__
|
||||||
|
|
||||||
|
namespace pFlow::sphereParticlesKernels
|
||||||
|
{
|
||||||
|
|
||||||
|
using rpAcceleration = Kokkos::RangePolicy<
|
||||||
|
DefaultExecutionSpace,
|
||||||
|
Kokkos::Schedule<Kokkos::Static>,
|
||||||
|
Kokkos::IndexType<int32>
|
||||||
|
>;
|
||||||
|
|
||||||
|
template<typename IncludeFunctionType>
|
||||||
|
void acceleration(
|
||||||
|
realx3 g,
|
||||||
|
deviceViewType1D<real> mass,
|
||||||
|
deviceViewType1D<realx3> force,
|
||||||
|
deviceViewType1D<real> I,
|
||||||
|
deviceViewType1D<realx3> torque,
|
||||||
|
IncludeFunctionType incld,
|
||||||
|
deviceViewType1D<realx3> lAcc,
|
||||||
|
deviceViewType1D<realx3> rAcc
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Kokkos::fence();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
204
src/Particles/SphereParticles/sphereShape/sphereShape.C
Normal file
204
src/Particles/SphereParticles/sphereShape/sphereShape.C
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
/*------------------------------- 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 "sphereShape.H"
|
||||||
|
#include "dictionary.H"
|
||||||
|
#include "vocabs.H"
|
||||||
|
#include "streams.H"
|
||||||
|
|
||||||
|
|
||||||
|
bool pFlow::sphereShape::insertNames
|
||||||
|
(
|
||||||
|
const wordVector& names
|
||||||
|
)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool pFlow::sphereShape::readDictionary
|
||||||
|
(
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
diameters_ = dict.getVal<realVector>("diameters");
|
||||||
|
materials_ = dict.getVal<wordVector>("materials");
|
||||||
|
auto names = dict.getVal<wordVector>("names");
|
||||||
|
|
||||||
|
if(diameters_.size() != materials_.size() )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" number of elements in diameters and properties are not the same in "<< dict.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if(diameters_.size() != names.size() )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" number of elements in diameters and names are not the same in "<< dict.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !insertNames(names) )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in reading dictionary "<< dict.globalName();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::sphereShape::writeDictionary
|
||||||
|
(
|
||||||
|
dictionary& dict
|
||||||
|
)const
|
||||||
|
{
|
||||||
|
|
||||||
|
if( !dict.add("diamters", diameters_) )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" Error in writing diameters to dictionary "<< dict.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !dict.add("properties", materials_) )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" Error in writing properties to dictionary "<< dict.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t n = names_.size();
|
||||||
|
wordVector names(n);
|
||||||
|
names.clear();
|
||||||
|
word nm;
|
||||||
|
|
||||||
|
for(label i=0; i<n; i++)
|
||||||
|
{
|
||||||
|
indexToName(i, nm);
|
||||||
|
names.push_back(nm);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !dict.add("names", names) )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" Error in writing names to dictionary "<< dict.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pFlow::sphereShape::sphereShape
|
||||||
|
(
|
||||||
|
const realVector& diameter,
|
||||||
|
const wordVector& property,
|
||||||
|
const wordVector& name
|
||||||
|
)
|
||||||
|
:
|
||||||
|
diameters_(diameter),
|
||||||
|
materials_(property)
|
||||||
|
{
|
||||||
|
if( !insertNames( name) )
|
||||||
|
{
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::sphereShape::shapeToDiameter
|
||||||
|
(
|
||||||
|
wordVector& names,
|
||||||
|
realVector& diams
|
||||||
|
)const
|
||||||
|
{
|
||||||
|
diams.clear();
|
||||||
|
uint32 idx;
|
||||||
|
for(const auto& nm:names)
|
||||||
|
{
|
||||||
|
if(!nameToIndex(nm, idx))
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" invalid shape name requested "<< nm <<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
diams.push_back(diameters_[idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool pFlow::sphereShape::read(iIstream& is)
|
||||||
|
{
|
||||||
|
|
||||||
|
dictionary sphereDict(sphereShapeFile__, true);
|
||||||
|
|
||||||
|
if( !sphereDict.read(is) )
|
||||||
|
{
|
||||||
|
ioErrorInFile(is.name(), is.lineNumber()) <<
|
||||||
|
" error in reading dictionray " << sphereShapeFile__ <<" from file. \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !readDictionary(sphereDict) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::sphereShape::write(iOstream& os)const
|
||||||
|
{
|
||||||
|
|
||||||
|
dictionary sphereDict(sphereShapeFile__, true);
|
||||||
|
|
||||||
|
if( !writeDictionary(sphereDict))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !sphereDict.write(os) )
|
||||||
|
{
|
||||||
|
ioErrorInFile( os.name(), os.lineNumber() )<<
|
||||||
|
" error in writing dictionray to file. \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
177
src/Particles/SphereParticles/sphereShape/sphereShape.H
Normal file
177
src/Particles/SphereParticles/sphereShape/sphereShape.H
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
/*------------------------------- 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 __sphereShape_H__
|
||||||
|
#define __sphereShape_H__
|
||||||
|
|
||||||
|
#include "Vectors.H"
|
||||||
|
#include "hashMap.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
class dictionary;
|
||||||
|
|
||||||
|
class sphereShape
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// - diameter of spheres
|
||||||
|
realVector diameters_;
|
||||||
|
|
||||||
|
// - property name of spheres
|
||||||
|
wordVector materials_;
|
||||||
|
|
||||||
|
// - hashed list of spheres names
|
||||||
|
wordHashMap<uint32> names_;
|
||||||
|
|
||||||
|
size_t numShapes_;
|
||||||
|
|
||||||
|
|
||||||
|
bool insertNames(const wordVector& names);
|
||||||
|
|
||||||
|
bool readDictionary(const dictionary& dict);
|
||||||
|
|
||||||
|
bool writeDictionary(dictionary& dict)const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// - type info
|
||||||
|
TypeNameNV("sphereShape");
|
||||||
|
|
||||||
|
|
||||||
|
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<sphereShape>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
sphereShape* clonePtr()const
|
||||||
|
{
|
||||||
|
return new sphereShape(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
~sphereShape() = default;
|
||||||
|
|
||||||
|
//// - Methods
|
||||||
|
const auto& names()const{
|
||||||
|
return names_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& diameters()const{
|
||||||
|
return diameters_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& materials()const{
|
||||||
|
return materials_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto diameter(label i)const{
|
||||||
|
return diameters_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto material(label i)const{
|
||||||
|
return materials_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 nameToIndex(const word& name)const
|
||||||
|
{
|
||||||
|
return names_.at(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool indexToName(uint32 i, word& name)const
|
||||||
|
{
|
||||||
|
for(auto& nm: names_)
|
||||||
|
{
|
||||||
|
if(nm.second == i)
|
||||||
|
{
|
||||||
|
name = nm.first;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
name = "";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool shapeToDiameter(wordVector& names, realVector& diams)const;
|
||||||
|
|
||||||
|
void diameterMinMax(real& minD, real& maxD)const
|
||||||
|
{
|
||||||
|
minD = min(diameters_);
|
||||||
|
maxD = max(diameters_);
|
||||||
|
}
|
||||||
|
|
||||||
|
//// - IO operatoin
|
||||||
|
|
||||||
|
// - read from stream/file
|
||||||
|
bool read(iIstream& is);
|
||||||
|
|
||||||
|
// - write to stream/file
|
||||||
|
bool write(iOstream& os)const;
|
||||||
|
|
||||||
|
// - read from dictionary
|
||||||
|
bool read(const dictionary& dict)
|
||||||
|
{
|
||||||
|
return readDictionary(dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - write to dictionary
|
||||||
|
bool write(dictionary& dict)const
|
||||||
|
{
|
||||||
|
return writeDictionary(dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // pFlow
|
||||||
|
|
||||||
|
#endif //__sphereShape_H__
|
115
src/Particles/dynamicPointStructure/dynamicPointStructure.C
Normal file
115
src/Particles/dynamicPointStructure/dynamicPointStructure.C
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "dynamicPointStructure.H"
|
||||||
|
|
||||||
|
|
||||||
|
pFlow::dynamicPointStructure::dynamicPointStructure
|
||||||
|
(
|
||||||
|
Time& time,
|
||||||
|
const word& integrationMethod
|
||||||
|
)
|
||||||
|
:
|
||||||
|
time_(time),
|
||||||
|
integrationMethod_(integrationMethod),
|
||||||
|
pStruct_(
|
||||||
|
time_.emplaceObject<pointStructure>(
|
||||||
|
objectFile(
|
||||||
|
pointStructureFile__,
|
||||||
|
"",
|
||||||
|
objectFile::READ_ALWAYS,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
velocity_(
|
||||||
|
time_.emplaceObject<realx3PointField_D>(
|
||||||
|
objectFile(
|
||||||
|
"velocity",
|
||||||
|
"",
|
||||||
|
objectFile::READ_ALWAYS,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
),
|
||||||
|
pStruct_,
|
||||||
|
zero3
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
Report(1)<< "Creating integration method "<<
|
||||||
|
greenText(integrationMethod_)<<" for dynamicPointStructure."<<endReport;
|
||||||
|
|
||||||
|
integrationPos_ = integration::create(
|
||||||
|
"pStructPosition",
|
||||||
|
time_.integration(),
|
||||||
|
pStruct_,
|
||||||
|
integrationMethod_);
|
||||||
|
|
||||||
|
integrationVel_ = integration::create(
|
||||||
|
"pStructVelocity",
|
||||||
|
time_.integration(),
|
||||||
|
pStruct_,
|
||||||
|
integrationMethod_);
|
||||||
|
|
||||||
|
if( !integrationPos_ )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in creating integration object for dynamicPointStructure (position). \n";
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !integrationVel_ )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in creating integration object for dynamicPointStructure (velocity). \n";
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::dynamicPointStructure::predict
|
||||||
|
(
|
||||||
|
real dt,
|
||||||
|
realx3PointField_D& acceleration
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto& pos = pStruct_.pointPosition();
|
||||||
|
|
||||||
|
if(!integrationPos_().predict(dt, pos.VectorField(), velocity_.VectorField() ))return false;
|
||||||
|
if(!integrationVel_().predict(dt, velocity_.VectorField(), acceleration.VectorField()))return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::dynamicPointStructure::correct
|
||||||
|
(
|
||||||
|
real dt,
|
||||||
|
realx3PointField_D& acceleration
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto& pos = pStruct_.pointPosition();
|
||||||
|
|
||||||
|
if(!integrationPos_().correct(dt, pos.VectorField(), velocity_.VectorField() ))return false;
|
||||||
|
|
||||||
|
if(!integrationVel_().correct(dt, velocity_.VectorField(), acceleration.VectorField()))return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
87
src/Particles/dynamicPointStructure/dynamicPointStructure.H
Normal file
87
src/Particles/dynamicPointStructure/dynamicPointStructure.H
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/*------------------------------- 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 __dynamicPointStructure_H__
|
||||||
|
#define __dynamicPointStructure_H__
|
||||||
|
|
||||||
|
#include "Time.H"
|
||||||
|
#include "pointFields.H"
|
||||||
|
#include "integrations.H"
|
||||||
|
#include "uniquePtr.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
class dynamicPointStructure
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
Time& time_;
|
||||||
|
|
||||||
|
const word integrationMethod_;
|
||||||
|
|
||||||
|
pointStructure& pStruct_;
|
||||||
|
|
||||||
|
realx3PointField_D& velocity_;
|
||||||
|
|
||||||
|
uniquePtr<integration> integrationPos_;
|
||||||
|
|
||||||
|
uniquePtr<integration> integrationVel_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeName("dynamicPointStructure");
|
||||||
|
|
||||||
|
dynamicPointStructure(Time& time, const word& integrationMethod);
|
||||||
|
|
||||||
|
virtual ~dynamicPointStructure() = default;
|
||||||
|
|
||||||
|
inline pointStructure& pStruct()
|
||||||
|
{
|
||||||
|
return pStruct_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const pointStructure& pStruct() const
|
||||||
|
{
|
||||||
|
return pStruct_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const realx3PointField_D& velocity()const
|
||||||
|
{
|
||||||
|
return velocity_;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto markDeleteOutOfBox(const box& domain)
|
||||||
|
{
|
||||||
|
return pStruct_.markDeleteOutOfBox(domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool predict(real dt, realx3PointField_D& acceleration);
|
||||||
|
|
||||||
|
bool correct(real dt, realx3PointField_D& acceleration);
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
47
src/Particles/particles/demParticles.H
Normal file
47
src/Particles/particles/demParticles.H
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*------------------------------- 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 __demParticles_H__
|
||||||
|
#define __demParticles_H__
|
||||||
|
|
||||||
|
#include "demComponent.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
class demParticles
|
||||||
|
:
|
||||||
|
public demComponent
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
demParticles(systemControl& control):
|
||||||
|
demComponent("particles", control)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
81
src/Particles/particles/particleIdHandler.H
Normal file
81
src/Particles/particles/particleIdHandler.H
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/*------------------------------- 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 __particleIdHandler_H__
|
||||||
|
#define __particleIdHandler_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "pointFields.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
class particleIdHandler
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
int32 nextId_=0;
|
||||||
|
public:
|
||||||
|
particleIdHandler(int32PointField_HD & id)
|
||||||
|
{
|
||||||
|
int32 maxID = maxActive<DeviceSide>(id);
|
||||||
|
|
||||||
|
if( maxID != -1 && id.size() == 0 )
|
||||||
|
{
|
||||||
|
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<int32>(id.size()) )
|
||||||
|
{
|
||||||
|
nextId_ = maxID + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nextId_ = id.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 getNextId()
|
||||||
|
{
|
||||||
|
return nextId_++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 nextId() const
|
||||||
|
{
|
||||||
|
return nextId_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
162
src/Particles/particles/particles.C
Normal file
162
src/Particles/particles/particles.C
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "particles.H"
|
||||||
|
|
||||||
|
|
||||||
|
pFlow::particles::particles
|
||||||
|
(
|
||||||
|
systemControl& control,
|
||||||
|
const word& integrationMethod
|
||||||
|
)
|
||||||
|
:
|
||||||
|
demParticles(control),
|
||||||
|
time_(control.time()),
|
||||||
|
integrationMethod_(integrationMethod),
|
||||||
|
dynPointStruct_(
|
||||||
|
control.time(),
|
||||||
|
integrationMethod
|
||||||
|
),
|
||||||
|
shapeName_(
|
||||||
|
control.time().emplaceObject<wordPointField>(
|
||||||
|
objectFile(
|
||||||
|
"shapeName",
|
||||||
|
"",
|
||||||
|
objectFile::READ_ALWAYS,
|
||||||
|
objectFile::WRITE_ALWAYS,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
pStruct(),
|
||||||
|
word("NO_NAME_SHAPE")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
id_(
|
||||||
|
control.time().emplaceObject<int32PointField_HD>(
|
||||||
|
objectFile(
|
||||||
|
"id",
|
||||||
|
"",
|
||||||
|
objectFile::READ_IF_PRESENT,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
),
|
||||||
|
pStruct(),
|
||||||
|
static_cast<int32>(-1)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
propertyId_(
|
||||||
|
control.time().emplaceObject<int8PointField_D>(
|
||||||
|
objectFile(
|
||||||
|
"propertyId",
|
||||||
|
"",
|
||||||
|
objectFile::READ_NEVER,
|
||||||
|
objectFile::WRITE_NEVER
|
||||||
|
),
|
||||||
|
pStruct(),
|
||||||
|
static_cast<int8>(0)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
diameter_(
|
||||||
|
control.time().emplaceObject<realPointField_D>(
|
||||||
|
objectFile(
|
||||||
|
"diameter",
|
||||||
|
"",
|
||||||
|
objectFile::READ_NEVER,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
),
|
||||||
|
pStruct(),
|
||||||
|
static_cast<real>(0.00000000001)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
mass_(
|
||||||
|
control.time().emplaceObject<realPointField_D>(
|
||||||
|
objectFile(
|
||||||
|
"mass",
|
||||||
|
"",
|
||||||
|
objectFile::READ_NEVER,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
),
|
||||||
|
pStruct(),
|
||||||
|
static_cast<real>(0.0000000001)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
accelertion_(
|
||||||
|
control.time().emplaceObject<realx3PointField_D>(
|
||||||
|
objectFile(
|
||||||
|
"accelertion",
|
||||||
|
"",
|
||||||
|
objectFile::READ_IF_PRESENT,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
),
|
||||||
|
pStruct(),
|
||||||
|
zero3
|
||||||
|
)
|
||||||
|
),
|
||||||
|
contactForce_(
|
||||||
|
control.time().emplaceObject<realx3PointField_D>(
|
||||||
|
objectFile(
|
||||||
|
"contactForce",
|
||||||
|
"",
|
||||||
|
objectFile::READ_IF_PRESENT,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
),
|
||||||
|
pStruct(),
|
||||||
|
zero3
|
||||||
|
)
|
||||||
|
),
|
||||||
|
contactTorque_(
|
||||||
|
control.time().emplaceObject<realx3PointField_D>(
|
||||||
|
objectFile(
|
||||||
|
"contactTorque",
|
||||||
|
"",
|
||||||
|
objectFile::READ_IF_PRESENT,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
),
|
||||||
|
pStruct(),
|
||||||
|
zero3
|
||||||
|
)
|
||||||
|
),
|
||||||
|
idHandler_(id_)
|
||||||
|
{
|
||||||
|
|
||||||
|
this->subscribe(pStruct());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pFlow::uniquePtr<pFlow::List<pFlow::eventObserver*>>
|
||||||
|
pFlow::particles::getFieldObjectList()const
|
||||||
|
{
|
||||||
|
auto objListPtr = makeUnique<pFlow::List<pFlow::eventObserver*>>();
|
||||||
|
objListPtr().push_back(
|
||||||
|
static_cast<eventObserver*>(&id_) );
|
||||||
|
|
||||||
|
objListPtr().push_back(
|
||||||
|
static_cast<eventObserver*>(&propertyId_) );
|
||||||
|
|
||||||
|
objListPtr().push_back(
|
||||||
|
static_cast<eventObserver*>(&diameter_) );
|
||||||
|
|
||||||
|
objListPtr().push_back(
|
||||||
|
static_cast<eventObserver*>(&mass_) );
|
||||||
|
|
||||||
|
objListPtr().push_back(
|
||||||
|
static_cast<eventObserver*>(&shapeName_) );
|
||||||
|
|
||||||
|
return objListPtr;
|
||||||
|
}
|
291
src/Particles/particles/particles.H
Normal file
291
src/Particles/particles/particles.H
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
/*------------------------------- 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 __particles_H__
|
||||||
|
#define __particles_H__
|
||||||
|
|
||||||
|
#include "dynamicPointStructure.H"
|
||||||
|
#include "particleIdHandler.H"
|
||||||
|
#include "demParticles.H"
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
class setFieldList;
|
||||||
|
|
||||||
|
class particles
|
||||||
|
:
|
||||||
|
public eventObserver,
|
||||||
|
public demParticles
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// owner repository
|
||||||
|
Time& time_;
|
||||||
|
|
||||||
|
const word integrationMethod_;
|
||||||
|
|
||||||
|
// dynamic point structure for particles
|
||||||
|
dynamicPointStructure dynPointStruct_;
|
||||||
|
|
||||||
|
// - name of shapes - this is managed by particles
|
||||||
|
wordPointField& shapeName_;
|
||||||
|
|
||||||
|
// id of particles on host
|
||||||
|
int32PointField_HD& id_;
|
||||||
|
|
||||||
|
// property id on device
|
||||||
|
int8PointField_D& propertyId_;
|
||||||
|
|
||||||
|
// diameter / boundig sphere size of particles on device
|
||||||
|
realPointField_D& diameter_;
|
||||||
|
|
||||||
|
// mass on device
|
||||||
|
realPointField_D& mass_;
|
||||||
|
|
||||||
|
// - acceleration on device
|
||||||
|
realx3PointField_D& accelertion_;
|
||||||
|
|
||||||
|
|
||||||
|
realx3PointField_D& contactForce_;
|
||||||
|
|
||||||
|
|
||||||
|
realx3PointField_D& contactTorque_;
|
||||||
|
|
||||||
|
|
||||||
|
// - object handling particle id
|
||||||
|
particleIdHandler idHandler_;
|
||||||
|
|
||||||
|
virtual uniquePtr<List<eventObserver*>> getFieldObjectList()const;
|
||||||
|
|
||||||
|
void zeroForce()
|
||||||
|
{
|
||||||
|
contactForce_.fill(zero3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void zeroTorque()
|
||||||
|
{
|
||||||
|
contactTorque_.fill(zero3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// type info
|
||||||
|
TypeName("particles");
|
||||||
|
|
||||||
|
particles(systemControl& control, const word& integrationMethod);
|
||||||
|
|
||||||
|
inline const auto& time()const {
|
||||||
|
return time_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto& time() {
|
||||||
|
return time_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto integrationMethod()const
|
||||||
|
{
|
||||||
|
return integrationMethod_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const auto& dynPointStruct()const
|
||||||
|
{
|
||||||
|
return dynPointStruct_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto& dynPointStruct()
|
||||||
|
{
|
||||||
|
return dynPointStruct_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const auto& pStruct()const{
|
||||||
|
return dynPointStruct_.pStruct();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto& pStruct(){
|
||||||
|
return dynPointStruct_.pStruct();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto size()const{
|
||||||
|
return pStruct().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto capacity() const{
|
||||||
|
return pStruct().capacity();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto activePointsMaskD()const{
|
||||||
|
return pStruct().activePointsMaskD();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto numActive()const
|
||||||
|
{
|
||||||
|
return pStruct().numActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
return pStruct().pointPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const auto& pointVelocity()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(){
|
||||||
|
return accelertion_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
realx3PointField_D& contactForce()
|
||||||
|
{
|
||||||
|
return contactForce_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
const realx3PointField_D& contactForce() const
|
||||||
|
{
|
||||||
|
return contactForce_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
realx3PointField_D& contactTorque()
|
||||||
|
{
|
||||||
|
return contactTorque_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
const realx3PointField_D& 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
|
||||||
|
{
|
||||||
|
auto domain = this->control().domain();
|
||||||
|
|
||||||
|
auto numMarked = dynPointStruct_.markDeleteOutOfBox(domain);
|
||||||
|
/*if(numMarked)
|
||||||
|
{
|
||||||
|
output<<"\nNumber of deleted points/particles that are out of domain box: "<<numMarked<<endl;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
this->zeroForce();
|
||||||
|
this->zeroTorque();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual
|
||||||
|
bool insertParticles
|
||||||
|
(
|
||||||
|
const realx3Vector& position,
|
||||||
|
const wordVector& shapes,
|
||||||
|
const setFieldList& setField
|
||||||
|
) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
virtual
|
||||||
|
realx3PointField_D& rAcceleration() = 0;
|
||||||
|
|
||||||
|
virtual
|
||||||
|
const realx3PointField_D& rAcceleration() const = 0;
|
||||||
|
|
||||||
|
virtual
|
||||||
|
const realVector_D& boundingSphere()const = 0;
|
||||||
|
|
||||||
|
virtual
|
||||||
|
word shapeTypeName()const = 0;
|
||||||
|
|
||||||
|
virtual
|
||||||
|
void boundingSphereMinMax(real & minDiam, real& maxDiam)const = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}; // particles
|
||||||
|
|
||||||
|
} // pFlow
|
||||||
|
|
||||||
|
#endif //__particles_H__
|
11
src/Property/CMakeLists.txt
Normal file
11
src/Property/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
set(SourceFiles
|
||||||
|
property.C
|
||||||
|
)
|
||||||
|
|
||||||
|
set(link_libs Kokkos::kokkos phasicFlow)
|
||||||
|
|
||||||
|
pFlow_add_library_install(Property SourceFiles link_libs)
|
||||||
|
|
||||||
|
|
||||||
|
|
155
src/Property/property.C
Normal file
155
src/Property/property.C
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
/*------------------------------- 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 "property.H"
|
||||||
|
#include "dictionary.H"
|
||||||
|
|
||||||
|
bool pFlow::property::readDictionary
|
||||||
|
(
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
materials_ = dict.getVal<wordVector>("materials");
|
||||||
|
|
||||||
|
densities_ = dict.getVal<realVector>("densities");
|
||||||
|
|
||||||
|
if(materials_.size() != densities_.size() )
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" number of elements in material ("<<materials_.size()<<
|
||||||
|
") is not equal to number of elements in densities ("<<densities_.size()<<
|
||||||
|
") in dictionary "<< dict.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!makeNameIndex())
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in dictionary "<< dict.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::property::writeDictionary
|
||||||
|
(
|
||||||
|
dictionary& dict
|
||||||
|
)const
|
||||||
|
{
|
||||||
|
|
||||||
|
if(!dict.add("materials", materials_))
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in writing materials to dictionary "<< dict.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!dict.add("densities", densities_))
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in writing densities to dictionary "<< dict.globalName()<<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pFlow::property::makeNameIndex()
|
||||||
|
{
|
||||||
|
nameIndex_.clear();
|
||||||
|
|
||||||
|
uint32 i=0;
|
||||||
|
for(auto& nm:materials_)
|
||||||
|
{
|
||||||
|
if(!nameIndex_.insertIf(nm, i++))
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" repeated material name in the list of materials: " << materials_;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nameIndex_.rehash(0);
|
||||||
|
numMaterials_ = materials_.size();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pFlow::property::property
|
||||||
|
(
|
||||||
|
const wordVector& materials,
|
||||||
|
const realVector& densities
|
||||||
|
)
|
||||||
|
:
|
||||||
|
materials_(materials),
|
||||||
|
densities_(densities)
|
||||||
|
{
|
||||||
|
if(!makeNameIndex())
|
||||||
|
{
|
||||||
|
fatalErrorInFunction<<
|
||||||
|
" error in the input parameters of constructor. \n";
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pFlow::property::property
|
||||||
|
(
|
||||||
|
const fileSystem& file
|
||||||
|
)
|
||||||
|
:
|
||||||
|
dict_
|
||||||
|
(
|
||||||
|
makeUnique<dictionary>
|
||||||
|
("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<dictionary>(dict)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(!readDictionary(dict_()))
|
||||||
|
{
|
||||||
|
fatalExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
172
src/Property/property.H
Normal file
172
src/Property/property.H
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
/*------------------------------- 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 __property_H__
|
||||||
|
#define __property_H__
|
||||||
|
|
||||||
|
#include "Vectors.H"
|
||||||
|
#include "hashMap.H"
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
class dictionary;
|
||||||
|
|
||||||
|
class property
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
uniquePtr<dictionary> dict_ = nullptr;
|
||||||
|
|
||||||
|
// - name of materials
|
||||||
|
wordVector materials_;
|
||||||
|
|
||||||
|
// - density of materials
|
||||||
|
realVector densities_;
|
||||||
|
|
||||||
|
// fast mapping from name to index
|
||||||
|
wordHashMap<uint32> nameIndex_;
|
||||||
|
|
||||||
|
// - number of properties
|
||||||
|
uint32 numMaterials_ = 0;
|
||||||
|
|
||||||
|
bool readDictionary(const dictionary& dict);
|
||||||
|
|
||||||
|
bool writeDictionary(dictionary& dict)const;
|
||||||
|
|
||||||
|
bool makeNameIndex();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// type info
|
||||||
|
TypeNameNV("property");
|
||||||
|
|
||||||
|
// - emptry, for reading from file
|
||||||
|
property(){}
|
||||||
|
|
||||||
|
property(const wordVector& materils, const realVector& densities);
|
||||||
|
|
||||||
|
property(const fileSystem& file);
|
||||||
|
|
||||||
|
property(const dictionary& dict);
|
||||||
|
|
||||||
|
property(const property& ) = default;
|
||||||
|
|
||||||
|
property(property&& ) = default;
|
||||||
|
|
||||||
|
property& operator= (const property&) = default;
|
||||||
|
|
||||||
|
property& operator= (property&&) = default;
|
||||||
|
|
||||||
|
~property() = default;
|
||||||
|
|
||||||
|
//// - Methods
|
||||||
|
|
||||||
|
inline const auto& dict()const
|
||||||
|
{
|
||||||
|
return dict_();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto numMaterials()const
|
||||||
|
{
|
||||||
|
return numMaterials_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const auto& materials()const{
|
||||||
|
return materials_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - densities
|
||||||
|
inline const auto& densities()const{
|
||||||
|
return densities_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const word& material(uint32 i)const
|
||||||
|
{
|
||||||
|
return materials_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool material(uint32 i, word& name)const
|
||||||
|
{
|
||||||
|
if(i<numMaterials_)
|
||||||
|
{
|
||||||
|
name = material(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
name.clear();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline real density(uint32 i)const
|
||||||
|
{
|
||||||
|
return densities_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool density(uint32 i, real& rho)const
|
||||||
|
{
|
||||||
|
if(i<numMaterials_)
|
||||||
|
{
|
||||||
|
rho = density(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rho = 0.00001;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool nameToIndex(const word& name, uint32& idx)const
|
||||||
|
{
|
||||||
|
if(auto[iter, found] = nameIndex_.findIf(name); found )
|
||||||
|
{
|
||||||
|
idx = iter->second;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
idx = 0;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __property_H__
|
93
src/demComponent/demComponent.H
Normal file
93
src/demComponent/demComponent.H
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*------------------------------- 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 __demComponent_H__
|
||||||
|
#define __demComponent_H__
|
||||||
|
|
||||||
|
#include "systemControl.H"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace pFlow
|
||||||
|
{
|
||||||
|
|
||||||
|
class demComponent
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
word componentName_;
|
||||||
|
|
||||||
|
|
||||||
|
systemControl& control_;
|
||||||
|
|
||||||
|
|
||||||
|
Timers timers_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeName("demComponent");
|
||||||
|
|
||||||
|
demComponent(const word& name, systemControl& control)
|
||||||
|
:
|
||||||
|
componentName_(name),
|
||||||
|
control_(control),
|
||||||
|
timers_(name, &control.timers())
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual ~demComponent() = default;
|
||||||
|
|
||||||
|
|
||||||
|
const auto& control()const
|
||||||
|
{
|
||||||
|
return control_;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& control()
|
||||||
|
{
|
||||||
|
return control_;
|
||||||
|
}
|
||||||
|
|
||||||
|
real dt()const
|
||||||
|
{
|
||||||
|
return control_.time().dt();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& timers(){
|
||||||
|
return timers_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& timers() const{
|
||||||
|
return timers_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual bool beforeIteration() = 0;
|
||||||
|
|
||||||
|
|
||||||
|
virtual bool iterate() = 0;
|
||||||
|
|
||||||
|
|
||||||
|
virtual bool afterIteration() = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
30
src/setHelpers/finalize.H
Normal file
30
src/setHelpers/finalize.H
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*------------------------------- 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 __finalize_H__
|
||||||
|
#define __finalize_H__
|
||||||
|
|
||||||
|
// initilized and finalize should be placed in onc scope
|
||||||
|
}
|
||||||
|
pFlow::output<< "\nFinalizing host/device execution space ...."<<pFlow::endl;
|
||||||
|
Kokkos::finalize();
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
33
src/setHelpers/initialize.H
Normal file
33
src/setHelpers/initialize.H
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*------------------------------- phasicFlow ---------------------------------
|
||||||
|
O C enter of
|
||||||
|
O O E ngineering and
|
||||||
|
O O M ultiscale modeling of
|
||||||
|
OOOOOOO F luid flow
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Copyright (C): www.cemf.ir
|
||||||
|
email: hamid.r.norouzi AT gmail.com
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Licence:
|
||||||
|
This file is part of phasicFlow code. It is a free software for simulating
|
||||||
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||||
|
the terms of GNU General Public License v3 or any other later versions.
|
||||||
|
|
||||||
|
phasicFlow is distributed to help others in their research in the field of
|
||||||
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __initialize_H__
|
||||||
|
#define __initialize_H__
|
||||||
|
|
||||||
|
// initilized and finalize should be placed in onc scope
|
||||||
|
Report(0)<<"Initializing host/device execution spaces . . . \n";
|
||||||
|
Report(1)<<"Host execution space is "<< greenText(pFlow::DefaultHostExecutionSpace::name())<<endReport;
|
||||||
|
Report(1)<<"Device execution space is "<<greenText(pFlow::DefaultExecutionSpace::name())<<endReport;
|
||||||
|
|
||||||
|
Kokkos::initialize( argc, argv );
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
30
src/setHelpers/initialize_Control.H
Normal file
30
src/setHelpers/initialize_Control.H
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*------------------------------- 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 __initializedControl_H__
|
||||||
|
#define __initializedControl_H__
|
||||||
|
|
||||||
|
// initilized and finalize should be placed in onc scope
|
||||||
|
#include "initialize.H"
|
||||||
|
|
||||||
|
Report(0)<<"\nCreating Control repository . . ."<<endReport;
|
||||||
|
pFlow::systemControl Control;
|
||||||
|
|
||||||
|
#endif
|
34
src/setHelpers/setPointStructure.H
Normal file
34
src/setHelpers/setPointStructure.H
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*------------------------------- 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 __setPointStructure_H__
|
||||||
|
#define __setPointStructure_H__
|
||||||
|
|
||||||
|
auto& pStruct = Control().time().emplaceObject<pointStructure>(
|
||||||
|
objectFile(
|
||||||
|
pointStructureFile__,
|
||||||
|
"",
|
||||||
|
objectFile::READ_ALWAYS,
|
||||||
|
objectFile::WRITE_ALWAYS
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
29
src/setHelpers/setProperty.H
Normal file
29
src/setHelpers/setProperty.H
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/*------------------------------- 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 __setProperty_H__
|
||||||
|
#define __setProperty_H__
|
||||||
|
|
||||||
|
Report(0)<<"\nReading proprties . . . "<<endReport;
|
||||||
|
|
||||||
|
auto proprties = pFlow::property(Control.caseSetup().path()+pFlow::propertyFile__);
|
||||||
|
|
||||||
|
#endif
|
28
src/setHelpers/setSurfaceGeometry.H
Normal file
28
src/setHelpers/setSurfaceGeometry.H
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*------------------------------- 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 __setSurfaceGeometry_H__
|
||||||
|
#define __setSurfaceGeometry_H__
|
||||||
|
|
||||||
|
Report(0)<< "\nCreating surface geometry . . . "<<endReport;
|
||||||
|
auto surfGeometryPtr = pFlow::geometry::create(Control, proprties);
|
||||||
|
auto& surfGeometry = surfGeometryPtr();
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user