Adding Database
This commit is contained in:
parent
cd67724ab0
commit
d3e91bc829
@ -15,7 +15,7 @@ SET( TEST_MAX_PROCS 16 )
|
||||
|
||||
|
||||
# Initialize the project
|
||||
PROJECT( ${PROJ} )
|
||||
PROJECT( ${PROJ} LANGUAGES CXX )
|
||||
|
||||
|
||||
# Prevent users from building in place
|
||||
@ -25,8 +25,13 @@ ENDIF()
|
||||
|
||||
|
||||
# Set the default C++ standard
|
||||
IF ( NOT CXX_STD )
|
||||
SET( CXX_STD 11 )
|
||||
SET( CMAKE_CXX_EXTENSIONS OFF )
|
||||
IF ( NOT CMAKE_CXX_STANDARD )
|
||||
IF ( CXX_STD )
|
||||
MESSAGE( WARNING "CXX_STD is obsolete, please set CMAKE_CXX_STANDARD" )
|
||||
SET( CMAKE_CXX_STANDARD ${CXX_STD} )
|
||||
ENDIF()
|
||||
SET( CMAKE_CXX_STANDARD 11 )
|
||||
ENDIF()
|
||||
|
||||
|
||||
@ -113,6 +118,8 @@ ADD_DISTCLEAN( analysis null_timer tests liblbpm-wia.* cpu gpu example common vi
|
||||
|
||||
|
||||
# Check for CUDA
|
||||
CHECK_ENABLE_FLAG( USE_CUDA 0 )
|
||||
NULL_USE( CMAKE_CUDA_FLAGS )
|
||||
IF ( USE_CUDA )
|
||||
ADD_DEFINITIONS( -DUSE_CUDA )
|
||||
ENABLE_LANGUAGE( CUDA )
|
||||
|
@ -121,7 +121,7 @@ static std::vector<IO::MeshDatabase> writeMeshesOrigFormat( const std::vector<IO
|
||||
static IO::MeshDatabase getDatabase( const std::string& filename, const IO::MeshDataStruct& mesh, int format )
|
||||
{
|
||||
int rank = MPI_WORLD_RANK();
|
||||
char domainname[10];
|
||||
char domainname[100];
|
||||
sprintf(domainname,"%s_%05i",mesh.meshName.c_str(),rank);
|
||||
// Create the MeshDatabase
|
||||
IO::MeshDatabase database;
|
||||
@ -310,12 +310,11 @@ static void writeSiloDomainMesh( DBfile *fid, const IO::MeshDataStruct& meshData
|
||||
info.jy*mesh.Ly/info.ny, (info.jy+1)*mesh.Ly/info.ny,
|
||||
info.kz*mesh.Lz/info.nz, (info.kz+1)*mesh.Lz/info.nz };
|
||||
std::array<int,3> N = { mesh.nx, mesh.ny, mesh.nz };
|
||||
std::array<int,3> baseindex = { info.ix, info.jy, info.kz };
|
||||
const std::string meshname = database.domains[0].name;
|
||||
auto meshname = database.domains[0].name;
|
||||
silo::writeUniformMesh<3>( fid, meshname, range, N );
|
||||
silo::write<int>( fid, meshname+"_rankinfo", { mesh.rank, mesh.nprocx, mesh.nprocy, mesh.nprocz } );
|
||||
for (size_t i=0; i<meshData.vars.size(); i++) {
|
||||
const IO::Variable& var = *meshData.vars[i];
|
||||
const auto& var = *meshData.vars[i];
|
||||
auto type = static_cast<silo::VariableType>( var.type );
|
||||
if ( var.precision == IO::DataType::Double ) {
|
||||
silo::writeUniformMeshVariable<3>( fid, meshname, N, var.name, var.data, type );
|
||||
@ -336,10 +335,8 @@ static void writeSiloDomainMesh( DBfile *fid, const IO::MeshDataStruct& meshData
|
||||
static IO::MeshDatabase write_domain_silo( DBfile *fid, const std::string& filename,
|
||||
const IO::MeshDataStruct& mesh, int format )
|
||||
{
|
||||
const int level = 0;
|
||||
int rank = MPI_WORLD_RANK();
|
||||
// Create the MeshDatabase
|
||||
IO::MeshDatabase database = getDatabase( filename, mesh, format );
|
||||
auto database = getDatabase( filename, mesh, format );
|
||||
if ( database.meshClass=="PointList" ) {
|
||||
writeSiloPointList( fid, mesh, database );
|
||||
} else if ( database.meshClass=="TriMesh" ) {
|
||||
@ -429,7 +426,7 @@ static std::vector<IO::MeshDatabase> writeMeshesSilo(
|
||||
sprintf(fullpath,"%s/%s",path.c_str(),filename);
|
||||
auto fid = silo::open( fullpath, silo::CREATE );
|
||||
for (size_t i=0; i<meshData.size(); i++) {
|
||||
std::shared_ptr<IO::Mesh> mesh = meshData[i].mesh;
|
||||
auto mesh = meshData[i].mesh;
|
||||
meshes_written.push_back( write_domain_silo(fid,filename,meshData[i],format) );
|
||||
}
|
||||
silo::close( fid );
|
||||
|
@ -1,13 +1,10 @@
|
||||
#ifndef Eikonal_HPP_INC
|
||||
#define Eikonal_HPP_INC
|
||||
|
||||
#include "analysis/eikonal.h"
|
||||
#include "analysis/imfilter.h"
|
||||
|
||||
|
||||
|
||||
|
||||
inline float minmod(float &a, float &b)
|
||||
static inline float minmod(float &a, float &b)
|
||||
{
|
||||
float value = a;
|
||||
if ( a*b < 0.0)
|
||||
@ -18,7 +15,7 @@ inline float minmod(float &a, float &b)
|
||||
}
|
||||
|
||||
|
||||
inline double minmod(double &a, double &b){
|
||||
static inline double minmod(double &a, double &b){
|
||||
|
||||
double value;
|
||||
|
||||
@ -33,9 +30,8 @@ inline double minmod(double &a, double &b){
|
||||
/******************************************************************
|
||||
* Solve the eikonal equation *
|
||||
******************************************************************/
|
||||
|
||||
|
||||
inline double Eikonal(DoubleArray &Distance, char *ID, Domain &Dm, int timesteps){
|
||||
double Eikonal(DoubleArray &Distance, const char *ID, const Domain &Dm, int timesteps)
|
||||
{
|
||||
|
||||
/*
|
||||
* This routine converts the data in the Distance array to a signed distance
|
||||
@ -180,7 +176,7 @@ inline double Eikonal(DoubleArray &Distance, char *ID, Domain &Dm, int timesteps
|
||||
return GlobalVar;
|
||||
}
|
||||
|
||||
inline float Eikonal3D( Array<float> &Distance, const Array<char> &ID, const Domain &Dm, const int timesteps)
|
||||
float Eikonal3D( Array<float> &Distance, const Array<char> &ID, const Domain &Dm, const int timesteps)
|
||||
{
|
||||
PROFILE_START("Eikonal3D");
|
||||
|
||||
@ -327,7 +323,7 @@ inline float Eikonal3D( Array<float> &Distance, const Array<char> &ID, const Dom
|
||||
/******************************************************************
|
||||
* A fast distance calculation *
|
||||
******************************************************************/
|
||||
inline bool CalcDist3DIteration( Array<float> &Distance, const Domain &Dm )
|
||||
bool CalcDist3DIteration( Array<float> &Distance, const Domain &Dm )
|
||||
{
|
||||
const float sq2 = sqrt(2.0f);
|
||||
const float sq3 = sqrt(3.0f);
|
||||
@ -367,7 +363,7 @@ inline bool CalcDist3DIteration( Array<float> &Distance, const Domain &Dm )
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
inline void CalcDist3D( Array<float> &Distance, const Array<char> &ID, const Domain &Dm )
|
||||
void CalcDist3D( Array<float> &Distance, const Array<char> &ID, const Domain &Dm )
|
||||
{
|
||||
PROFILE_START("Calc Distance");
|
||||
// Initialize the distance to be 0 fore the cells adjacent to the interface
|
||||
@ -402,7 +398,7 @@ inline void CalcDist3D( Array<float> &Distance, const Array<char> &ID, const Dom
|
||||
/******************************************************************
|
||||
* A fast distance calculation *
|
||||
******************************************************************/
|
||||
inline void CalcDistMultiLevelHelper( Array<float> &Distance, const Domain &Dm )
|
||||
void CalcDistMultiLevelHelper( Array<float> &Distance, const Domain &Dm )
|
||||
{
|
||||
size_t ratio = 4;
|
||||
std::function<float(const Array<float>&)> coarsen = [ratio]( const Array<float>& data )
|
||||
@ -440,7 +436,10 @@ inline void CalcDistMultiLevelHelper( Array<float> &Distance, const Domain &Dm )
|
||||
// Coarsen
|
||||
Array<float> dist(Nx,Ny,Nz);
|
||||
fillData.copy(Distance,dist);
|
||||
Domain Dm2(Nx/ratio,Ny/ratio,Nz/ratio,Dm.rank,Dm.nprocx,Dm.nprocy,Dm.nprocz,Dm.Lx,Dm.Ly,Dm.Lz,0);
|
||||
auto db = Dm.getDatabase()->cloneDatabase();
|
||||
auto n = db->getVector<int>( "n" );
|
||||
db->putVector<int>( "n", { n[0]/ratio, n[1]/ratio, n[2]/ratio } );
|
||||
Domain Dm2(db);
|
||||
Dm2.CommInit(Dm.Comm);
|
||||
fillHalo<float> fillData2(Dm2.Comm,Dm2.rank_info,Nx/ratio,Ny/ratio,Nz/ratio,1,1,1,0,1);
|
||||
auto dist2 = dist.coarsen( {ratio,ratio,ratio}, coarsen );
|
||||
@ -483,7 +482,7 @@ inline void CalcDistMultiLevelHelper( Array<float> &Distance, const Domain &Dm )
|
||||
}
|
||||
}
|
||||
}
|
||||
inline void CalcDistMultiLevel( Array<float> &Distance, const Array<char> &ID, const Domain &Dm )
|
||||
void CalcDistMultiLevel( Array<float> &Distance, const Array<char> &ID, const Domain &Dm )
|
||||
{
|
||||
PROFILE_START("Calc Distance Multilevel");
|
||||
int Nx = Dm.Nx-2;
|
||||
@ -515,5 +514,3 @@ inline void CalcDistMultiLevel( Array<float> &Distance, const Array<char> &ID, c
|
||||
Distance = imfilter::imfilter_separable<float>( Distance, {H,H,H}, BC );
|
||||
PROFILE_STOP("Calc Distance Multilevel");
|
||||
}
|
||||
|
||||
#endif
|
@ -1,6 +1,7 @@
|
||||
#ifndef Eikonal_H_INC
|
||||
#define Eikonal_H_INC
|
||||
|
||||
#include "common/Domain.h"
|
||||
|
||||
|
||||
/*!
|
||||
@ -21,7 +22,7 @@
|
||||
* @param[in] timesteps Maximum number of timesteps to process
|
||||
* @return Returns the global variation
|
||||
*/
|
||||
inline double Eikonal(DoubleArray &Distance, const char *ID, const Domain &Dm, int timesteps);
|
||||
double Eikonal(DoubleArray &Distance, const char *ID, const Domain &Dm, int timesteps);
|
||||
|
||||
float Eikonal3D( Array<float> &Distance, const Array<char> &ID, const Domain &Dm, const int timesteps);
|
||||
|
||||
@ -52,7 +53,4 @@ void CalcDist3D( Array<float> &Distance, const Array<char> &ID, const Domain &Dm
|
||||
void CalcDistMultiLevel( Array<float> &Distance, const Array<char> &ID, const Domain &Dm );
|
||||
|
||||
|
||||
|
||||
#include "analysis/eikonal.hpp"
|
||||
|
||||
#endif
|
||||
|
@ -35,11 +35,14 @@ IF ( ${CMAKE_BUILD_TYPE} STREQUAL "Release" AND ${CMAKE_VERSION} VERSION_GREATER
|
||||
CHECK_IPO_SUPPORTED(RESULT supported OUTPUT error)
|
||||
IF( supported )
|
||||
MESSAGE(STATUS "IPO / LTO enabled")
|
||||
SET( LTO TRUE )
|
||||
SET( CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE )
|
||||
ELSE()
|
||||
MESSAGE(STATUS "IPO / LTO not supported: <${error}>")
|
||||
SET( LTO FALSE )
|
||||
MESSAGE(STATUS "IPO / LTO not supported")
|
||||
ENDIF()
|
||||
ELSEIF( NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION )
|
||||
SET( LTO FALSE )
|
||||
MESSAGE(STATUS "IPO / LTO disabled")
|
||||
ENDIF()
|
||||
|
||||
@ -320,7 +323,7 @@ MACRO( INSTALL_PROJ_LIB )
|
||||
FOREACH ( tmp ${${PROJ}_LIBS} )
|
||||
SET( tmp_link_list ${tmp_link_list} $<TARGET_OBJECTS:${tmp}> )
|
||||
ENDFOREACH()
|
||||
ADD_LIBRARY( ${${PROJ}_LIB} ${tmp_link_list} )
|
||||
ADD_LIBRARY( ${${PROJ}_LIB} ${LIB_TYPE} ${tmp_link_list} )
|
||||
TARGET_LINK_EXTERNAL_LIBRARIES( ${${PROJ}_LIB} LINK_PUBLIC )
|
||||
INSTALL( TARGETS ${${PROJ}_LIB} DESTINATION ${${PROJ}_INSTALL_DIR}/lib )
|
||||
ENDMACRO()
|
||||
@ -408,6 +411,9 @@ MACRO( IDENTIFY_COMPILER )
|
||||
IF( CMAKE_COMPILER_IS_GNUG77 OR (${CMAKE_Fortran_COMPILER_ID} MATCHES "GNU") )
|
||||
SET( USING_GFORTRAN TRUE )
|
||||
MESSAGE("Using gfortran")
|
||||
IF ( NOT USING_GCC )
|
||||
LIST( REMOVE_ITEM CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES gcc )
|
||||
ENDIF()
|
||||
ELSEIF ( (${CMAKE_Fortran_COMPILER_ID} MATCHES "Intel") )
|
||||
SET(USING_IFORT TRUE)
|
||||
MESSAGE("Using ifort")
|
||||
@ -477,76 +483,6 @@ MACRO( ADD_USER_FLAGS )
|
||||
ENDMACRO()
|
||||
|
||||
|
||||
# Macro to add user c++ std
|
||||
MACRO( ADD_CXX_STD )
|
||||
IF ( NOT CXX_STD )
|
||||
MESSAGE( FATAL_ERROR "The desired c++ standard must be specified: CXX_STD=(98,11,14,NONE)")
|
||||
ENDIF()
|
||||
IF ( ${CXX_STD} STREQUAL "NONE" )
|
||||
# Do nothing
|
||||
return()
|
||||
ELSEIF ( (NOT ${CXX_STD} STREQUAL "98") AND (NOT ${CXX_STD} STREQUAL "11") AND (NOT ${CXX_STD} STREQUAL "14") )
|
||||
MESSAGE( FATAL_ERROR "Unknown c++ standard (98,11,14,NONE)" )
|
||||
ENDIF()
|
||||
# Add the flags
|
||||
SET( CMAKE_CXX_STANDARD ${CXX_STD} )
|
||||
MESSAGE( "C++ standard: ${CXX_STD}" )
|
||||
SET( CXX_STD_FLAG )
|
||||
IF ( USING_GCC )
|
||||
# GNU: -std=
|
||||
IF ( ${CXX_STD} STREQUAL "98" )
|
||||
SET( CXX_STD_FLAG -std=c++98 )
|
||||
ELSEIF ( ${CXX_STD} STREQUAL "11" )
|
||||
SET( CXX_STD_FLAG -std=c++11 )
|
||||
ELSEIF ( ${CXX_STD} STREQUAL "14" )
|
||||
SET( CXX_STD_FLAG -std=c++1y )
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "Unknown standard")
|
||||
ENDIF()
|
||||
ELSEIF ( USING_MSVC )
|
||||
# Microsoft: Does not support this level of control
|
||||
ELSEIF ( USING_ICC )
|
||||
# ICC: -std=
|
||||
SET( CXX_STD_FLAG -std=c++${CXX_STD} )
|
||||
ELSEIF ( USING_CRAY )
|
||||
# Cray: Does not seem to support controlling the std?
|
||||
ELSEIF ( USING_PGCC )
|
||||
# PGI: -std=
|
||||
IF ( ${CXX_STD} STREQUAL "98" )
|
||||
SET( CXX_STD_FLAG --c++0x )
|
||||
ELSEIF ( ${CXX_STD} STREQUAL "11" )
|
||||
SET( CXX_STD_FLAG --c++11 )
|
||||
ELSEIF ( ${CXX_STD} STREQUAL "14" )
|
||||
MESSAGE( FATAL_ERROR "C++14 features are not availible yet for PGI" )
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "Unknown standard")
|
||||
ENDIF()
|
||||
ELSEIF ( USING_CLANG )
|
||||
# Clang: -std=
|
||||
IF ( ( ${CXX_STD} STREQUAL "98") OR ( ${CXX_STD} STREQUAL "11" ) )
|
||||
SET( CXX_STD_FLAG -std=c++${CXX_STD} )
|
||||
ELSEIF ( ${CXX_STD} STREQUAL "14" )
|
||||
SET( CXX_STD_FLAG -std=c++1y )
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "Unknown standard")
|
||||
ENDIF()
|
||||
ELSEIF ( USING_XL )
|
||||
# XL: -std=
|
||||
IF ( ( ${CXX_STD} STREQUAL "98") OR ( ${CXX_STD} STREQUAL "11" ) )
|
||||
SET( CXX_STD_FLAG -std=c++${CXX_STD} )
|
||||
ELSEIF ( ${CXX_STD} STREQUAL "14" )
|
||||
SET( CXX_STD_FLAG -std=c++1y )
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "Unknown standard")
|
||||
ENDIF()
|
||||
ELSEIF ( USING_DEFAULT )
|
||||
# Default: do nothing
|
||||
ENDIF()
|
||||
ADD_DEFINITIONS( -DCXX_STD=${CXX_STD} )
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STD_FLAG}")
|
||||
ENDMACRO()
|
||||
|
||||
|
||||
# Macro to set the compile/link flags
|
||||
MACRO( SET_COMPILER_FLAGS )
|
||||
# Initilaize the compiler
|
||||
@ -585,8 +521,6 @@ MACRO( SET_COMPILER_FLAGS )
|
||||
SET( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "Release flags" FORCE)
|
||||
# Add the user flags
|
||||
ADD_USER_FLAGS()
|
||||
# Add the c++ standard flags
|
||||
ADD_CXX_STD()
|
||||
# Set the warnings to use
|
||||
SET_WARNINGS()
|
||||
# Test the compile flags
|
||||
@ -1098,71 +1032,19 @@ ENDMACRO()
|
||||
|
||||
|
||||
# Add a matlab mex file
|
||||
FUNCTION( ADD_MATLAB_MEX MEXFILE )
|
||||
# Set the MEX compiler and default link flags
|
||||
IF ( USING_MSVC )
|
||||
SET( MEX_LDFLAGS ${MEX_LDFLAGS} -L${CMAKE_CURRENT_BINARY_DIR}/..
|
||||
-L${CMAKE_CURRENT_BINARY_DIR}/../Debug -L${CMAKE_CURRENT_BINARY_DIR} )
|
||||
ENDIF()
|
||||
SET( MEX_LDFLAGS ${MEX_LDFLAGS} -L${CMAKE_CURRENT_BINARY_DIR}/.. -L${CMAKE_CURRENT_BINARY_DIR}/../.. ${SYSTEM_LDFLAGS} )
|
||||
SET( MEX_LIBS ${MEX_LIBS} ${SYSTEM_LIBS} )
|
||||
IF ( NOT USING_MSVC )
|
||||
FOREACH( rpath ${CMAKE_INSTALL_RPATH} )
|
||||
SET( MEX_LDFLAGS ${MEX_LDFLAGS} "-Wl,-rpath,${rpath},--no-undefined" )
|
||||
ENDFOREACH()
|
||||
ENDIF()
|
||||
IF ( "${CMAKE_BUILD_TYPE}" STREQUAL "Debug" )
|
||||
SET( MEX_FLAGS ${MEX_FLAGS} -g )
|
||||
ELSEIF ( "${CMAKE_BUILD_TYPE}" STREQUAL "Release" )
|
||||
SET( MEX_FLAGS ${MEX_FLAGS} -O )
|
||||
ELSE()
|
||||
MESSAGE( FATAL_ERROR "Unknown build type: ${CMAKE_BUILD_TYPE}" )
|
||||
ENDIF()
|
||||
# Create the mex comamnd
|
||||
STRING(REGEX REPLACE "[.]cpp" "" TARGET ${MEXFILE})
|
||||
STRING(REGEX REPLACE "[.]c" "" TARGET ${TARGET})
|
||||
FILE(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/temp/${TARGET}" )
|
||||
IF ( USING_MSVC )
|
||||
SET( MEX_BAT_FILE "${CMAKE_CURRENT_BINARY_DIR}/temp/${TARGET}/compile_mex.bat" )
|
||||
FILE( WRITE "${MEX_BAT_FILE}" "${MEX_EXE} \"${CMAKE_CURRENT_SOURCE_DIR}/${MEXFILE}\" " )
|
||||
APPEND_LIST( "${MEX_BAT_FILE}" "${MEX_FLAGS}" "\"" "\" " )
|
||||
APPEND_LIST( "${MEX_BAT_FILE}" "${COMPFLAGS}" "\"" "\" " )
|
||||
APPEND_LIST( "${MEX_BAT_FILE}" "${MEX_INCLUDE}" "\"" "\" " )
|
||||
APPEND_LIST( "${MEX_BAT_FILE}" "${MEX_LDFLAGS}" "\"" "\" " )
|
||||
APPEND_LIST( "${MEX_BAT_FILE}" "${MEX_LIBS}" "\"" "\" " )
|
||||
APPEND_LIST( "${MEX_BAT_FILE}" "${COVERAGE_MATLAB_LIBS}" "\"" "\" " )
|
||||
SET( MEX_COMMAND "${MEX_BAT_FILE}" )
|
||||
ELSE()
|
||||
STRING(REPLACE " " ";" MEX_CFLAGS "$$CFLAGS ${CMAKE_C_FLAGS}")
|
||||
STRING(REPLACE " " ";" MEX_CXXFLAGS "$$CXXFLAGS ${CMAKE_CXX_FLAGS}")
|
||||
SET( MEX_COMMAND ${MEX_EXE} ${CMAKE_CURRENT_SOURCE_DIR}/${MEXFILE}
|
||||
${MEX_FLAGS} ${MEX_INCLUDE}
|
||||
CFLAGS="${MEX_CFLAGS}"
|
||||
CXXFLAGS="${MEX_CXXFLAGS}"
|
||||
LDFLAGS="${MEX_LDFLAGS}"
|
||||
${MEX_LIBS} ${COVERAGE_MATLAB_LIBS}
|
||||
)
|
||||
ENDIF()
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.${MEX_EXTENSION}
|
||||
COMMAND ${MEX_COMMAND}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_BINARY_DIR}/temp/${TARGET}/${TARGET}.${MEX_EXTENSION}" "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_BINARY_DIR}/temp/${TARGET}/${TARGET}.${MEX_EXTENSION}" "${${PROJ}_INSTALL_DIR}/mex"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/temp/${TARGET}
|
||||
DEPENDS ${${PROJ}_LIBS} ${MATLAB_TARGET} ${CMAKE_CURRENT_SOURCE_DIR}/${MEXFILE}
|
||||
FUNCTION( ADD_MATLAB_MEX SOURCE )
|
||||
STRING( REGEX REPLACE "[.]cpp" "" TARGET ${SOURCE} )
|
||||
STRING( REGEX REPLACE "[.]c" "" TARGET ${TARGET} )
|
||||
MATLAB_ADD_MEX(
|
||||
NAME ${TARGET}
|
||||
SRC ${SOURCE}
|
||||
)
|
||||
ADD_CUSTOM_TARGET( ${TARGET}
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.${MEX_EXTENSION}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${MEXFILE}
|
||||
)
|
||||
IF ( MATLAB_TARGET )
|
||||
ADD_DEPENDENCIES( ${TARGET} ${MATLAB_TARGET} )
|
||||
ENDIF()
|
||||
IF ( ${PROJ}_LIBS )
|
||||
ADD_DEPENDENCIES( ${TARGET} ${${PROJ}_LIBS} )
|
||||
ENDIF()
|
||||
TARGET_LINK_LIBRARIES( ${TARGET} ${MATLAB_TARGET} )
|
||||
ADD_PROJ_EXE_DEP( ${TARGET} )
|
||||
ADD_DEPENDENCIES( mex ${TARGET} )
|
||||
SET( MEX_FILES2 ${MEX_FILES} "${${PROJ}_INSTALL_DIR}/mex/${TARGET}.${MEX_EXTENSION}" )
|
||||
INSTALL( TARGETS ${TARGET} DESTINATION ${${PROJ}_INSTALL_DIR}/mex )
|
||||
ADD_DEPENDENCIES( mex ${TARGET} )
|
||||
SET( MEX_FILES2 ${MEX_FILES} "${${PROJ}_INSTALL_DIR}/mex/${TARGET}.${Matlab_MEX_EXTENSION}" )
|
||||
LIST( REMOVE_DUPLICATES MEX_FILES2 )
|
||||
SET( MEX_FILES ${MEX_FILES2} CACHE INTERNAL "" )
|
||||
ENDFUNCTION()
|
||||
@ -1178,7 +1060,7 @@ MACRO( ADD_MATLAB_TEST EXEFILE ${ARGN} )
|
||||
IF ( USING_MSVC )
|
||||
SET( MATLAB_OPTIONS "-logfile" "log_${EXEFILE}" )
|
||||
ENDIF()
|
||||
SET( MATLAB_COMMAND "try, ${EXEFILE}, catch ME, ME, clear all global, exit(1), end, disp('ALL TESTS PASSED'); exit(0)" )
|
||||
SET( MATLAB_COMMAND "try, ${EXEFILE}, catch ME, disp(getReport(ME)), clear all global, exit(1), end, disp('ALL TESTS PASSED'); exit(0)" )
|
||||
SET( MATLAB_DEBUGGER_OPTIONS )
|
||||
IF ( MATLAB_DEBUGGER )
|
||||
SET( MATLAB_DEBUGGER_OPTIONS -D${MATLAB_DEBUGGER} )
|
||||
@ -1195,7 +1077,6 @@ FUNCTION( CREATE_MATLAB_WRAPPER )
|
||||
SET( tmp_libs ${MEX_LIBCXX} ${MEX_FILES} )
|
||||
STRING(REGEX REPLACE ";" ":" tmp_libs "${tmp_libs}")
|
||||
STRING(REGEX REPLACE ";" ":" tmp_path "${MATLABPATH}")
|
||||
FIND_PROGRAM( MATLAB_EXE2 NAME matlab PATHS "${MATLAB_DIRECTORY}/bin" NO_DEFAULT_PATH )
|
||||
IF ( USING_MSVC )
|
||||
# Create a matlab wrapper for windows
|
||||
SET( MATLAB_GUI "${CMAKE_CURRENT_BINARY_DIR}/tmp/matlab-gui.bat" )
|
||||
@ -1212,8 +1093,8 @@ FUNCTION( CREATE_MATLAB_WRAPPER )
|
||||
SET( MATLAB_GUI "${CMAKE_CURRENT_BINARY_DIR}/tmp/matlab-gui" )
|
||||
SET( MATLAB_CMD "${CMAKE_CURRENT_BINARY_DIR}/tmp/matlab-cmd" )
|
||||
SET( MATLAB_INSTALL_CMD "matlab-cmd" )
|
||||
FILE( WRITE "${MATLAB_GUI}" "LD_PRELOAD=\"${tmp_libs}\" MKL_NUM_THREADS=1 MATLABPATH=\"${tmp_path}\" \"${MATLAB_EXE2}\" -singleCompThread -nosplash \"$@\"\n")
|
||||
FILE( WRITE "${MATLAB_CMD}" "LD_PRELOAD=\"${tmp_libs}\" MKL_NUM_THREADS=1 MATLABPATH=\"${tmp_path}\" \"${MATLAB_EXE2}\" -singleCompThread -nosplash -nodisplay -nojvm \"$@\"\n")
|
||||
FILE( WRITE "${MATLAB_GUI}" "LD_PRELOAD=\"${tmp_libs}\" MKL_NUM_THREADS=1 MATLABPATH=\"${tmp_path}\" \"${Matlab_MAIN_PROGRAM}\" -singleCompThread -nosplash \"$@\"\n")
|
||||
FILE( WRITE "${MATLAB_CMD}" "LD_PRELOAD=\"${tmp_libs}\" MKL_NUM_THREADS=1 MATLABPATH=\"${tmp_path}\" \"${Matlab_MAIN_PROGRAM}\" -singleCompThread -nosplash -nodisplay -nojvm \"$@\"\n")
|
||||
ENDIF()
|
||||
FILE( COPY "${MATLAB_GUI}" DESTINATION "${${PROJ}_INSTALL_DIR}/mex"
|
||||
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
|
||||
@ -1294,6 +1175,7 @@ MACRO( ADD_DISTCLEAN ${ARGN} )
|
||||
install_manifest.txt
|
||||
test
|
||||
matlab
|
||||
Matlab
|
||||
mex
|
||||
tmp
|
||||
#tmp#
|
||||
|
597
common/Database.cpp
Normal file
597
common/Database.cpp
Normal file
@ -0,0 +1,597 @@
|
||||
#include "common/Database.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Constructors/destructor *
|
||||
********************************************************************/
|
||||
Database::Database() = default;
|
||||
Database::~Database() = default;
|
||||
Database::Database( const Database& rhs ) : KeyData( rhs )
|
||||
{
|
||||
d_data.clear();
|
||||
for ( const auto& tmp : rhs.d_data )
|
||||
putData( tmp.first, tmp.second->clone() );
|
||||
}
|
||||
Database& Database::operator=( const Database& rhs )
|
||||
{
|
||||
if ( this == &rhs )
|
||||
return *this;
|
||||
d_data.clear();
|
||||
for ( const auto& tmp : rhs.d_data )
|
||||
putData( tmp.first, tmp.second->clone() );
|
||||
return *this;
|
||||
}
|
||||
Database::Database( Database&& rhs ) { std::swap( d_data, rhs.d_data ); }
|
||||
Database& Database::operator=( Database&& rhs )
|
||||
{
|
||||
if ( this != &rhs )
|
||||
std::swap( d_data, rhs.d_data );
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Clone the database *
|
||||
********************************************************************/
|
||||
std::shared_ptr<KeyData> Database::clone() const { return cloneDatabase(); }
|
||||
std::shared_ptr<Database> Database::cloneDatabase() const
|
||||
{
|
||||
auto db = std::make_shared<Database>();
|
||||
for ( const auto& tmp : d_data )
|
||||
db->putData( tmp.first, tmp.second->clone() );
|
||||
return db;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Get the data object *
|
||||
********************************************************************/
|
||||
bool Database::keyExists( const std::string& key ) const
|
||||
{
|
||||
return d_data.find( key ) != d_data.end();
|
||||
}
|
||||
std::shared_ptr<KeyData> Database::getData( const std::string& key )
|
||||
{
|
||||
auto it = d_data.find( key );
|
||||
if ( it == d_data.end() ) {
|
||||
char msg[1000];
|
||||
sprintf( msg, "Variable %s was not found in database", key.c_str() );
|
||||
ERROR( msg );
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
std::shared_ptr<const KeyData> Database::getData( const std::string& key ) const
|
||||
{
|
||||
return const_cast<Database*>( this )->getData( key );
|
||||
}
|
||||
bool Database::isDatabase( const std::string& key ) const
|
||||
{
|
||||
auto ptr = getData( key );
|
||||
auto ptr2 = std::dynamic_pointer_cast<const Database>( ptr );
|
||||
return ptr2 != nullptr;
|
||||
}
|
||||
std::shared_ptr<Database> Database::getDatabase( const std::string& key )
|
||||
{
|
||||
std::shared_ptr<KeyData> ptr = getData( key );
|
||||
std::shared_ptr<Database> ptr2 = std::dynamic_pointer_cast<Database>( ptr );
|
||||
if ( ptr2 == nullptr ) {
|
||||
char msg[1000];
|
||||
sprintf( msg, "Variable %s is not a database", key.c_str() );
|
||||
ERROR( msg );
|
||||
}
|
||||
return ptr2;
|
||||
}
|
||||
std::shared_ptr<const Database> Database::getDatabase( const std::string& key ) const
|
||||
{
|
||||
return const_cast<Database*>( this )->getDatabase( key );
|
||||
}
|
||||
std::vector<std::string> Database::getAllKeys() const
|
||||
{
|
||||
std::vector<std::string> keys;
|
||||
keys.reserve( d_data.size() );
|
||||
for ( const auto& it : d_data )
|
||||
keys.push_back( it.first );
|
||||
return keys;
|
||||
}
|
||||
void Database::putDatabase( const std::string& key, std::shared_ptr<Database> db )
|
||||
{
|
||||
d_data[key] = std::move( db );
|
||||
}
|
||||
void Database::putData( const std::string& key, std::shared_ptr<KeyData> data )
|
||||
{
|
||||
d_data[key] = std::move( data );
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Is the data of the given type *
|
||||
********************************************************************/
|
||||
template<>
|
||||
bool Database::isType<double>( const std::string& key ) const
|
||||
{
|
||||
auto type = getData( key )->type();
|
||||
return type == "double";
|
||||
}
|
||||
template<>
|
||||
bool Database::isType<float>( const std::string& key ) const
|
||||
{
|
||||
auto type = getData( key )->type();
|
||||
return type == "double";
|
||||
}
|
||||
template<>
|
||||
bool Database::isType<int>( const std::string& key ) const
|
||||
{
|
||||
bool pass = true;
|
||||
auto type = getData( key )->type();
|
||||
if ( type == "double" ) {
|
||||
auto data = getVector<double>( key );
|
||||
for ( auto tmp : data )
|
||||
pass = pass && static_cast<double>( static_cast<int>( tmp ) ) == tmp;
|
||||
} else {
|
||||
pass = false;
|
||||
}
|
||||
return pass;
|
||||
}
|
||||
template<>
|
||||
bool Database::isType<std::string>( const std::string& key ) const
|
||||
{
|
||||
auto type = getData( key )->type();
|
||||
return type == "string";
|
||||
}
|
||||
template<>
|
||||
bool Database::isType<bool>( const std::string& key ) const
|
||||
{
|
||||
auto type = getData( key )->type();
|
||||
return type == "bool";
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Get a vector *
|
||||
********************************************************************/
|
||||
template<>
|
||||
std::vector<std::string> Database::getVector<std::string>(
|
||||
const std::string& key, const Units& ) const
|
||||
{
|
||||
std::shared_ptr<const KeyData> ptr = getData( key );
|
||||
if ( std::dynamic_pointer_cast<const EmptyKeyData>( ptr ) )
|
||||
return std::vector<std::string>();
|
||||
const auto* ptr2 = dynamic_cast<const KeyDataString*>( ptr.get() );
|
||||
if ( ptr2 == nullptr ) {
|
||||
ERROR( "Key '" + key + "' is not a string" );
|
||||
}
|
||||
return ptr2->d_data;
|
||||
}
|
||||
template<>
|
||||
std::vector<bool> Database::getVector<bool>( const std::string& key, const Units& ) const
|
||||
{
|
||||
std::shared_ptr<const KeyData> ptr = getData( key );
|
||||
if ( std::dynamic_pointer_cast<const EmptyKeyData>( ptr ) )
|
||||
return std::vector<bool>();
|
||||
const auto* ptr2 = dynamic_cast<const KeyDataBool*>( ptr.get() );
|
||||
if ( ptr2 == nullptr ) {
|
||||
ERROR( "Key '" + key + "' is not a bool" );
|
||||
}
|
||||
return ptr2->d_data;
|
||||
}
|
||||
template<class TYPE>
|
||||
std::vector<TYPE> Database::getVector( const std::string& key, const Units& unit ) const
|
||||
{
|
||||
std::shared_ptr<const KeyData> ptr = getData( key );
|
||||
if ( std::dynamic_pointer_cast<const EmptyKeyData>( ptr ) )
|
||||
return std::vector<TYPE>();
|
||||
std::vector<TYPE> data;
|
||||
if ( std::dynamic_pointer_cast<const KeyDataDouble>( ptr ) ) {
|
||||
const auto* ptr2 = dynamic_cast<const KeyDataDouble*>( ptr.get() );
|
||||
const std::vector<double>& data2 = ptr2->d_data;
|
||||
double factor = 1;
|
||||
if ( !unit.isNull() ) {
|
||||
INSIST( !ptr2->d_unit.isNull(), "Field " + key + " must have units" );
|
||||
factor = ptr2->d_unit.convert( unit );
|
||||
INSIST( factor != 0, "Unit conversion failed" );
|
||||
}
|
||||
data.resize( data2.size() );
|
||||
for ( size_t i = 0; i < data2.size(); i++ )
|
||||
data[i] = static_cast<TYPE>( factor * data2[i] );
|
||||
} else if ( std::dynamic_pointer_cast<const KeyDataString>( ptr ) ) {
|
||||
ERROR( "Converting std::string to another type" );
|
||||
} else if ( std::dynamic_pointer_cast<const KeyDataBool>( ptr ) ) {
|
||||
ERROR( "Converting std::bool to another type" );
|
||||
} else {
|
||||
ERROR( "Unable to convert data format" );
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Put a vector *
|
||||
********************************************************************/
|
||||
template<>
|
||||
void Database::putVector<std::string>(
|
||||
const std::string& key, const std::vector<std::string>& data, const Units& )
|
||||
{
|
||||
std::shared_ptr<KeyDataString> ptr( new KeyDataString() );
|
||||
ptr->d_data = data;
|
||||
d_data[key] = ptr;
|
||||
}
|
||||
template<>
|
||||
void Database::putVector<bool>(
|
||||
const std::string& key, const std::vector<bool>& data, const Units& )
|
||||
{
|
||||
std::shared_ptr<KeyDataBool> ptr( new KeyDataBool() );
|
||||
ptr->d_data = data;
|
||||
d_data[key] = ptr;
|
||||
}
|
||||
template<class TYPE>
|
||||
void Database::putVector( const std::string& key, const std::vector<TYPE>& data, const Units& unit )
|
||||
{
|
||||
std::shared_ptr<KeyDataDouble> ptr( new KeyDataDouble() );
|
||||
ptr->d_unit = unit;
|
||||
ptr->d_data.resize( data.size() );
|
||||
for ( size_t i = 0; i < data.size(); i++ )
|
||||
ptr->d_data[i] = static_cast<double>( data[i] );
|
||||
d_data[key] = ptr;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Print the database *
|
||||
********************************************************************/
|
||||
void Database::print( std::ostream& os, const std::string& indent ) const
|
||||
{
|
||||
for ( const auto& it : d_data ) {
|
||||
os << indent << it.first;
|
||||
if ( dynamic_cast<const Database*>( it.second.get() ) ) {
|
||||
const auto* db = dynamic_cast<const Database*>( it.second.get() );
|
||||
os << " {\n";
|
||||
db->print( os, indent + " " );
|
||||
os << indent << "}\n";
|
||||
} else {
|
||||
os << " = ";
|
||||
it.second->print( os, "" );
|
||||
}
|
||||
}
|
||||
}
|
||||
std::string Database::print( const std::string& indent ) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
print( ss, indent );
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Read input database file *
|
||||
********************************************************************/
|
||||
Database::Database( const std::string& filename )
|
||||
{
|
||||
// Read the input file into memory
|
||||
FILE* fid = fopen( filename.c_str(), "rb" );
|
||||
if ( fid == nullptr )
|
||||
ERROR( "Error opening file " + filename );
|
||||
fseek( fid, 0, SEEK_END );
|
||||
size_t bytes = ftell( fid );
|
||||
rewind( fid );
|
||||
auto* buffer = new char[bytes + 4];
|
||||
size_t result = fread( buffer, 1, bytes, fid );
|
||||
fclose( fid );
|
||||
if ( result != bytes )
|
||||
ERROR( "Error reading file " + filename );
|
||||
buffer[bytes + 0] = '\n';
|
||||
buffer[bytes + 1] = '}';
|
||||
buffer[bytes + 2] = '\n';
|
||||
buffer[bytes + 3] = 0;
|
||||
// Create the database entries
|
||||
loadDatabase( buffer, *this );
|
||||
// Free temporary memory
|
||||
delete[] buffer;
|
||||
}
|
||||
std::shared_ptr<Database> Database::createFromString( const std::string& data )
|
||||
{
|
||||
std::shared_ptr<Database> db( new Database() );
|
||||
auto* buffer = new char[data.size() + 4];
|
||||
memcpy( buffer, data.data(), data.size() );
|
||||
buffer[data.size() + 0] = '\n';
|
||||
buffer[data.size() + 1] = '}';
|
||||
buffer[data.size() + 2] = '\n';
|
||||
buffer[data.size() + 3] = 0;
|
||||
loadDatabase( buffer, *db );
|
||||
delete[] buffer;
|
||||
return db;
|
||||
}
|
||||
enum class token_type {
|
||||
newline,
|
||||
line_comment,
|
||||
block_start,
|
||||
block_stop,
|
||||
quote,
|
||||
equal,
|
||||
bracket,
|
||||
end_bracket,
|
||||
end
|
||||
};
|
||||
inline size_t length( token_type type )
|
||||
{
|
||||
size_t len = 0;
|
||||
if ( type == token_type::newline || type == token_type::quote || type == token_type::equal ||
|
||||
type == token_type::bracket || type == token_type::end_bracket ||
|
||||
type == token_type::end ) {
|
||||
len = 1;
|
||||
} else if ( type == token_type::line_comment || type == token_type::block_start ||
|
||||
type == token_type::block_stop ) {
|
||||
len = 2;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
inline std::tuple<size_t, token_type> find_next_token( const char* buffer )
|
||||
{
|
||||
size_t i = 0;
|
||||
while ( true ) {
|
||||
if ( buffer[i] == '\n' || buffer[i] == '\r' ) {
|
||||
return std::pair<size_t, token_type>( i + 1, token_type::newline );
|
||||
} else if ( buffer[i] == 0 ) {
|
||||
return std::pair<size_t, token_type>( i + 1, token_type::end );
|
||||
} else if ( buffer[i] == '"' ) {
|
||||
return std::pair<size_t, token_type>( i + 1, token_type::quote );
|
||||
} else if ( buffer[i] == '=' ) {
|
||||
return std::pair<size_t, token_type>( i + 1, token_type::equal );
|
||||
} else if ( buffer[i] == '{' ) {
|
||||
return std::pair<size_t, token_type>( i + 1, token_type::bracket );
|
||||
} else if ( buffer[i] == '}' ) {
|
||||
return std::pair<size_t, token_type>( i + 1, token_type::end_bracket );
|
||||
} else if ( buffer[i] == '/' ) {
|
||||
if ( buffer[i + 1] == '/' ) {
|
||||
return std::pair<size_t, token_type>( i + 2, token_type::line_comment );
|
||||
} else if ( buffer[i + 1] == '*' ) {
|
||||
return std::pair<size_t, token_type>( i + 2, token_type::block_start );
|
||||
}
|
||||
} else if ( buffer[i] == '*' ) {
|
||||
if ( buffer[i + 1] == '/' )
|
||||
return std::pair<size_t, token_type>( i + 2, token_type::block_stop );
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return std::pair<size_t, token_type>( 0, token_type::end );
|
||||
}
|
||||
inline std::string deblank( const std::string& str )
|
||||
{
|
||||
size_t i1 = 0xFFFFFFF, i2 = 0;
|
||||
for ( size_t i = 0; i < str.size(); i++ ) {
|
||||
if ( str[i] != ' ' ) {
|
||||
i1 = std::min( i1, i );
|
||||
i2 = std::max( i2, i );
|
||||
}
|
||||
}
|
||||
return i1 <= i2 ? str.substr( i1, i2 - i1 + 1 ) : std::string();
|
||||
}
|
||||
size_t skip_comment( const char* buffer )
|
||||
{
|
||||
auto tmp = find_next_token( buffer );
|
||||
const token_type end_comment = ( std::get<1>( tmp ) == token_type::line_comment ) ?
|
||||
token_type::newline :
|
||||
token_type::block_stop;
|
||||
size_t pos = 0;
|
||||
while ( std::get<1>( tmp ) != end_comment ) {
|
||||
if ( std::get<1>( tmp ) == token_type::end )
|
||||
ERROR( "Encountered end of file before block comment end" );
|
||||
pos += std::get<0>( tmp );
|
||||
tmp = find_next_token( &buffer[pos] );
|
||||
}
|
||||
pos += std::get<0>( tmp );
|
||||
return pos;
|
||||
}
|
||||
inline std::string lower( const std::string& str )
|
||||
{
|
||||
std::string tmp( str );
|
||||
std::transform( tmp.begin(), tmp.end(), tmp.begin(), ::tolower );
|
||||
return tmp;
|
||||
}
|
||||
static std::tuple<size_t, std::shared_ptr<KeyData>> read_value(
|
||||
const char* buffer, const std::string& key )
|
||||
{
|
||||
// Get the value as a std::string
|
||||
size_t pos = 0;
|
||||
token_type type = token_type::end;
|
||||
std::tie( pos, type ) = find_next_token( &buffer[pos] );
|
||||
size_t len = pos - length( type );
|
||||
while ( type != token_type::newline ) {
|
||||
if ( type == token_type::quote ) {
|
||||
size_t i = 0;
|
||||
std::tie( i, type ) = find_next_token( &buffer[pos] );
|
||||
pos += i;
|
||||
while ( type != token_type::quote ) {
|
||||
ASSERT( type != token_type::end );
|
||||
std::tie( i, type ) = find_next_token( &buffer[pos] );
|
||||
pos += i;
|
||||
}
|
||||
} else if ( type == token_type::line_comment || type == token_type::block_start ) {
|
||||
len = pos - length( type );
|
||||
pos += skip_comment( &buffer[pos - length( type )] ) - length( type );
|
||||
break;
|
||||
}
|
||||
size_t i = 0;
|
||||
std::tie( i, type ) = find_next_token( &buffer[pos] );
|
||||
pos += i;
|
||||
len = pos - length( type );
|
||||
}
|
||||
const std::string value = deblank( std::string( buffer, len ) );
|
||||
// Split the value to an array of values
|
||||
std::vector<std::string> values;
|
||||
size_t i0 = 0, i = 0, count = 0;
|
||||
for ( ; i < value.size(); i++ ) {
|
||||
if ( value[i] == '"' ) {
|
||||
count++;
|
||||
} else if ( value[i] == ',' && count % 2 == 0 ) {
|
||||
values.push_back( deblank( value.substr( i0, i - i0 ) ) );
|
||||
i0 = i + 1;
|
||||
}
|
||||
}
|
||||
values.push_back( deblank( value.substr( i0 ) ) );
|
||||
// Convert the string value to the database value
|
||||
std::shared_ptr<KeyData> data;
|
||||
if ( value.empty() ) {
|
||||
data.reset( new EmptyKeyData() );
|
||||
} else if ( value.find( '"' ) != std::string::npos ) {
|
||||
auto* data2 = new KeyDataString();
|
||||
data.reset( data2 );
|
||||
data2->d_data.resize( values.size() );
|
||||
for ( size_t i = 0; i < values.size(); i++ ) {
|
||||
ASSERT( values[i].size() >= 2 );
|
||||
ASSERT( values[i][0] == '"' && values[i][values[i].size() - 1] == '"' );
|
||||
data2->d_data[i] = values[i].substr( 1, values[i].size() - 2 );
|
||||
}
|
||||
} else if ( lower( value ) == "true" || lower( value ) == "false" ) {
|
||||
auto* data2 = new KeyDataBool();
|
||||
data.reset( data2 );
|
||||
data2->d_data.resize( values.size() );
|
||||
for ( size_t i = 0; i < values.size(); i++ ) {
|
||||
ASSERT( values[i].size() >= 2 );
|
||||
if ( lower( values[i] ) != "true" && lower( values[i] ) != "false" )
|
||||
ERROR( "Error converting " + key + " to logical array" );
|
||||
data2->d_data[i] = lower( values[i] ) == "true";
|
||||
}
|
||||
} else { // if ( value.find('.')!=std::string::npos || value.find('e')!=std::string::npos ) {
|
||||
auto* data2 = new KeyDataDouble();
|
||||
data.reset( data2 );
|
||||
data2->d_data.resize( values.size(), 0 );
|
||||
for ( size_t i = 0; i < values.size(); i++ ) {
|
||||
Units unit;
|
||||
std::tie( data2->d_data[i], unit ) = KeyDataDouble::read( values[i] );
|
||||
if ( !unit.isNull() )
|
||||
data2->d_unit = unit;
|
||||
}
|
||||
//} else {
|
||||
// ERROR("Unable to determine data type: "+value);
|
||||
}
|
||||
return std::tuple<size_t, std::shared_ptr<KeyData>>( pos, data );
|
||||
}
|
||||
size_t Database::loadDatabase( const char* buffer, Database& db )
|
||||
{
|
||||
size_t pos = 0;
|
||||
while ( true ) {
|
||||
size_t i;
|
||||
token_type type;
|
||||
std::tie( i, type ) = find_next_token( &buffer[pos] );
|
||||
const std::string key =
|
||||
deblank( std::string( &buffer[pos], std::max<int>( i - length( type ), 1 ) - 1 ) );
|
||||
if ( type == token_type::line_comment || type == token_type::block_start ) {
|
||||
// Comment
|
||||
INSIST( key.empty(), "Key should be empty: " + key );
|
||||
pos += skip_comment( &buffer[pos] );
|
||||
} else if ( type == token_type::newline ) {
|
||||
INSIST( key.empty(), "Key should be empty: " + key );
|
||||
pos += i;
|
||||
} else if ( type == token_type::equal ) {
|
||||
// Reading key/value pair
|
||||
ASSERT( !key.empty() );
|
||||
pos += i;
|
||||
std::shared_ptr<KeyData> data;
|
||||
std::tie( i, data ) = read_value( &buffer[pos], key );
|
||||
ASSERT( data.get() != nullptr );
|
||||
db.d_data[key] = data;
|
||||
pos += i;
|
||||
} else if ( type == token_type::bracket ) {
|
||||
// Read database
|
||||
ASSERT( !key.empty() );
|
||||
pos += i;
|
||||
std::shared_ptr<Database> database( new Database() );
|
||||
pos += loadDatabase( &buffer[pos], *database );
|
||||
db.d_data[key] = database;
|
||||
} else if ( type == token_type::end_bracket ) {
|
||||
// Finished with the database
|
||||
pos += i;
|
||||
break;
|
||||
} else {
|
||||
ERROR( "Error loading data" );
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Data type helper functions *
|
||||
********************************************************************/
|
||||
void KeyDataDouble::print( std::ostream& os, const std::string& indent ) const
|
||||
{
|
||||
os << indent;
|
||||
for ( size_t i = 0; i < d_data.size(); i++ ) {
|
||||
if ( i > 0 )
|
||||
os << ", ";
|
||||
if ( d_data[i] != d_data[i] ) {
|
||||
os << "nan";
|
||||
} else if ( d_data[i] == std::numeric_limits<double>::infinity() ) {
|
||||
os << "inf";
|
||||
} else if ( d_data[i] == -std::numeric_limits<double>::infinity() ) {
|
||||
os << "-inf";
|
||||
} else {
|
||||
os << std::setprecision( 12 ) << d_data[i];
|
||||
}
|
||||
}
|
||||
if ( !d_unit.isNull() )
|
||||
os << " " << d_unit.str();
|
||||
os << std::endl;
|
||||
}
|
||||
std::tuple<double, Units> KeyDataDouble::read( const std::string& str )
|
||||
{
|
||||
std::string tmp = deblank( str );
|
||||
size_t index = tmp.find( " " );
|
||||
if ( index != std::string::npos ) {
|
||||
return std::make_tuple(
|
||||
readValue( tmp.substr( 0, index ) ), Units( tmp.substr( index + 1 ) ) );
|
||||
} else {
|
||||
return std::make_tuple( readValue( tmp ), Units() );
|
||||
}
|
||||
}
|
||||
double KeyDataDouble::readValue( const std::string& str )
|
||||
{
|
||||
const std::string tmp = lower( str );
|
||||
double data = 0;
|
||||
if ( tmp == "inf" || tmp == "infinity" ) {
|
||||
data = std::numeric_limits<double>::infinity();
|
||||
} else if ( tmp == "-inf" || tmp == "-infinity" ) {
|
||||
data = -std::numeric_limits<double>::infinity();
|
||||
} else if ( tmp == "nan" ) {
|
||||
data = std::numeric_limits<double>::quiet_NaN();
|
||||
} else if ( tmp.find( '/' ) != std::string::npos ) {
|
||||
ERROR( "Error reading value" );
|
||||
} else {
|
||||
char* pos = nullptr;
|
||||
data = strtod( tmp.c_str(), &pos );
|
||||
if ( static_cast<size_t>( pos - tmp.c_str() ) == tmp.size() + 1 )
|
||||
ERROR( "Error reading value" );
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Instantiations *
|
||||
********************************************************************/
|
||||
template std::vector<char> Database::getVector<char>( const std::string&, const Units& ) const;
|
||||
template std::vector<int> Database::getVector<int>( const std::string&, const Units& ) const;
|
||||
template std::vector<size_t> Database::getVector<size_t>( const std::string&, const Units& ) const;
|
||||
template std::vector<float> Database::getVector<float>( const std::string&, const Units& ) const;
|
||||
template std::vector<double> Database::getVector<double>( const std::string&, const Units& ) const;
|
||||
template void Database::putVector<char>(
|
||||
const std::string&, const std::vector<char>&, const Units& );
|
||||
template void Database::putVector<int>( const std::string&, const std::vector<int>&, const Units& );
|
||||
template void Database::putVector<size_t>(
|
||||
const std::string&, const std::vector<size_t>&, const Units& );
|
||||
template void Database::putVector<float>(
|
||||
const std::string&, const std::vector<float>&, const Units& );
|
||||
template void Database::putVector<double>(
|
||||
const std::string&, const std::vector<double>&, const Units& );
|
||||
template bool Database::isType<int>( const std::string& ) const;
|
||||
template bool Database::isType<float>( const std::string& ) const;
|
||||
template bool Database::isType<double>( const std::string& ) const;
|
||||
template bool Database::isType<std::string>( const std::string& ) const;
|
288
common/Database.h
Normal file
288
common/Database.h
Normal file
@ -0,0 +1,288 @@
|
||||
#ifndef included_Database
|
||||
#define included_Database
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "common/Units.h"
|
||||
|
||||
|
||||
//! Base class to hold data of a given type
|
||||
class KeyData
|
||||
{
|
||||
protected:
|
||||
//! Empty constructor
|
||||
KeyData() {}
|
||||
|
||||
public:
|
||||
//! Destructor
|
||||
virtual ~KeyData() {}
|
||||
//! Copy the data
|
||||
virtual std::shared_ptr<KeyData> clone() const = 0;
|
||||
//! Print the data to a stream
|
||||
virtual void print( std::ostream& os, const std::string& indent = "" ) const = 0;
|
||||
//! Return the native data type
|
||||
virtual std::string type() const = 0;
|
||||
|
||||
protected:
|
||||
KeyData( const KeyData& ) {}
|
||||
KeyData& operator=( const KeyData& );
|
||||
};
|
||||
|
||||
|
||||
//! Class to a database
|
||||
class Database : public KeyData
|
||||
{
|
||||
public:
|
||||
//! Empty constructor
|
||||
Database();
|
||||
|
||||
/**
|
||||
* Open an database file.
|
||||
* @param filename Name of input file to open
|
||||
*/
|
||||
explicit Database( const std::string& filename );
|
||||
|
||||
/**
|
||||
* Create database from string
|
||||
* @param data String containing the database data
|
||||
*/
|
||||
static std::shared_ptr<Database> createFromString( const std::string& data );
|
||||
|
||||
//! Copy constructor
|
||||
Database( const Database& );
|
||||
|
||||
//! Assignment operator
|
||||
Database& operator=( const Database& );
|
||||
|
||||
//! Move constructor
|
||||
Database( Database&& rhs );
|
||||
|
||||
//! Move assignment operator
|
||||
Database& operator=( Database&& rhs );
|
||||
|
||||
//! Destructor
|
||||
virtual ~Database();
|
||||
|
||||
//! Copy the data
|
||||
virtual std::shared_ptr<KeyData> clone() const override;
|
||||
|
||||
//! Copy the data
|
||||
std::shared_ptr<Database> cloneDatabase() const;
|
||||
|
||||
|
||||
/**
|
||||
* Return true if the specified key exists in the database and false
|
||||
* otherwise.
|
||||
* @param[in] key Key name to lookup.
|
||||
*/
|
||||
bool keyExists( const std::string& key ) const;
|
||||
|
||||
|
||||
/**
|
||||
* Return all keys in the database.
|
||||
*/
|
||||
std::vector<std::string> getAllKeys() const;
|
||||
|
||||
|
||||
//! Return the number of entries in the database
|
||||
size_t size() const { return d_data.size(); }
|
||||
|
||||
|
||||
/**
|
||||
* Get the scalar entry from the database with the specified key
|
||||
* name. If the specified key does not exist in the database or
|
||||
* is not a scalar of the given type, then an error message is printed and
|
||||
* the program exits.
|
||||
*
|
||||
* @param[in] key Key name in database.
|
||||
* @param[in] unit Desired units
|
||||
*/
|
||||
template<class TYPE>
|
||||
inline TYPE getScalar( const std::string& key, const Units& unit = Units() ) const;
|
||||
|
||||
|
||||
/// @copydoc Database::getScalar(const std::string&,const Units&) const
|
||||
template<class TYPE>
|
||||
inline TYPE getScalar( const std::string& key, const std::string& unit ) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get the scalar entry from the database with the specified key
|
||||
* name. If the specified key does not exist in the database the
|
||||
* the default value will be printed
|
||||
*
|
||||
* @param[in] key Key name in database
|
||||
* @param[in] value Default value
|
||||
* @param[in] unit Desired units
|
||||
*/
|
||||
template<class TYPE>
|
||||
inline TYPE getWithDefault(
|
||||
const std::string& key, const TYPE& value, const Units& unit = Units() ) const;
|
||||
|
||||
|
||||
/// @copydoc Database::getWithDefault(const std::string&,const TYPE&,const Units&) const
|
||||
template<class TYPE>
|
||||
inline TYPE getWithDefault(
|
||||
const std::string& key, const TYPE& value, const std::string& unit ) const;
|
||||
|
||||
|
||||
/**
|
||||
* Put the scalar entry into the database with the specified key name.
|
||||
* @param key Key name in database.
|
||||
* @param value Value to store
|
||||
* @param unit Desired units
|
||||
*/
|
||||
template<class TYPE>
|
||||
inline void putScalar( const std::string& key, const TYPE& value, const Units& unit = Units() );
|
||||
|
||||
|
||||
/**
|
||||
* Put the scalar entry into the database with the specified key name.
|
||||
* @param key Key name in database.
|
||||
* @param value Value to store
|
||||
* @param unit Desired units
|
||||
*/
|
||||
template<class TYPE>
|
||||
inline void putScalar( const std::string& key, const TYPE& value, const std::string& unit );
|
||||
|
||||
|
||||
/**
|
||||
* Get the vector entries from the database with the specified key
|
||||
* name. If the specified key does not exist in the database or
|
||||
* is not of the given type, then an error message is printed and
|
||||
* the program exits.
|
||||
*
|
||||
* @param key Key name in database.
|
||||
* @param unit Desired units
|
||||
*/
|
||||
template<class TYPE>
|
||||
std::vector<TYPE> getVector( const std::string& key, const Units& unit = Units() ) const;
|
||||
|
||||
|
||||
/// @copydoc Database::getVector(const std::string&,const Units&) const
|
||||
template<class TYPE>
|
||||
inline std::vector<TYPE> getVector( const std::string& key, const std::string& unit ) const;
|
||||
|
||||
|
||||
/**
|
||||
* Put the vector entries into the database with the specified key
|
||||
* name. If the specified key does not exist in the database or
|
||||
* is not of the given type, then an error message is printed and
|
||||
* the program exits.
|
||||
*
|
||||
* @param key Key name in database.
|
||||
* @param data Data to store
|
||||
* @param unit Desired units
|
||||
*/
|
||||
template<class TYPE>
|
||||
void putVector(
|
||||
const std::string& key, const std::vector<TYPE>& data, const Units& unit = Units() );
|
||||
|
||||
|
||||
/// @copydoc Database::putVector(const std::string&,const std::vector<TYPE>&,const Units&)
|
||||
template<class TYPE>
|
||||
inline void putVector(
|
||||
const std::string& key, const std::vector<TYPE>& data, const std::string& unit );
|
||||
|
||||
|
||||
/**
|
||||
* Get the data for a key in the database. If the specified key
|
||||
* does not exist in the database an error message is printed and
|
||||
* the program exits.
|
||||
*
|
||||
* @param key Key name in database.
|
||||
*/
|
||||
std::shared_ptr<KeyData> getData( const std::string& key );
|
||||
|
||||
/**
|
||||
* Get the data for a key in the database. If the specified key
|
||||
* does not exist in the database an error message is printed and
|
||||
* the program exits.
|
||||
*
|
||||
* @param key Key name in database.
|
||||
*/
|
||||
std::shared_ptr<const KeyData> getData( const std::string& key ) const;
|
||||
|
||||
|
||||
/**
|
||||
* Put the data for a key in the database.
|
||||
*
|
||||
* @param key Key name in database.
|
||||
* @param data Data to store
|
||||
*/
|
||||
void putData( const std::string& key, std::shared_ptr<KeyData> data );
|
||||
|
||||
|
||||
// Check if the key is a database object
|
||||
bool isDatabase( const std::string& key ) const;
|
||||
|
||||
|
||||
// Check if the entry can be stored as the given type
|
||||
template<class TYPE>
|
||||
bool isType( const std::string& key ) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get the database for a key in the database. If the specified key
|
||||
* does not exist in the database an error message is printed and
|
||||
* the program exits.
|
||||
*
|
||||
* @param key Key name in database.
|
||||
*/
|
||||
std::shared_ptr<Database> getDatabase( const std::string& key );
|
||||
|
||||
/**
|
||||
* Get the database for a key in the database. If the specified key
|
||||
* does not exist in the database an error message is printed and
|
||||
* the program exits.
|
||||
*
|
||||
* @param key Key name in database.
|
||||
*/
|
||||
std::shared_ptr<const Database> getDatabase( const std::string& key ) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get the database for a key in the database. If the specified key
|
||||
* does not exist in the database an error message is printed and
|
||||
* the program exits.
|
||||
*
|
||||
* @param key Key name in database.
|
||||
* @param db Database to store
|
||||
*/
|
||||
void putDatabase( const std::string& key, std::shared_ptr<Database> db );
|
||||
|
||||
|
||||
/**
|
||||
* Print the data to a stream
|
||||
* @param os Output stream
|
||||
* @param indent Indenting to use before each line
|
||||
*/
|
||||
virtual void print( std::ostream& os, const std::string& indent = "" ) const override;
|
||||
|
||||
|
||||
//! Print the type
|
||||
virtual std::string type() const override { return "database"; }
|
||||
|
||||
|
||||
/**
|
||||
* Print the data to a string
|
||||
* @return Output string
|
||||
*/
|
||||
std::string print( const std::string& indent = "" ) const;
|
||||
|
||||
|
||||
protected:
|
||||
std::map<std::string, std::shared_ptr<KeyData>> d_data;
|
||||
|
||||
// Function to load a database from a buffer
|
||||
static size_t loadDatabase( const char* buffer, Database& db );
|
||||
};
|
||||
|
||||
|
||||
#include "common/Database.hpp"
|
||||
|
||||
#endif
|
173
common/Database.hpp
Normal file
173
common/Database.hpp
Normal file
@ -0,0 +1,173 @@
|
||||
#ifndef included_Database_hpp
|
||||
#define included_Database_hpp
|
||||
|
||||
#include "common/Database.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
#include <tuple>
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Basic classes for primative data types *
|
||||
********************************************************************/
|
||||
class EmptyKeyData : public KeyData
|
||||
{
|
||||
public:
|
||||
EmptyKeyData() {}
|
||||
virtual ~EmptyKeyData() {}
|
||||
virtual std::shared_ptr<KeyData> clone() const override
|
||||
{
|
||||
return std::make_shared<EmptyKeyData>();
|
||||
}
|
||||
virtual void print( std::ostream& os, const std::string& = "" ) const override
|
||||
{
|
||||
os << std::endl;
|
||||
}
|
||||
virtual std::string type() const override { return ""; }
|
||||
};
|
||||
class KeyDataDouble : public KeyData
|
||||
{
|
||||
public:
|
||||
KeyDataDouble() {}
|
||||
explicit KeyDataDouble( const std::vector<double>& data, const Units& unit )
|
||||
: d_data( data ), d_unit( unit )
|
||||
{
|
||||
}
|
||||
virtual ~KeyDataDouble() {}
|
||||
virtual std::shared_ptr<KeyData> clone() const override
|
||||
{
|
||||
return std::make_shared<KeyDataDouble>( d_data, d_unit );
|
||||
}
|
||||
virtual void print( std::ostream& os, const std::string& indent = "" ) const override;
|
||||
virtual std::string type() const override { return "double"; }
|
||||
|
||||
static std::tuple<double, Units> read( const std::string& );
|
||||
static double readValue( const std::string& );
|
||||
|
||||
public:
|
||||
std::vector<double> d_data;
|
||||
Units d_unit;
|
||||
};
|
||||
class KeyDataBool : public KeyData
|
||||
{
|
||||
public:
|
||||
KeyDataBool() {}
|
||||
explicit KeyDataBool( const std::vector<bool>& data ) : d_data( data ) {}
|
||||
virtual ~KeyDataBool() {}
|
||||
virtual std::shared_ptr<KeyData> clone() const override
|
||||
{
|
||||
return std::make_shared<KeyDataBool>( d_data );
|
||||
}
|
||||
virtual void print( std::ostream& os, const std::string& indent = "" ) const override
|
||||
{
|
||||
os << indent;
|
||||
for ( size_t i = 0; i < d_data.size(); i++ ) {
|
||||
if ( i > 0 ) {
|
||||
os << ", ";
|
||||
}
|
||||
if ( d_data[i] ) {
|
||||
os << "true";
|
||||
} else {
|
||||
os << "false";
|
||||
}
|
||||
}
|
||||
os << std::endl;
|
||||
}
|
||||
virtual std::string type() const override { return "bool"; }
|
||||
std::vector<bool> d_data;
|
||||
};
|
||||
class KeyDataString : public KeyData
|
||||
{
|
||||
public:
|
||||
KeyDataString() {}
|
||||
explicit KeyDataString( const std::vector<std::string>& data ) : d_data( data ) {}
|
||||
virtual ~KeyDataString() {}
|
||||
virtual std::shared_ptr<KeyData> clone() const override
|
||||
{
|
||||
return std::make_shared<KeyDataString>( d_data );
|
||||
}
|
||||
virtual void print( std::ostream& os, const std::string& indent = "" ) const override
|
||||
{
|
||||
os << indent;
|
||||
for ( size_t i = 0; i < d_data.size(); i++ ) {
|
||||
if ( i > 0 ) {
|
||||
os << ", ";
|
||||
}
|
||||
os << '"' << d_data[i] << '"';
|
||||
}
|
||||
os << std::endl;
|
||||
}
|
||||
virtual std::string type() const override { return "string"; }
|
||||
std::vector<std::string> d_data;
|
||||
};
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Get a vector *
|
||||
********************************************************************/
|
||||
template<class TYPE>
|
||||
inline std::vector<TYPE> Database::getVector(
|
||||
const std::string& key, const std::string& unit ) const
|
||||
{
|
||||
return getVector<TYPE>( key, Units( unit ) );
|
||||
}
|
||||
template<class TYPE>
|
||||
inline void Database::putVector(
|
||||
const std::string& key, const std::vector<TYPE>& data, const std::string& unit )
|
||||
{
|
||||
putVector<TYPE>( key, data, Units( unit ) );
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Get a scalar *
|
||||
********************************************************************/
|
||||
template<class TYPE>
|
||||
inline TYPE Database::getScalar( const std::string& key, const Units& unit ) const
|
||||
{
|
||||
const std::vector<TYPE>& data = getVector<TYPE>( key, unit );
|
||||
if ( data.size() != 1 ) {
|
||||
char msg[1000];
|
||||
sprintf( msg, "Variable %s is not a scalar", key.c_str() );
|
||||
ERROR( msg );
|
||||
}
|
||||
return data[0];
|
||||
}
|
||||
template<class TYPE>
|
||||
inline TYPE Database::getWithDefault(
|
||||
const std::string& key, const TYPE& value, const Units& unit ) const
|
||||
{
|
||||
if ( !keyExists( key ) )
|
||||
return value;
|
||||
return getScalar<TYPE>( key, unit );
|
||||
}
|
||||
template<class TYPE>
|
||||
inline void Database::putScalar( const std::string& key, const TYPE& data, const Units& unit )
|
||||
{
|
||||
putVector<TYPE>( key, std::vector<TYPE>( 1, data ), unit );
|
||||
}
|
||||
template<class TYPE>
|
||||
inline TYPE Database::getScalar( const std::string& key, const std::string& unit ) const
|
||||
{
|
||||
return getScalar<TYPE>( key, Units( unit ) );
|
||||
}
|
||||
template<class TYPE>
|
||||
inline TYPE Database::getWithDefault(
|
||||
const std::string& key, const TYPE& value, const std::string& unit ) const
|
||||
{
|
||||
return getWithDefault<TYPE>( key, value, Units( unit ) );
|
||||
}
|
||||
template<class TYPE>
|
||||
inline void Database::putScalar( const std::string& key, const TYPE& data, const std::string& unit )
|
||||
{
|
||||
putScalar<TYPE>( key, data, Units( unit ) );
|
||||
}
|
||||
template<class TYPE>
|
||||
inline void putVector(
|
||||
const std::string& key, const std::vector<TYPE>& data, const std::string& unit )
|
||||
{
|
||||
putVector<TYPE>( key, data, Units( unit ) );
|
||||
}
|
||||
|
||||
|
||||
#endif
|
@ -15,92 +15,131 @@
|
||||
#include "common/MPI_Helpers.h"
|
||||
#include "common/Communication.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Reading the domain information file
|
||||
void read_domain( int rank, int nprocs, MPI_Comm comm,
|
||||
int& nprocx, int& nprocy, int& nprocz, int& nx, int& ny, int& nz,
|
||||
int& nspheres, double& Lx, double& Ly, double& Lz )
|
||||
|
||||
|
||||
// Inline function to read line without a return argument
|
||||
static inline void fgetl( char * str, int num, FILE * stream )
|
||||
{
|
||||
if (rank==0){
|
||||
ifstream domain("Domain.in");
|
||||
domain >> nprocx;
|
||||
domain >> nprocy;
|
||||
domain >> nprocz;
|
||||
domain >> nx;
|
||||
domain >> ny;
|
||||
domain >> nz;
|
||||
domain >> nspheres;
|
||||
domain >> Lx;
|
||||
domain >> Ly;
|
||||
domain >> Lz;
|
||||
|
||||
}
|
||||
MPI_Barrier(comm);
|
||||
// Computational domain
|
||||
//.................................................
|
||||
MPI_Bcast(&nx,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&ny,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nz,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocx,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocy,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocz,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nspheres,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Lx,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Bcast(&Ly,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Bcast(&Lz,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Barrier(comm);
|
||||
char* ptr = fgets( str, num, stream );
|
||||
if ( 0 ) {char *temp = (char *)&ptr; temp++;}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Constructor/Destructor *
|
||||
* Constructors/Destructor *
|
||||
********************************************************/
|
||||
Domain::Domain(int nx, int ny, int nz, int rnk, int npx, int npy, int npz,
|
||||
double lx, double ly, double lz, int BC):
|
||||
Nx(0), Ny(0), Nz(0), iproc(0), jproc(0), nprocx(0), nprocy(0), nprocz(0),
|
||||
Lx(0), Ly(0), Lz(0), Volume(0), rank(0), BoundaryCondition(0),
|
||||
Group(MPI_GROUP_NULL), Comm(MPI_COMM_NULL),
|
||||
rank_x(0), rank_y(0), rank_z(0), rank_X(0), rank_Y(0), rank_Z(0),
|
||||
rank_xy(0), rank_XY(0), rank_xY(0), rank_Xy(0),
|
||||
rank_xz(0), rank_XZ(0), rank_xZ(0), rank_Xz(0),
|
||||
rank_yz(0), rank_YZ(0), rank_yZ(0), rank_Yz(0),
|
||||
sendCount_x(0), sendCount_y(0), sendCount_z(0), sendCount_X(0), sendCount_Y(0), sendCount_Z(0),
|
||||
sendCount_xy(0), sendCount_yz(0), sendCount_xz(0), sendCount_Xy(0), sendCount_Yz(0), sendCount_xZ(0),
|
||||
sendCount_xY(0), sendCount_yZ(0), sendCount_Xz(0), sendCount_XY(0), sendCount_YZ(0), sendCount_XZ(0),
|
||||
sendList_x(NULL), sendList_y(NULL), sendList_z(NULL), sendList_X(NULL), sendList_Y(NULL), sendList_Z(NULL),
|
||||
sendList_xy(NULL), sendList_yz(NULL), sendList_xz(NULL), sendList_Xy(NULL), sendList_Yz(NULL), sendList_xZ(NULL),
|
||||
sendList_xY(NULL), sendList_yZ(NULL), sendList_Xz(NULL), sendList_XY(NULL), sendList_YZ(NULL), sendList_XZ(NULL),
|
||||
sendBuf_x(NULL), sendBuf_y(NULL), sendBuf_z(NULL), sendBuf_X(NULL), sendBuf_Y(NULL), sendBuf_Z(NULL),
|
||||
sendBuf_xy(NULL), sendBuf_yz(NULL), sendBuf_xz(NULL), sendBuf_Xy(NULL), sendBuf_Yz(NULL), sendBuf_xZ(NULL),
|
||||
sendBuf_xY(NULL), sendBuf_yZ(NULL), sendBuf_Xz(NULL), sendBuf_XY(NULL), sendBuf_YZ(NULL), sendBuf_XZ(NULL),
|
||||
recvCount_x(0), recvCount_y(0), recvCount_z(0), recvCount_X(0), recvCount_Y(0), recvCount_Z(0),
|
||||
recvCount_xy(0), recvCount_yz(0), recvCount_xz(0), recvCount_Xy(0), recvCount_Yz(0), recvCount_xZ(0),
|
||||
recvCount_xY(0), recvCount_yZ(0), recvCount_Xz(0), recvCount_XY(0), recvCount_YZ(0), recvCount_XZ(0),
|
||||
recvList_x(NULL), recvList_y(NULL), recvList_z(NULL), recvList_X(NULL), recvList_Y(NULL), recvList_Z(NULL),
|
||||
recvList_xy(NULL), recvList_yz(NULL), recvList_xz(NULL), recvList_Xy(NULL), recvList_Yz(NULL), recvList_xZ(NULL),
|
||||
recvList_xY(NULL), recvList_yZ(NULL), recvList_Xz(NULL), recvList_XY(NULL), recvList_YZ(NULL), recvList_XZ(NULL),
|
||||
recvBuf_x(NULL), recvBuf_y(NULL), recvBuf_z(NULL), recvBuf_X(NULL), recvBuf_Y(NULL), recvBuf_Z(NULL),
|
||||
recvBuf_xy(NULL), recvBuf_yz(NULL), recvBuf_xz(NULL), recvBuf_Xy(NULL), recvBuf_Yz(NULL), recvBuf_xZ(NULL),
|
||||
recvBuf_xY(NULL), recvBuf_yZ(NULL), recvBuf_Xz(NULL), recvBuf_XY(NULL), recvBuf_YZ(NULL), recvBuf_XZ(NULL),
|
||||
sendData_x(NULL), sendData_y(NULL), sendData_z(NULL), sendData_X(NULL), sendData_Y(NULL), sendData_Z(NULL),
|
||||
sendData_xy(NULL), sendData_yz(NULL), sendData_xz(NULL), sendData_Xy(NULL), sendData_Yz(NULL), sendData_xZ(NULL),
|
||||
sendData_xY(NULL), sendData_yZ(NULL), sendData_Xz(NULL), sendData_XY(NULL), sendData_YZ(NULL), sendData_XZ(NULL),
|
||||
recvData_x(NULL), recvData_y(NULL), recvData_z(NULL), recvData_X(NULL), recvData_Y(NULL), recvData_Z(NULL),
|
||||
recvData_xy(NULL), recvData_yz(NULL), recvData_xz(NULL), recvData_Xy(NULL), recvData_Yz(NULL), recvData_xZ(NULL),
|
||||
recvData_xY(NULL), recvData_yZ(NULL), recvData_Xz(NULL), recvData_XY(NULL), recvData_YZ(NULL), recvData_XZ(NULL),
|
||||
id(NULL)
|
||||
Domain::Domain( int nx, int ny, int nz, int rnk, int npx, int npy, int npz,
|
||||
double lx, double ly, double lz, int BC):
|
||||
Nx(0), Ny(0), Nz(0), iproc(0), jproc(0), nprocx(0), nprocy(0), nprocz(0),
|
||||
Lx(0), Ly(0), Lz(0), Volume(0), rank(0), BoundaryCondition(0),
|
||||
Group(MPI_GROUP_NULL), Comm(MPI_COMM_NULL),
|
||||
rank_x(0), rank_y(0), rank_z(0), rank_X(0), rank_Y(0), rank_Z(0),
|
||||
rank_xy(0), rank_XY(0), rank_xY(0), rank_Xy(0),
|
||||
rank_xz(0), rank_XZ(0), rank_xZ(0), rank_Xz(0),
|
||||
rank_yz(0), rank_YZ(0), rank_yZ(0), rank_Yz(0),
|
||||
sendCount_x(0), sendCount_y(0), sendCount_z(0), sendCount_X(0), sendCount_Y(0), sendCount_Z(0),
|
||||
sendCount_xy(0), sendCount_yz(0), sendCount_xz(0), sendCount_Xy(0), sendCount_Yz(0), sendCount_xZ(0),
|
||||
sendCount_xY(0), sendCount_yZ(0), sendCount_Xz(0), sendCount_XY(0), sendCount_YZ(0), sendCount_XZ(0),
|
||||
sendList_x(NULL), sendList_y(NULL), sendList_z(NULL), sendList_X(NULL), sendList_Y(NULL), sendList_Z(NULL),
|
||||
sendList_xy(NULL), sendList_yz(NULL), sendList_xz(NULL), sendList_Xy(NULL), sendList_Yz(NULL), sendList_xZ(NULL),
|
||||
sendList_xY(NULL), sendList_yZ(NULL), sendList_Xz(NULL), sendList_XY(NULL), sendList_YZ(NULL), sendList_XZ(NULL),
|
||||
sendBuf_x(NULL), sendBuf_y(NULL), sendBuf_z(NULL), sendBuf_X(NULL), sendBuf_Y(NULL), sendBuf_Z(NULL),
|
||||
sendBuf_xy(NULL), sendBuf_yz(NULL), sendBuf_xz(NULL), sendBuf_Xy(NULL), sendBuf_Yz(NULL), sendBuf_xZ(NULL),
|
||||
sendBuf_xY(NULL), sendBuf_yZ(NULL), sendBuf_Xz(NULL), sendBuf_XY(NULL), sendBuf_YZ(NULL), sendBuf_XZ(NULL),
|
||||
recvCount_x(0), recvCount_y(0), recvCount_z(0), recvCount_X(0), recvCount_Y(0), recvCount_Z(0),
|
||||
recvCount_xy(0), recvCount_yz(0), recvCount_xz(0), recvCount_Xy(0), recvCount_Yz(0), recvCount_xZ(0),
|
||||
recvCount_xY(0), recvCount_yZ(0), recvCount_Xz(0), recvCount_XY(0), recvCount_YZ(0), recvCount_XZ(0),
|
||||
recvList_x(NULL), recvList_y(NULL), recvList_z(NULL), recvList_X(NULL), recvList_Y(NULL), recvList_Z(NULL),
|
||||
recvList_xy(NULL), recvList_yz(NULL), recvList_xz(NULL), recvList_Xy(NULL), recvList_Yz(NULL), recvList_xZ(NULL),
|
||||
recvList_xY(NULL), recvList_yZ(NULL), recvList_Xz(NULL), recvList_XY(NULL), recvList_YZ(NULL), recvList_XZ(NULL),
|
||||
recvBuf_x(NULL), recvBuf_y(NULL), recvBuf_z(NULL), recvBuf_X(NULL), recvBuf_Y(NULL), recvBuf_Z(NULL),
|
||||
recvBuf_xy(NULL), recvBuf_yz(NULL), recvBuf_xz(NULL), recvBuf_Xy(NULL), recvBuf_Yz(NULL), recvBuf_xZ(NULL),
|
||||
recvBuf_xY(NULL), recvBuf_yZ(NULL), recvBuf_Xz(NULL), recvBuf_XY(NULL), recvBuf_YZ(NULL), recvBuf_XZ(NULL),
|
||||
sendData_x(NULL), sendData_y(NULL), sendData_z(NULL), sendData_X(NULL), sendData_Y(NULL), sendData_Z(NULL),
|
||||
sendData_xy(NULL), sendData_yz(NULL), sendData_xz(NULL), sendData_Xy(NULL), sendData_Yz(NULL), sendData_xZ(NULL),
|
||||
sendData_xY(NULL), sendData_yZ(NULL), sendData_Xz(NULL), sendData_XY(NULL), sendData_YZ(NULL), sendData_XZ(NULL),
|
||||
recvData_x(NULL), recvData_y(NULL), recvData_z(NULL), recvData_X(NULL), recvData_Y(NULL), recvData_Z(NULL),
|
||||
recvData_xy(NULL), recvData_yz(NULL), recvData_xz(NULL), recvData_Xy(NULL), recvData_Yz(NULL), recvData_xZ(NULL),
|
||||
recvData_xY(NULL), recvData_yZ(NULL), recvData_Xz(NULL), recvData_XY(NULL), recvData_YZ(NULL), recvData_XZ(NULL),
|
||||
id(NULL)
|
||||
{
|
||||
Volume = nx*ny*nx*npx*npy*npz*1.0;
|
||||
Nx = nx+2; Ny = ny+2; Nz = nz+2;
|
||||
Lx = lx, Ly = ly, Lz = lz;
|
||||
rank = rnk;
|
||||
nprocx=npx; nprocy=npy; nprocz=npz;
|
||||
auto db = std::make_shared<Database>( );
|
||||
db->putScalar<int>( "BC", BC );
|
||||
db->putVector<int>( "nproc", { npx, npx, npx } );
|
||||
db->putVector<int>( "n", { nx, ny, nz } );
|
||||
db->putScalar<int>( "nspheres", 0 );
|
||||
db->putVector<double>( "L", { lx, ly, lz } );
|
||||
initialize( db );
|
||||
}
|
||||
Domain::Domain( std::shared_ptr<Database> db ):
|
||||
Nx(0), Ny(0), Nz(0), iproc(0), jproc(0), nprocx(0), nprocy(0), nprocz(0),
|
||||
Lx(0), Ly(0), Lz(0), Volume(0), rank(0), BoundaryCondition(0),
|
||||
Group(MPI_GROUP_NULL), Comm(MPI_COMM_NULL),
|
||||
rank_x(0), rank_y(0), rank_z(0), rank_X(0), rank_Y(0), rank_Z(0),
|
||||
rank_xy(0), rank_XY(0), rank_xY(0), rank_Xy(0),
|
||||
rank_xz(0), rank_XZ(0), rank_xZ(0), rank_Xz(0),
|
||||
rank_yz(0), rank_YZ(0), rank_yZ(0), rank_Yz(0),
|
||||
sendCount_x(0), sendCount_y(0), sendCount_z(0), sendCount_X(0), sendCount_Y(0), sendCount_Z(0),
|
||||
sendCount_xy(0), sendCount_yz(0), sendCount_xz(0), sendCount_Xy(0), sendCount_Yz(0), sendCount_xZ(0),
|
||||
sendCount_xY(0), sendCount_yZ(0), sendCount_Xz(0), sendCount_XY(0), sendCount_YZ(0), sendCount_XZ(0),
|
||||
sendList_x(NULL), sendList_y(NULL), sendList_z(NULL), sendList_X(NULL), sendList_Y(NULL), sendList_Z(NULL),
|
||||
sendList_xy(NULL), sendList_yz(NULL), sendList_xz(NULL), sendList_Xy(NULL), sendList_Yz(NULL), sendList_xZ(NULL),
|
||||
sendList_xY(NULL), sendList_yZ(NULL), sendList_Xz(NULL), sendList_XY(NULL), sendList_YZ(NULL), sendList_XZ(NULL),
|
||||
sendBuf_x(NULL), sendBuf_y(NULL), sendBuf_z(NULL), sendBuf_X(NULL), sendBuf_Y(NULL), sendBuf_Z(NULL),
|
||||
sendBuf_xy(NULL), sendBuf_yz(NULL), sendBuf_xz(NULL), sendBuf_Xy(NULL), sendBuf_Yz(NULL), sendBuf_xZ(NULL),
|
||||
sendBuf_xY(NULL), sendBuf_yZ(NULL), sendBuf_Xz(NULL), sendBuf_XY(NULL), sendBuf_YZ(NULL), sendBuf_XZ(NULL),
|
||||
recvCount_x(0), recvCount_y(0), recvCount_z(0), recvCount_X(0), recvCount_Y(0), recvCount_Z(0),
|
||||
recvCount_xy(0), recvCount_yz(0), recvCount_xz(0), recvCount_Xy(0), recvCount_Yz(0), recvCount_xZ(0),
|
||||
recvCount_xY(0), recvCount_yZ(0), recvCount_Xz(0), recvCount_XY(0), recvCount_YZ(0), recvCount_XZ(0),
|
||||
recvList_x(NULL), recvList_y(NULL), recvList_z(NULL), recvList_X(NULL), recvList_Y(NULL), recvList_Z(NULL),
|
||||
recvList_xy(NULL), recvList_yz(NULL), recvList_xz(NULL), recvList_Xy(NULL), recvList_Yz(NULL), recvList_xZ(NULL),
|
||||
recvList_xY(NULL), recvList_yZ(NULL), recvList_Xz(NULL), recvList_XY(NULL), recvList_YZ(NULL), recvList_XZ(NULL),
|
||||
recvBuf_x(NULL), recvBuf_y(NULL), recvBuf_z(NULL), recvBuf_X(NULL), recvBuf_Y(NULL), recvBuf_Z(NULL),
|
||||
recvBuf_xy(NULL), recvBuf_yz(NULL), recvBuf_xz(NULL), recvBuf_Xy(NULL), recvBuf_Yz(NULL), recvBuf_xZ(NULL),
|
||||
recvBuf_xY(NULL), recvBuf_yZ(NULL), recvBuf_Xz(NULL), recvBuf_XY(NULL), recvBuf_YZ(NULL), recvBuf_XZ(NULL),
|
||||
sendData_x(NULL), sendData_y(NULL), sendData_z(NULL), sendData_X(NULL), sendData_Y(NULL), sendData_Z(NULL),
|
||||
sendData_xy(NULL), sendData_yz(NULL), sendData_xz(NULL), sendData_Xy(NULL), sendData_Yz(NULL), sendData_xZ(NULL),
|
||||
sendData_xY(NULL), sendData_yZ(NULL), sendData_Xz(NULL), sendData_XY(NULL), sendData_YZ(NULL), sendData_XZ(NULL),
|
||||
recvData_x(NULL), recvData_y(NULL), recvData_z(NULL), recvData_X(NULL), recvData_Y(NULL), recvData_Z(NULL),
|
||||
recvData_xy(NULL), recvData_yz(NULL), recvData_xz(NULL), recvData_Xy(NULL), recvData_Yz(NULL), recvData_xZ(NULL),
|
||||
recvData_xY(NULL), recvData_yZ(NULL), recvData_Xz(NULL), recvData_XY(NULL), recvData_YZ(NULL), recvData_XZ(NULL),
|
||||
id(NULL)
|
||||
{
|
||||
initialize( db );
|
||||
}
|
||||
void Domain::initialize( std::shared_ptr<Database> db )
|
||||
{
|
||||
d_db = db;
|
||||
auto nproc = d_db->getVector<int>("nproc");
|
||||
auto n = d_db->getVector<int>("n");
|
||||
auto L = d_db->getVector<double>("L");
|
||||
ASSERT( n.size() == 3u );
|
||||
ASSERT( L.size() == 3u );
|
||||
ASSERT( nproc.size() == 3u );
|
||||
int nx = n[0];
|
||||
int ny = n[1];
|
||||
int nz = n[2];
|
||||
Lx = L[0];
|
||||
Ly = L[1];
|
||||
Lz = L[2];
|
||||
Nx = nx+2;
|
||||
Ny = ny+2;
|
||||
Nz = nz+2;
|
||||
nprocx = nproc[0];
|
||||
nprocy = nproc[1];
|
||||
nprocz = nproc[2];
|
||||
N = Nx*Ny*Nz;
|
||||
Volume = nx*ny*nx*nprocx*nprocy*nprocz*1.0;
|
||||
id = new char[N];
|
||||
memset(id,0,N);
|
||||
BoundaryCondition = BC;
|
||||
BoundaryCondition = d_db->getScalar<int>("BC");
|
||||
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
|
||||
rank_info=RankInfoStruct(rank,nprocx,nprocy,nprocz);
|
||||
int nprocs;
|
||||
MPI_Comm_size( MPI_COMM_WORLD, &nprocs );
|
||||
INSIST(nprocs == nprocx*nprocy*nprocz,"Fatal error in processor count!");
|
||||
}
|
||||
Domain::~Domain()
|
||||
{
|
||||
@ -1240,3 +1279,447 @@ void Domain::CommunicateMeshHalo(DoubleArray &Mesh)
|
||||
UnpackMeshData(recvList_YZ, recvCount_YZ ,recvData_YZ, MeshData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
double SSO(DoubleArray &Distance, char *ID, Domain &Dm, int timesteps){
|
||||
/*
|
||||
* This routine converts the data in the Distance array to a signed distance
|
||||
* by solving the equation df/dt = sign(1-|grad f|), where Distance provides
|
||||
* the values of f on the mesh associated with domain Dm
|
||||
* It has been tested with segmented data initialized to values [-1,1]
|
||||
* and will converge toward the signed distance to the surface bounding the associated phases
|
||||
*/
|
||||
|
||||
int Q=26;
|
||||
int q,i,j,k;
|
||||
double dt=0.1;
|
||||
int in,jn,kn;
|
||||
double Dqx,Dqy,Dqz,Dx,Dy,Dz,W;
|
||||
double nx,ny,nz,Cqx,Cqy,Cqz,sign,norm;
|
||||
double TotalVariation=0.0;
|
||||
|
||||
const static int D3Q27[26][3]={{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1},
|
||||
{1,1,0},{-1,-1,0},{1,-1,0},{-1,1,0},{1,0,1},{-1,0,-1},{1,0,-1},{-1,0,1},
|
||||
{0,1,1},{0,-1,-1},{0,1,-1},{0,-1,1},{1,1,1},{-1,-1,-1},{1,1,-1},{-1,-1,1},
|
||||
{-1,1,-1},{1,-1,1},{1,-1,-1},{-1,1,1}};
|
||||
|
||||
double weights[26];
|
||||
// Compute the weights from the finite differences
|
||||
for (q=0; q<Q; q++){
|
||||
weights[q] = sqrt(1.0*(D3Q27[q][0]*D3Q27[q][0]) + 1.0*(D3Q27[q][1]*D3Q27[q][1]) + 1.0*(D3Q27[q][2]*D3Q27[q][2]));
|
||||
}
|
||||
|
||||
int xdim,ydim,zdim;
|
||||
xdim=Dm.Nx-2;
|
||||
ydim=Dm.Ny-2;
|
||||
zdim=Dm.Nz-2;
|
||||
fillHalo<double> fillData(Dm.Comm, Dm.rank_info,xdim,ydim,zdim,1,1,1,0,1);
|
||||
|
||||
int count = 0;
|
||||
while (count < timesteps){
|
||||
|
||||
// Communicate the halo of values
|
||||
fillData.fill(Distance);
|
||||
|
||||
TotalVariation=0.0;
|
||||
// Execute the next timestep
|
||||
for (k=1;k<Dm.Nz-1;k++){
|
||||
for (j=1;j<Dm.Ny-1;j++){
|
||||
for (i=1;i<Dm.Nx-1;i++){
|
||||
|
||||
int n = k*Dm.Nx*Dm.Ny + j*Dm.Nx + i;
|
||||
//sign = Distance(i,j,k) / fabs(Distance(i,j,k));
|
||||
sign = -1;
|
||||
if (ID[n] == 1) sign = 1;
|
||||
/*
|
||||
if (!(i+1<Nx)) nx=0.5*Distance(i,j,k);
|
||||
else nx=0.5*Distance(i+1,j,k);;
|
||||
if (!(j+1<Ny)) ny=0.5*Distance(i,j,k);
|
||||
else ny=0.5*Distance(i,j+1,k);
|
||||
if (!(k+1<Nz)) nz=0.5*Distance(i,j,k);
|
||||
else nz=0.5*Distance(i,j,k+1);
|
||||
if (i<1) nx-=0.5*Distance(i,j,k);
|
||||
else nx-=0.5*Distance(i-1,j,k);
|
||||
if (j<1) ny-=0.5*Distance(i,j,k);
|
||||
else ny-=0.5*Distance(i,j-1,k);
|
||||
if (k<1) nz-=0.5*Distance(i,j,k);
|
||||
else nz-=0.5*Distance(i,j,k-1);
|
||||
*/
|
||||
|
||||
//............Compute the Gradient...................................
|
||||
nx = 0.5*(Distance(i+1,j,k) - Distance(i-1,j,k));
|
||||
ny = 0.5*(Distance(i,j+1,k) - Distance(i,j-1,k));
|
||||
nz = 0.5*(Distance(i,j,k+1) - Distance(i,j,k-1));
|
||||
|
||||
W = 0.0; Dx = Dy = Dz = 0.0;
|
||||
// also ignore places where the gradient is zero since this will not
|
||||
// result in any local change to Distance
|
||||
if (nx*nx+ny*ny+nz*nz > 0.0 ){
|
||||
for (q=0; q<26; q++){
|
||||
Cqx = 1.0*D3Q27[q][0];
|
||||
Cqy = 1.0*D3Q27[q][1];
|
||||
Cqz = 1.0*D3Q27[q][2];
|
||||
// get the associated neighbor
|
||||
in = i + D3Q27[q][0];
|
||||
jn = j + D3Q27[q][1];
|
||||
kn = k + D3Q27[q][2];
|
||||
|
||||
// make sure the neighbor is in the domain (periodic BC)
|
||||
/* if (in < 0 ) in +=Nx;
|
||||
* don't need this in parallel since MPI handles the halos
|
||||
if (jn < 0 ) jn +=Ny;
|
||||
if (kn < 0 ) kn +=Nz;
|
||||
if (!(in < Nx) ) in -=Nx;
|
||||
if (!(jn < Ny) ) jn -=Ny;
|
||||
if (!(kn < Nz) ) kn -=Nz;
|
||||
// symmetric boundary
|
||||
if (in < 0 ) in = i;
|
||||
if (jn < 0 ) jn = j;
|
||||
if (kn < 0 ) kn = k;
|
||||
if (!(in < Nx) ) in = i;
|
||||
if (!(jn < Ny) ) jn = k;
|
||||
if (!(kn < Nz) ) kn = k;
|
||||
*/
|
||||
|
||||
// Compute the gradient using upwind finite differences
|
||||
Dqx = weights[q]*(Distance(i,j,k) - Distance(in,jn,kn))*Cqx;
|
||||
Dqy = weights[q]*(Distance(i,j,k) - Distance(in,jn,kn))*Cqy;
|
||||
Dqz = weights[q]*(Distance(i,j,k) - Distance(in,jn,kn))*Cqz;
|
||||
|
||||
// Only include upwind derivatives
|
||||
if (sign*(nx*Cqx + ny*Cqy + nz*Cqz) < 0.0 ){
|
||||
|
||||
Dx += Dqx;
|
||||
Dy += Dqy;
|
||||
Dz += Dqz;
|
||||
W += weights[q];
|
||||
}
|
||||
}
|
||||
// Normalize by the weight to get the approximation to the gradient
|
||||
if (fabs(W) > 0.0){
|
||||
Dx /= W;
|
||||
Dy /= W;
|
||||
Dz /= W;
|
||||
}
|
||||
norm = sqrt(Dx*Dx+Dy*Dy+Dz*Dz);
|
||||
}
|
||||
else{
|
||||
norm = 0.0;
|
||||
}
|
||||
Distance(i,j,k) += dt*sign*(1.0 - norm);
|
||||
TotalVariation += dt*sign*(1.0 - norm);
|
||||
// Disallow any change in phase
|
||||
// if (Distance(i,j,k)*2.0*(ID[n]-1.0) < 0) Distance(i,j,k) = -Distance(i,j,k);
|
||||
}
|
||||
}
|
||||
}
|
||||
TotalVariation /= (Dm.Nx-2)*(Dm.Ny-2)*(Dm.Nz-2);
|
||||
count++;
|
||||
}
|
||||
|
||||
return TotalVariation;
|
||||
}
|
||||
|
||||
|
||||
void ReadSpherePacking(int nspheres, double *List_cx, double *List_cy, double *List_cz, double *List_rad)
|
||||
{
|
||||
// Read in the full sphere pack
|
||||
//...... READ IN THE SPHERES...................................
|
||||
cout << "Reading the packing file..." << endl;
|
||||
FILE *fid = fopen("pack.out","rb");
|
||||
INSIST(fid!=NULL,"Error opening pack.out");
|
||||
//.........Trash the header lines..........
|
||||
char line[100];
|
||||
fgetl(line, 100, fid);
|
||||
fgetl(line, 100, fid);
|
||||
fgetl(line, 100, fid);
|
||||
fgetl(line, 100, fid);
|
||||
fgetl(line, 100, fid);
|
||||
//........read the spheres..................
|
||||
// We will read until a blank like or end-of-file is reached
|
||||
int count = 0;
|
||||
while ( !feof(fid) && fgets(line,100,fid)!=NULL ) {
|
||||
char* line2 = line;
|
||||
List_cx[count] = strtod(line2,&line2);
|
||||
List_cy[count] = strtod(line2,&line2);
|
||||
List_cz[count] = strtod(line2,&line2);
|
||||
List_rad[count] = strtod(line2,&line2);
|
||||
count++;
|
||||
}
|
||||
cout << "Number of spheres extracted is: " << count << endl;
|
||||
INSIST( count==nspheres, "Specified number of spheres is probably incorrect!" );
|
||||
// .............................................................
|
||||
}
|
||||
|
||||
void AssignLocalSolidID(char *ID, int nspheres, double *List_cx, double *List_cy, double *List_cz, double *List_rad,
|
||||
double Lx, double Ly, double Lz, int Nx, int Ny, int Nz,
|
||||
int iproc, int jproc, int kproc, int nprocx, int nprocy, int nprocz)
|
||||
{
|
||||
// Use sphere lists to determine which nodes are in porespace
|
||||
// Write out binary file for nodes
|
||||
char value;
|
||||
int N = Nx*Ny*Nz; // Domain size, including the halo
|
||||
double hx,hy,hz;
|
||||
double x,y,z;
|
||||
double cx,cy,cz,r;
|
||||
int imin,imax,jmin,jmax,kmin,kmax;
|
||||
int p,i,j,k,n;
|
||||
//............................................
|
||||
double min_x,min_y,min_z;
|
||||
// double max_x,max_y,max_z;
|
||||
//............................................
|
||||
// Lattice spacing for the entire domain
|
||||
// It should generally be true that hx=hy=hz
|
||||
// Otherwise, you will end up with ellipsoids
|
||||
hx = Lx/(Nx*nprocx-1);
|
||||
hy = Ly/(Ny*nprocy-1);
|
||||
hz = Lz/(Nz*nprocz-1);
|
||||
//............................................
|
||||
// Get maximum and minimum for this domain
|
||||
// Halo is included !
|
||||
min_x = double(iproc*Nx-1)*hx;
|
||||
min_y = double(jproc*Ny-1)*hy;
|
||||
min_z = double(kproc*Nz-1)*hz;
|
||||
// max_x = ((iproc+1)*Nx+1)*hx;
|
||||
// max_y = ((jproc+1)*Ny+1)*hy;
|
||||
// max_z = ((kproc+1)*Nz+1)*hz;
|
||||
//............................................
|
||||
|
||||
//............................................
|
||||
// Pre-initialize local ID
|
||||
for (n=0;n<N;n++){
|
||||
ID[n]=1;
|
||||
}
|
||||
//............................................
|
||||
|
||||
//............................................
|
||||
// .........Loop over the spheres.............
|
||||
for (p=0;p<nspheres;p++){
|
||||
// Get the sphere from the list, map to local min
|
||||
cx = List_cx[p] - min_x;
|
||||
cy = List_cy[p] - min_y;
|
||||
cz = List_cz[p] - min_z;
|
||||
r = List_rad[p];
|
||||
// Check if
|
||||
// Range for this sphere in global indexing
|
||||
imin = int ((cx-r)/hx)-1;
|
||||
imax = int ((cx+r)/hx)+1;
|
||||
jmin = int ((cy-r)/hy)-1;
|
||||
jmax = int ((cy+r)/hy)+1;
|
||||
kmin = int ((cz-r)/hz)-1;
|
||||
kmax = int ((cz+r)/hz)+1;
|
||||
// Obviously we have to do something at the edges
|
||||
if (imin<0) imin = 0;
|
||||
if (imin>Nx) imin = Nx;
|
||||
if (imax<0) imax = 0;
|
||||
if (imax>Nx) imax = Nx;
|
||||
if (jmin<0) jmin = 0;
|
||||
if (jmin>Ny) jmin = Ny;
|
||||
if (jmax<0) jmax = 0;
|
||||
if (jmax>Ny) jmax = Ny;
|
||||
if (kmin<0) kmin = 0;
|
||||
if (kmin>Nz) kmin = Nz;
|
||||
if (kmax<0) kmax = 0;
|
||||
if (kmax>Nz) kmax = Nz;
|
||||
// Loop over the domain for this sphere (may be null)
|
||||
for (i=imin;i<imax;i++){
|
||||
for (j=jmin;j<jmax;j++){
|
||||
for (k=kmin;k<kmax;k++){
|
||||
// Initialize ID value to 'fluid (=1)'
|
||||
x = i*hx;
|
||||
y = j*hy;
|
||||
z = k*hz;
|
||||
value = 1;
|
||||
// if inside sphere, set to zero
|
||||
if ( (cx-x)*(cx-x)+(cy-y)*(cy-y)+(cz-z)*(cz-z) < r*r){
|
||||
value=0;
|
||||
}
|
||||
// get the position in the list
|
||||
n = k*Nx*Ny+j*Nx+i;
|
||||
if ( ID[n] != 0 ){
|
||||
ID[n] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SignedDistance(double *Distance, int nspheres, double *List_cx, double *List_cy, double *List_cz, double *List_rad,
|
||||
double Lx, double Ly, double Lz, int Nx, int Ny, int Nz,
|
||||
int iproc, int jproc, int kproc, int nprocx, int nprocy, int nprocz)
|
||||
{
|
||||
// Use sphere lists to determine which nodes are in porespace
|
||||
// Write out binary file for nodes
|
||||
int N = Nx*Ny*Nz; // Domain size, including the halo
|
||||
double hx,hy,hz;
|
||||
double x,y,z;
|
||||
double cx,cy,cz,r;
|
||||
int imin,imax,jmin,jmax,kmin,kmax;
|
||||
int p,i,j,k,n;
|
||||
//............................................
|
||||
double min_x,min_y,min_z;
|
||||
double distance;
|
||||
//............................................
|
||||
// Lattice spacing for the entire domain
|
||||
// It should generally be true that hx=hy=hz
|
||||
// Otherwise, you will end up with ellipsoids
|
||||
hx = Lx/((Nx-2)*nprocx-1);
|
||||
hy = Ly/((Ny-2)*nprocy-1);
|
||||
hz = Lz/((Nz-2)*nprocz-1);
|
||||
//............................................
|
||||
// Get maximum and minimum for this domain
|
||||
// Halo is included !
|
||||
min_x = double(iproc*(Nx-2)-1)*hx;
|
||||
min_y = double(jproc*(Ny-2)-1)*hy;
|
||||
min_z = double(kproc*(Nz-2)-1)*hz;
|
||||
//............................................
|
||||
|
||||
//............................................
|
||||
// Pre-initialize Distance
|
||||
for (n=0;n<N;n++){
|
||||
Distance[n]=100.0;
|
||||
}
|
||||
//............................................
|
||||
|
||||
//............................................
|
||||
// .........Loop over the spheres.............
|
||||
for (p=0;p<nspheres;p++){
|
||||
// Get the sphere from the list, map to local min
|
||||
cx = List_cx[p] - min_x;
|
||||
cy = List_cy[p] - min_y;
|
||||
cz = List_cz[p] - min_z;
|
||||
r = List_rad[p];
|
||||
// Check if
|
||||
// Range for this sphere in global indexing
|
||||
imin = int ((cx-2*r)/hx);
|
||||
imax = int ((cx+2*r)/hx)+2;
|
||||
jmin = int ((cy-2*r)/hy);
|
||||
jmax = int ((cy+2*r)/hy)+2;
|
||||
kmin = int ((cz-2*r)/hz);
|
||||
kmax = int ((cz+2*r)/hz)+2;
|
||||
// Obviously we have to do something at the edges
|
||||
if (imin<0) imin = 0;
|
||||
if (imin>Nx) imin = Nx;
|
||||
if (imax<0) imax = 0;
|
||||
if (imax>Nx) imax = Nx;
|
||||
if (jmin<0) jmin = 0;
|
||||
if (jmin>Ny) jmin = Ny;
|
||||
if (jmax<0) jmax = 0;
|
||||
if (jmax>Ny) jmax = Ny;
|
||||
if (kmin<0) kmin = 0;
|
||||
if (kmin>Nz) kmin = Nz;
|
||||
if (kmax<0) kmax = 0;
|
||||
if (kmax>Nz) kmax = Nz;
|
||||
// Loop over the domain for this sphere (may be null)
|
||||
for (i=imin;i<imax;i++){
|
||||
for (j=jmin;j<jmax;j++){
|
||||
for (k=kmin;k<kmax;k++){
|
||||
// x,y,z is distance in physical units
|
||||
x = i*hx;
|
||||
y = j*hy;
|
||||
z = k*hz;
|
||||
// if inside sphere, set to zero
|
||||
// get the position in the list
|
||||
n = k*Nx*Ny+j*Nx+i;
|
||||
// Compute the distance
|
||||
distance = sqrt((cx-x)*(cx-x)+(cy-y)*(cy-y)+(cz-z)*(cz-z)) - r;
|
||||
// Assign the minimum distance
|
||||
if (distance < Distance[n]) Distance[n] = distance;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Map the distance to lattice units
|
||||
for (n=0; n<N; n++) Distance[n] = Distance[n]/hx;
|
||||
}
|
||||
|
||||
void WriteLocalSolidID(char *FILENAME, char *ID, int N)
|
||||
{
|
||||
char value;
|
||||
ofstream File(FILENAME,ios::binary);
|
||||
for (int n=0; n<N; n++){
|
||||
value = ID[n];
|
||||
File.write((char*) &value, sizeof(value));
|
||||
}
|
||||
File.close();
|
||||
}
|
||||
|
||||
void WriteLocalSolidDistance(char *FILENAME, double *Distance, int N)
|
||||
{
|
||||
double value;
|
||||
ofstream File(FILENAME,ios::binary);
|
||||
for (int n=0; n<N; n++){
|
||||
value = Distance[n];
|
||||
File.write((char*) &value, sizeof(value));
|
||||
}
|
||||
File.close();
|
||||
}
|
||||
|
||||
|
||||
void WriteCheckpoint(const char *FILENAME, const double *cDen, const double *cfq, int Np)
|
||||
{
|
||||
int q,n;
|
||||
double value;
|
||||
ofstream File(FILENAME,ios::binary);
|
||||
for (n=0; n<Np; n++){
|
||||
// Write the two density values
|
||||
value = cDen[n];
|
||||
File.write((char*) &value, sizeof(value));
|
||||
value = cDen[Np+n];
|
||||
File.write((char*) &value, sizeof(value));
|
||||
// Write the even distributions
|
||||
for (q=0; q<19; q++){
|
||||
value = cfq[q*Np+n];
|
||||
File.write((char*) &value, sizeof(value));
|
||||
}
|
||||
}
|
||||
File.close();
|
||||
|
||||
}
|
||||
|
||||
void ReadCheckpoint(char *FILENAME, double *cDen, double *cfq, int Np)
|
||||
{
|
||||
int q=0, n=0;
|
||||
double value=0;
|
||||
ifstream File(FILENAME,ios::binary);
|
||||
for (n=0; n<Np; n++){
|
||||
// Write the two density values
|
||||
File.read((char*) &value, sizeof(value));
|
||||
cDen[n] = value;
|
||||
File.read((char*) &value, sizeof(value));
|
||||
cDen[Np+n] = value;
|
||||
// Read the even distributions
|
||||
for (q=0; q<19; q++){
|
||||
File.read((char*) &value, sizeof(value));
|
||||
cfq[q*Np+n] = value;
|
||||
}
|
||||
}
|
||||
File.close();
|
||||
}
|
||||
|
||||
void ReadBinaryFile(char *FILENAME, double *Data, int N)
|
||||
{
|
||||
int n;
|
||||
double value;
|
||||
ifstream File(FILENAME,ios::binary);
|
||||
if (File.good()){
|
||||
for (n=0; n<N; n++){
|
||||
// Write the two density values
|
||||
File.read((char*) &value, sizeof(value));
|
||||
Data[n] = value;
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (n=0; n<N; n++) Data[n] = 1.2e-34;
|
||||
}
|
||||
File.close();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
496
common/Domain.h
496
common/Domain.h
@ -3,39 +3,60 @@
|
||||
// Created by James McClure
|
||||
// Copyright 2008-2013
|
||||
|
||||
//#define _GLIBCXX_USE_CXX11_ABI 0
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <exception> // std::exception
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "common/Array.h"
|
||||
#include "common/Utilities.h"
|
||||
#include "common/MPI_Helpers.h"
|
||||
#include "common/Communication.h"
|
||||
#include "common/Database.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
//! Read the domain information file
|
||||
void read_domain( int rank, int nprocs, MPI_Comm comm,
|
||||
int& nprocx, int& nprocy, int& nprocz, int& nx, int& ny, int& nz,
|
||||
int& nspheres, double& Lx, double& Ly, double& Lz );
|
||||
std::shared_ptr<Database> read_domain( );
|
||||
|
||||
|
||||
//! Class to hold domain info
|
||||
struct Domain{
|
||||
// Default constructor
|
||||
Domain(int nx, int ny, int nz, int rnk, int npx, int npy, int npz,
|
||||
double lx, double ly, double lz, int BC);
|
||||
class Domain{
|
||||
public:
|
||||
//! Default constructor
|
||||
Domain( std::shared_ptr<Database> db );
|
||||
|
||||
// Destructor
|
||||
//! Obsolete constructor
|
||||
Domain( int nx, int ny, int nz, int rnk, int npx, int npy, int npz,
|
||||
double lx, double ly, double lz, int BC);
|
||||
|
||||
//! Empty constructor
|
||||
Domain() = delete;
|
||||
|
||||
//! Copy constructor
|
||||
Domain( const Domain& ) = delete;
|
||||
|
||||
//! Assignment operator
|
||||
Domain& operator=( const Domain& ) = delete;
|
||||
|
||||
//! Destructor
|
||||
~Domain();
|
||||
|
||||
//! Get the database
|
||||
inline std::shared_ptr<const Database> getDatabase() const { return d_db; }
|
||||
|
||||
private:
|
||||
|
||||
void initialize( std::shared_ptr<Database> db );
|
||||
|
||||
std::shared_ptr<Database> d_db;
|
||||
|
||||
public:
|
||||
|
||||
// Basic domain information
|
||||
int Nx,Ny,Nz,N;
|
||||
int iproc,jproc,kproc;
|
||||
@ -114,454 +135,27 @@ private:
|
||||
};
|
||||
|
||||
|
||||
double SSO(DoubleArray &Distance, char *ID, Domain &Dm, int timesteps);
|
||||
|
||||
// Inline function to read line without a return argument
|
||||
static inline void fgetl( char * str, int num, FILE * stream )
|
||||
{
|
||||
char* ptr = fgets( str, num, stream );
|
||||
if ( 0 ) {char *temp = (char *)&ptr; temp++;}
|
||||
}
|
||||
void ReadSpherePacking(int nspheres, double *List_cx, double *List_cy, double *List_cz, double *List_rad);
|
||||
|
||||
void AssignLocalSolidID(char *ID, int nspheres, double *List_cx, double *List_cy, double *List_cz, double *List_rad,
|
||||
double Lx, double Ly, double Lz, int Nx, int Ny, int Nz,
|
||||
int iproc, int jproc, int kproc, int nprocx, int nprocy, int nprocz);
|
||||
|
||||
void SignedDistance(double *Distance, int nspheres, double *List_cx, double *List_cy, double *List_cz, double *List_rad,
|
||||
double Lx, double Ly, double Lz, int Nx, int Ny, int Nz,
|
||||
int iproc, int jproc, int kproc, int nprocx, int nprocy, int nprocz);
|
||||
|
||||
inline double SSO(DoubleArray &Distance, char *ID, Domain &Dm, int timesteps){
|
||||
/*
|
||||
* This routine converts the data in the Distance array to a signed distance
|
||||
* by solving the equation df/dt = sign(1-|grad f|), where Distance provides
|
||||
* the values of f on the mesh associated with domain Dm
|
||||
* It has been tested with segmented data initialized to values [-1,1]
|
||||
* and will converge toward the signed distance to the surface bounding the associated phases
|
||||
*/
|
||||
void WriteLocalSolidID(char *FILENAME, char *ID, int N);
|
||||
|
||||
int Q=26;
|
||||
int q,i,j,k;
|
||||
double dt=0.1;
|
||||
int in,jn,kn;
|
||||
double Dqx,Dqy,Dqz,Dx,Dy,Dz,W;
|
||||
double nx,ny,nz,Cqx,Cqy,Cqz,sign,norm;
|
||||
double TotalVariation=0.0;
|
||||
void WriteLocalSolidDistance(char *FILENAME, double *Distance, int N);
|
||||
|
||||
const static int D3Q27[26][3]={{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1},
|
||||
{1,1,0},{-1,-1,0},{1,-1,0},{-1,1,0},{1,0,1},{-1,0,-1},{1,0,-1},{-1,0,1},
|
||||
{0,1,1},{0,-1,-1},{0,1,-1},{0,-1,1},{1,1,1},{-1,-1,-1},{1,1,-1},{-1,-1,1},
|
||||
{-1,1,-1},{1,-1,1},{1,-1,-1},{-1,1,1}};
|
||||
void WriteCheckpoint(const char *FILENAME, const double *cDen, const double *cfq, int Np);
|
||||
|
||||
double weights[26];
|
||||
// Compute the weights from the finite differences
|
||||
for (q=0; q<Q; q++){
|
||||
weights[q] = sqrt(1.0*(D3Q27[q][0]*D3Q27[q][0]) + 1.0*(D3Q27[q][1]*D3Q27[q][1]) + 1.0*(D3Q27[q][2]*D3Q27[q][2]));
|
||||
}
|
||||
void ReadCheckpoint(char *FILENAME, double *cDen, double *cfq, int Np);
|
||||
|
||||
int xdim,ydim,zdim;
|
||||
xdim=Dm.Nx-2;
|
||||
ydim=Dm.Ny-2;
|
||||
zdim=Dm.Nz-2;
|
||||
fillHalo<double> fillData(Dm.Comm, Dm.rank_info,xdim,ydim,zdim,1,1,1,0,1);
|
||||
|
||||
int count = 0;
|
||||
while (count < timesteps){
|
||||
|
||||
// Communicate the halo of values
|
||||
fillData.fill(Distance);
|
||||
|
||||
TotalVariation=0.0;
|
||||
// Execute the next timestep
|
||||
for (k=1;k<Dm.Nz-1;k++){
|
||||
for (j=1;j<Dm.Ny-1;j++){
|
||||
for (i=1;i<Dm.Nx-1;i++){
|
||||
|
||||
int n = k*Dm.Nx*Dm.Ny + j*Dm.Nx + i;
|
||||
//sign = Distance(i,j,k) / fabs(Distance(i,j,k));
|
||||
sign = -1;
|
||||
if (ID[n] == 1) sign = 1;
|
||||
/*
|
||||
if (!(i+1<Nx)) nx=0.5*Distance(i,j,k);
|
||||
else nx=0.5*Distance(i+1,j,k);;
|
||||
if (!(j+1<Ny)) ny=0.5*Distance(i,j,k);
|
||||
else ny=0.5*Distance(i,j+1,k);
|
||||
if (!(k+1<Nz)) nz=0.5*Distance(i,j,k);
|
||||
else nz=0.5*Distance(i,j,k+1);
|
||||
if (i<1) nx-=0.5*Distance(i,j,k);
|
||||
else nx-=0.5*Distance(i-1,j,k);
|
||||
if (j<1) ny-=0.5*Distance(i,j,k);
|
||||
else ny-=0.5*Distance(i,j-1,k);
|
||||
if (k<1) nz-=0.5*Distance(i,j,k);
|
||||
else nz-=0.5*Distance(i,j,k-1);
|
||||
*/
|
||||
|
||||
//............Compute the Gradient...................................
|
||||
nx = 0.5*(Distance(i+1,j,k) - Distance(i-1,j,k));
|
||||
ny = 0.5*(Distance(i,j+1,k) - Distance(i,j-1,k));
|
||||
nz = 0.5*(Distance(i,j,k+1) - Distance(i,j,k-1));
|
||||
|
||||
W = 0.0; Dx = Dy = Dz = 0.0;
|
||||
// also ignore places where the gradient is zero since this will not
|
||||
// result in any local change to Distance
|
||||
if (nx*nx+ny*ny+nz*nz > 0.0 ){
|
||||
for (q=0; q<26; q++){
|
||||
Cqx = 1.0*D3Q27[q][0];
|
||||
Cqy = 1.0*D3Q27[q][1];
|
||||
Cqz = 1.0*D3Q27[q][2];
|
||||
// get the associated neighbor
|
||||
in = i + D3Q27[q][0];
|
||||
jn = j + D3Q27[q][1];
|
||||
kn = k + D3Q27[q][2];
|
||||
|
||||
// make sure the neighbor is in the domain (periodic BC)
|
||||
/* if (in < 0 ) in +=Nx;
|
||||
* don't need this in parallel since MPI handles the halos
|
||||
if (jn < 0 ) jn +=Ny;
|
||||
if (kn < 0 ) kn +=Nz;
|
||||
if (!(in < Nx) ) in -=Nx;
|
||||
if (!(jn < Ny) ) jn -=Ny;
|
||||
if (!(kn < Nz) ) kn -=Nz;
|
||||
// symmetric boundary
|
||||
if (in < 0 ) in = i;
|
||||
if (jn < 0 ) jn = j;
|
||||
if (kn < 0 ) kn = k;
|
||||
if (!(in < Nx) ) in = i;
|
||||
if (!(jn < Ny) ) jn = k;
|
||||
if (!(kn < Nz) ) kn = k;
|
||||
*/
|
||||
|
||||
// Compute the gradient using upwind finite differences
|
||||
Dqx = weights[q]*(Distance(i,j,k) - Distance(in,jn,kn))*Cqx;
|
||||
Dqy = weights[q]*(Distance(i,j,k) - Distance(in,jn,kn))*Cqy;
|
||||
Dqz = weights[q]*(Distance(i,j,k) - Distance(in,jn,kn))*Cqz;
|
||||
|
||||
// Only include upwind derivatives
|
||||
if (sign*(nx*Cqx + ny*Cqy + nz*Cqz) < 0.0 ){
|
||||
|
||||
Dx += Dqx;
|
||||
Dy += Dqy;
|
||||
Dz += Dqz;
|
||||
W += weights[q];
|
||||
}
|
||||
}
|
||||
// Normalize by the weight to get the approximation to the gradient
|
||||
if (fabs(W) > 0.0){
|
||||
Dx /= W;
|
||||
Dy /= W;
|
||||
Dz /= W;
|
||||
}
|
||||
norm = sqrt(Dx*Dx+Dy*Dy+Dz*Dz);
|
||||
}
|
||||
else{
|
||||
norm = 0.0;
|
||||
}
|
||||
Distance(i,j,k) += dt*sign*(1.0 - norm);
|
||||
TotalVariation += dt*sign*(1.0 - norm);
|
||||
// Disallow any change in phase
|
||||
// if (Distance(i,j,k)*2.0*(ID[n]-1.0) < 0) Distance(i,j,k) = -Distance(i,j,k);
|
||||
}
|
||||
}
|
||||
}
|
||||
TotalVariation /= (Dm.Nx-2)*(Dm.Ny-2)*(Dm.Nz-2);
|
||||
count++;
|
||||
}
|
||||
|
||||
return TotalVariation;
|
||||
}
|
||||
|
||||
|
||||
inline void ReadSpherePacking(int nspheres, double *List_cx, double *List_cy, double *List_cz, double *List_rad)
|
||||
{
|
||||
// Read in the full sphere pack
|
||||
//...... READ IN THE SPHERES...................................
|
||||
cout << "Reading the packing file..." << endl;
|
||||
FILE *fid = fopen("pack.out","rb");
|
||||
INSIST(fid!=NULL,"Error opening pack.out");
|
||||
//.........Trash the header lines..........
|
||||
char line[100];
|
||||
fgetl(line, 100, fid);
|
||||
fgetl(line, 100, fid);
|
||||
fgetl(line, 100, fid);
|
||||
fgetl(line, 100, fid);
|
||||
fgetl(line, 100, fid);
|
||||
//........read the spheres..................
|
||||
// We will read until a blank like or end-of-file is reached
|
||||
int count = 0;
|
||||
while ( !feof(fid) && fgets(line,100,fid)!=NULL ) {
|
||||
char* line2 = line;
|
||||
List_cx[count] = strtod(line2,&line2);
|
||||
List_cy[count] = strtod(line2,&line2);
|
||||
List_cz[count] = strtod(line2,&line2);
|
||||
List_rad[count] = strtod(line2,&line2);
|
||||
count++;
|
||||
}
|
||||
cout << "Number of spheres extracted is: " << count << endl;
|
||||
INSIST( count==nspheres, "Specified number of spheres is probably incorrect!" );
|
||||
// .............................................................
|
||||
}
|
||||
|
||||
inline void AssignLocalSolidID(char *ID, int nspheres, double *List_cx, double *List_cy, double *List_cz, double *List_rad,
|
||||
double Lx, double Ly, double Lz, int Nx, int Ny, int Nz,
|
||||
int iproc, int jproc, int kproc, int nprocx, int nprocy, int nprocz)
|
||||
{
|
||||
// Use sphere lists to determine which nodes are in porespace
|
||||
// Write out binary file for nodes
|
||||
char value;
|
||||
int N = Nx*Ny*Nz; // Domain size, including the halo
|
||||
double hx,hy,hz;
|
||||
double x,y,z;
|
||||
double cx,cy,cz,r;
|
||||
int imin,imax,jmin,jmax,kmin,kmax;
|
||||
int p,i,j,k,n;
|
||||
//............................................
|
||||
double min_x,min_y,min_z;
|
||||
// double max_x,max_y,max_z;
|
||||
//............................................
|
||||
// Lattice spacing for the entire domain
|
||||
// It should generally be true that hx=hy=hz
|
||||
// Otherwise, you will end up with ellipsoids
|
||||
hx = Lx/(Nx*nprocx-1);
|
||||
hy = Ly/(Ny*nprocy-1);
|
||||
hz = Lz/(Nz*nprocz-1);
|
||||
//............................................
|
||||
// Get maximum and minimum for this domain
|
||||
// Halo is included !
|
||||
min_x = double(iproc*Nx-1)*hx;
|
||||
min_y = double(jproc*Ny-1)*hy;
|
||||
min_z = double(kproc*Nz-1)*hz;
|
||||
// max_x = ((iproc+1)*Nx+1)*hx;
|
||||
// max_y = ((jproc+1)*Ny+1)*hy;
|
||||
// max_z = ((kproc+1)*Nz+1)*hz;
|
||||
//............................................
|
||||
|
||||
//............................................
|
||||
// Pre-initialize local ID
|
||||
for (n=0;n<N;n++){
|
||||
ID[n]=1;
|
||||
}
|
||||
//............................................
|
||||
|
||||
//............................................
|
||||
// .........Loop over the spheres.............
|
||||
for (p=0;p<nspheres;p++){
|
||||
// Get the sphere from the list, map to local min
|
||||
cx = List_cx[p] - min_x;
|
||||
cy = List_cy[p] - min_y;
|
||||
cz = List_cz[p] - min_z;
|
||||
r = List_rad[p];
|
||||
// Check if
|
||||
// Range for this sphere in global indexing
|
||||
imin = int ((cx-r)/hx)-1;
|
||||
imax = int ((cx+r)/hx)+1;
|
||||
jmin = int ((cy-r)/hy)-1;
|
||||
jmax = int ((cy+r)/hy)+1;
|
||||
kmin = int ((cz-r)/hz)-1;
|
||||
kmax = int ((cz+r)/hz)+1;
|
||||
// Obviously we have to do something at the edges
|
||||
if (imin<0) imin = 0;
|
||||
if (imin>Nx) imin = Nx;
|
||||
if (imax<0) imax = 0;
|
||||
if (imax>Nx) imax = Nx;
|
||||
if (jmin<0) jmin = 0;
|
||||
if (jmin>Ny) jmin = Ny;
|
||||
if (jmax<0) jmax = 0;
|
||||
if (jmax>Ny) jmax = Ny;
|
||||
if (kmin<0) kmin = 0;
|
||||
if (kmin>Nz) kmin = Nz;
|
||||
if (kmax<0) kmax = 0;
|
||||
if (kmax>Nz) kmax = Nz;
|
||||
// Loop over the domain for this sphere (may be null)
|
||||
for (i=imin;i<imax;i++){
|
||||
for (j=jmin;j<jmax;j++){
|
||||
for (k=kmin;k<kmax;k++){
|
||||
// Initialize ID value to 'fluid (=1)'
|
||||
x = i*hx;
|
||||
y = j*hy;
|
||||
z = k*hz;
|
||||
value = 1;
|
||||
// if inside sphere, set to zero
|
||||
if ( (cx-x)*(cx-x)+(cy-y)*(cy-y)+(cz-z)*(cz-z) < r*r){
|
||||
value=0;
|
||||
}
|
||||
// get the position in the list
|
||||
n = k*Nx*Ny+j*Nx+i;
|
||||
if ( ID[n] != 0 ){
|
||||
ID[n] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void SignedDistance(double *Distance, int nspheres, double *List_cx, double *List_cy, double *List_cz, double *List_rad,
|
||||
double Lx, double Ly, double Lz, int Nx, int Ny, int Nz,
|
||||
int iproc, int jproc, int kproc, int nprocx, int nprocy, int nprocz)
|
||||
{
|
||||
// Use sphere lists to determine which nodes are in porespace
|
||||
// Write out binary file for nodes
|
||||
int N = Nx*Ny*Nz; // Domain size, including the halo
|
||||
double hx,hy,hz;
|
||||
double x,y,z;
|
||||
double cx,cy,cz,r;
|
||||
int imin,imax,jmin,jmax,kmin,kmax;
|
||||
int p,i,j,k,n;
|
||||
//............................................
|
||||
double min_x,min_y,min_z;
|
||||
double distance;
|
||||
//............................................
|
||||
// Lattice spacing for the entire domain
|
||||
// It should generally be true that hx=hy=hz
|
||||
// Otherwise, you will end up with ellipsoids
|
||||
hx = Lx/((Nx-2)*nprocx-1);
|
||||
hy = Ly/((Ny-2)*nprocy-1);
|
||||
hz = Lz/((Nz-2)*nprocz-1);
|
||||
//............................................
|
||||
// Get maximum and minimum for this domain
|
||||
// Halo is included !
|
||||
min_x = double(iproc*(Nx-2)-1)*hx;
|
||||
min_y = double(jproc*(Ny-2)-1)*hy;
|
||||
min_z = double(kproc*(Nz-2)-1)*hz;
|
||||
//............................................
|
||||
|
||||
//............................................
|
||||
// Pre-initialize Distance
|
||||
for (n=0;n<N;n++){
|
||||
Distance[n]=100.0;
|
||||
}
|
||||
//............................................
|
||||
|
||||
//............................................
|
||||
// .........Loop over the spheres.............
|
||||
for (p=0;p<nspheres;p++){
|
||||
// Get the sphere from the list, map to local min
|
||||
cx = List_cx[p] - min_x;
|
||||
cy = List_cy[p] - min_y;
|
||||
cz = List_cz[p] - min_z;
|
||||
r = List_rad[p];
|
||||
// Check if
|
||||
// Range for this sphere in global indexing
|
||||
imin = int ((cx-2*r)/hx);
|
||||
imax = int ((cx+2*r)/hx)+2;
|
||||
jmin = int ((cy-2*r)/hy);
|
||||
jmax = int ((cy+2*r)/hy)+2;
|
||||
kmin = int ((cz-2*r)/hz);
|
||||
kmax = int ((cz+2*r)/hz)+2;
|
||||
// Obviously we have to do something at the edges
|
||||
if (imin<0) imin = 0;
|
||||
if (imin>Nx) imin = Nx;
|
||||
if (imax<0) imax = 0;
|
||||
if (imax>Nx) imax = Nx;
|
||||
if (jmin<0) jmin = 0;
|
||||
if (jmin>Ny) jmin = Ny;
|
||||
if (jmax<0) jmax = 0;
|
||||
if (jmax>Ny) jmax = Ny;
|
||||
if (kmin<0) kmin = 0;
|
||||
if (kmin>Nz) kmin = Nz;
|
||||
if (kmax<0) kmax = 0;
|
||||
if (kmax>Nz) kmax = Nz;
|
||||
// Loop over the domain for this sphere (may be null)
|
||||
for (i=imin;i<imax;i++){
|
||||
for (j=jmin;j<jmax;j++){
|
||||
for (k=kmin;k<kmax;k++){
|
||||
// x,y,z is distance in physical units
|
||||
x = i*hx;
|
||||
y = j*hy;
|
||||
z = k*hz;
|
||||
// if inside sphere, set to zero
|
||||
// get the position in the list
|
||||
n = k*Nx*Ny+j*Nx+i;
|
||||
// Compute the distance
|
||||
distance = sqrt((cx-x)*(cx-x)+(cy-y)*(cy-y)+(cz-z)*(cz-z)) - r;
|
||||
// Assign the minimum distance
|
||||
if (distance < Distance[n]) Distance[n] = distance;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Map the distance to lattice units
|
||||
for (n=0; n<N; n++) Distance[n] = Distance[n]/hx;
|
||||
}
|
||||
|
||||
inline void WriteLocalSolidID(char *FILENAME, char *ID, int N)
|
||||
{
|
||||
char value;
|
||||
ofstream File(FILENAME,ios::binary);
|
||||
for (int n=0; n<N; n++){
|
||||
value = ID[n];
|
||||
File.write((char*) &value, sizeof(value));
|
||||
}
|
||||
File.close();
|
||||
}
|
||||
|
||||
inline void WriteLocalSolidDistance(char *FILENAME, double *Distance, int N)
|
||||
{
|
||||
double value;
|
||||
ofstream File(FILENAME,ios::binary);
|
||||
for (int n=0; n<N; n++){
|
||||
value = Distance[n];
|
||||
File.write((char*) &value, sizeof(value));
|
||||
}
|
||||
File.close();
|
||||
}
|
||||
|
||||
|
||||
inline void WriteCheckpoint(const char *FILENAME, const double *cDen, const double *cfq, int Np)
|
||||
{
|
||||
int q,n;
|
||||
double value;
|
||||
ofstream File(FILENAME,ios::binary);
|
||||
for (n=0; n<Np; n++){
|
||||
// Write the two density values
|
||||
value = cDen[n];
|
||||
File.write((char*) &value, sizeof(value));
|
||||
value = cDen[Np+n];
|
||||
File.write((char*) &value, sizeof(value));
|
||||
// Write the even distributions
|
||||
for (q=0; q<19; q++){
|
||||
value = cfq[q*Np+n];
|
||||
File.write((char*) &value, sizeof(value));
|
||||
}
|
||||
}
|
||||
File.close();
|
||||
|
||||
}
|
||||
|
||||
inline void ReadCheckpoint(char *FILENAME, double *cDen, double *cfq, int Np)
|
||||
{
|
||||
int q=0, n=0;
|
||||
double value=0;
|
||||
ifstream File(FILENAME,ios::binary);
|
||||
for (n=0; n<Np; n++){
|
||||
// Write the two density values
|
||||
File.read((char*) &value, sizeof(value));
|
||||
cDen[n] = value;
|
||||
File.read((char*) &value, sizeof(value));
|
||||
cDen[Np+n] = value;
|
||||
// Read the even distributions
|
||||
for (q=0; q<19; q++){
|
||||
File.read((char*) &value, sizeof(value));
|
||||
cfq[q*Np+n] = value;
|
||||
}
|
||||
}
|
||||
File.close();
|
||||
}
|
||||
|
||||
inline void ReadBinaryFile(char *FILENAME, double *Data, int N)
|
||||
{
|
||||
int n;
|
||||
double value;
|
||||
ifstream File(FILENAME,ios::binary);
|
||||
if (File.good()){
|
||||
for (n=0; n<N; n++){
|
||||
// Write the two density values
|
||||
File.read((char*) &value, sizeof(value));
|
||||
Data[n] = value;
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (n=0; n<N; n++) Data[n] = 1.2e-34;
|
||||
}
|
||||
File.close();
|
||||
|
||||
}
|
||||
void ReadBinaryFile(char *FILENAME, double *Data, int N);
|
||||
|
||||
|
||||
#endif
|
||||
|
226
common/Units.cpp
Normal file
226
common/Units.cpp
Normal file
@ -0,0 +1,226 @@
|
||||
#include "common/Units.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
|
||||
|
||||
constexpr double Units::d_pow10[22];
|
||||
constexpr char Units::d_prefixSymbol[];
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Constructors *
|
||||
********************************************************************/
|
||||
Units::Units() : d_prefix( UnitPrefix::unknown ), d_unit( UnitValue::unknown ) {}
|
||||
Units::Units( UnitPrefix p, UnitValue u ) : d_prefix( p ), d_unit( u ) {}
|
||||
Units::Units( const std::string& unit )
|
||||
: d_prefix( UnitPrefix::unknown ), d_unit( UnitValue::unknown )
|
||||
{
|
||||
// Parse the string to get it into a more friendly format
|
||||
auto tmp = unit;
|
||||
tmp.erase( std::remove( tmp.begin(), tmp.end(), ' ' ), tmp.end() );
|
||||
// Check if the character '-' is present indicating a seperation between the prefix and unit
|
||||
size_t index = tmp.find( '-' );
|
||||
if ( index != std::string::npos ) {
|
||||
d_prefix = getUnitPrefix( tmp.substr( 0, index ) );
|
||||
d_unit = getUnitValue( tmp.substr( index + 1 ) );
|
||||
} else {
|
||||
if ( tmp.size() <= 1 ) {
|
||||
d_prefix = UnitPrefix::none;
|
||||
d_unit = getUnitValue( tmp );
|
||||
} else if ( tmp.substr( 0, 2 ) == "da" ) {
|
||||
d_prefix = UnitPrefix::deca;
|
||||
d_unit = getUnitValue( tmp.substr( 2 ) );
|
||||
} else {
|
||||
d_prefix = getUnitPrefix( tmp.substr( 0, 1 ) );
|
||||
d_unit = getUnitValue( tmp.substr( 1 ) );
|
||||
if ( d_prefix == UnitPrefix::unknown || d_unit == UnitValue::unknown ) {
|
||||
d_prefix = UnitPrefix::none;
|
||||
d_unit = getUnitValue( tmp );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Get prefix *
|
||||
********************************************************************/
|
||||
Units::UnitPrefix Units::getUnitPrefix( const std::string& str ) noexcept
|
||||
{
|
||||
Units::UnitPrefix value = UnitPrefix::unknown;
|
||||
if ( str.empty() ) {
|
||||
value = UnitPrefix::none;
|
||||
} else if ( str == "yotta" || str == "Y" ) {
|
||||
value = UnitPrefix::yotta;
|
||||
} else if ( str == "zetta" || str == "Z" ) {
|
||||
value = UnitPrefix::zetta;
|
||||
} else if ( str == "exa" || str == "E" ) {
|
||||
value = UnitPrefix::exa;
|
||||
} else if ( str == "peta" || str == "P" ) {
|
||||
value = UnitPrefix::peta;
|
||||
} else if ( str == "tera" || str == "T" ) {
|
||||
value = UnitPrefix::tera;
|
||||
} else if ( str == "giga" || str == "G" ) {
|
||||
value = UnitPrefix::giga;
|
||||
} else if ( str == "mega" || str == "M" ) {
|
||||
value = UnitPrefix::mega;
|
||||
} else if ( str == "kilo" || str == "k" ) {
|
||||
value = UnitPrefix::kilo;
|
||||
} else if ( str == "hecto" || str == "h" ) {
|
||||
value = UnitPrefix::hecto;
|
||||
} else if ( str == "deca" || str == "da" ) {
|
||||
value = UnitPrefix::deca;
|
||||
} else if ( str == "deci" || str == "d" ) {
|
||||
value = UnitPrefix::deci;
|
||||
} else if ( str == "centi" || str == "c" ) {
|
||||
value = UnitPrefix::centi;
|
||||
} else if ( str == "milli" || str == "m" ) {
|
||||
value = UnitPrefix::milli;
|
||||
} else if ( str == "micro" || str == "u" ) {
|
||||
value = UnitPrefix::micro;
|
||||
} else if ( str == "nano" || str == "n" ) {
|
||||
value = UnitPrefix::nano;
|
||||
} else if ( str == "pico" || str == "p" ) {
|
||||
value = UnitPrefix::pico;
|
||||
} else if ( str == "femto" || str == "f" ) {
|
||||
value = UnitPrefix::femto;
|
||||
} else if ( str == "atto" || str == "a" ) {
|
||||
value = UnitPrefix::atto;
|
||||
} else if ( str == "zepto" || str == "z" ) {
|
||||
value = UnitPrefix::zepto;
|
||||
} else if ( str == "yocto" || str == "y" ) {
|
||||
value = UnitPrefix::yocto;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Get unit value *
|
||||
********************************************************************/
|
||||
Units::UnitValue Units::getUnitValue( const std::string& str ) noexcept
|
||||
{
|
||||
Units::UnitValue value = UnitValue::unknown;
|
||||
if ( str == "meter" || str == "m" ) {
|
||||
value = UnitValue::meter;
|
||||
} else if ( str == "gram" || str == "g" ) {
|
||||
value = UnitValue::gram;
|
||||
} else if ( str == "second" || str == "s" ) {
|
||||
value = UnitValue::second;
|
||||
} else if ( str == "ampere" || str == "A" ) {
|
||||
value = UnitValue::ampere;
|
||||
} else if ( str == "kelvin" || str == "K" ) {
|
||||
value = UnitValue::kelvin;
|
||||
} else if ( str == "joule" || str == "J" ) {
|
||||
value = UnitValue::joule;
|
||||
} else if ( str == "ergs" || str == "erg" ) {
|
||||
value = UnitValue::erg;
|
||||
} else if ( str == "degree" || str == "degrees" ) {
|
||||
value = UnitValue::degree;
|
||||
} else if ( str == "radian" || str == "radians" ) {
|
||||
value = UnitValue::radian;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Get unit type *
|
||||
********************************************************************/
|
||||
Units::UnitType Units::getUnitType( UnitValue u ) noexcept
|
||||
{
|
||||
switch ( u ) {
|
||||
case UnitValue::meter:
|
||||
return UnitType::length;
|
||||
case UnitValue::gram:
|
||||
return UnitType::mass;
|
||||
case UnitValue::second:
|
||||
return UnitType::time;
|
||||
case UnitValue::ampere:
|
||||
return UnitType::current;
|
||||
case UnitValue::kelvin:
|
||||
return UnitType::temperature;
|
||||
case UnitValue::joule:
|
||||
case UnitValue::erg:
|
||||
return UnitType::energy;
|
||||
case UnitValue::degree:
|
||||
case UnitValue::radian:
|
||||
return UnitType::angle;
|
||||
default:
|
||||
return UnitType::unknown;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Convert to another unit system *
|
||||
********************************************************************/
|
||||
double Units::convert( const Units& rhs ) const noexcept
|
||||
{
|
||||
if ( this->operator==( rhs ) )
|
||||
return 1;
|
||||
// Convert the prefix
|
||||
double cp = convert( d_prefix ) / convert( rhs.d_prefix );
|
||||
if ( d_unit == rhs.d_unit )
|
||||
return cp; // Only need to convert prefix
|
||||
// Convert the unit
|
||||
if ( getUnitType( d_unit ) != getUnitType( rhs.d_unit ) )
|
||||
return 0; // Invalid conversion
|
||||
double cu = 0;
|
||||
if ( d_unit == UnitValue::joule && rhs.d_unit == UnitValue::erg )
|
||||
cu = 1e7;
|
||||
else if ( d_unit == UnitValue::erg && rhs.d_unit == UnitValue::joule )
|
||||
cu = 1e-7;
|
||||
else if ( d_unit == UnitValue::degree && rhs.d_unit == UnitValue::radian )
|
||||
cu = 0.017453292519943;
|
||||
else if ( d_unit == UnitValue::radian && rhs.d_unit == UnitValue::degree )
|
||||
cu = 57.295779513082323;
|
||||
// Return the total conversion
|
||||
return cp * cu;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Write a string for the units *
|
||||
********************************************************************/
|
||||
std::string Units::str() const
|
||||
{
|
||||
ASSERT( !isNull() );
|
||||
return std::string( str( d_prefix ).data() ) + str( d_unit );
|
||||
}
|
||||
std::array<char, 3> Units::str( UnitPrefix p ) noexcept
|
||||
{
|
||||
std::array<char, 3> str;
|
||||
str[0] = d_prefixSymbol[static_cast<int8_t>( p )];
|
||||
str[1] = 0;
|
||||
str[2] = 0;
|
||||
if ( p == UnitPrefix::deca )
|
||||
str[1] = 'a';
|
||||
return str;
|
||||
}
|
||||
std::string Units::str( UnitValue u )
|
||||
{
|
||||
if ( u == UnitValue::meter ) {
|
||||
return "m";
|
||||
} else if ( u == UnitValue::gram ) {
|
||||
return "g";
|
||||
} else if ( u == UnitValue::second ) {
|
||||
return "s";
|
||||
} else if ( u == UnitValue::ampere ) {
|
||||
return "A";
|
||||
} else if ( u == UnitValue::kelvin ) {
|
||||
return "K";
|
||||
} else if ( u == UnitValue::joule ) {
|
||||
return "J";
|
||||
} else if ( u == UnitValue::erg ) {
|
||||
return "erg";
|
||||
} else if ( u == UnitValue::degree ) {
|
||||
return "degree";
|
||||
} else if ( u == UnitValue::radian ) {
|
||||
return "radian";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
140
common/Units.h
Normal file
140
common/Units.h
Normal file
@ -0,0 +1,140 @@
|
||||
#ifndef included_Units
|
||||
#define included_Units
|
||||
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
//! Unit system class
|
||||
class Units final
|
||||
{
|
||||
public:
|
||||
//! Enum to hold prefix
|
||||
enum class UnitPrefix : int8_t {
|
||||
yocto = 0,
|
||||
zepto = 1,
|
||||
atto = 2,
|
||||
femto = 3,
|
||||
pico = 4,
|
||||
nano = 5,
|
||||
micro = 6,
|
||||
milli = 7,
|
||||
centi = 8,
|
||||
deci = 9,
|
||||
none = 10,
|
||||
deca = 11,
|
||||
hecto = 12,
|
||||
kilo = 13,
|
||||
mega = 14,
|
||||
giga = 15,
|
||||
tera = 16,
|
||||
peta = 17,
|
||||
exa = 18,
|
||||
zetta = 19,
|
||||
yotta = 20,
|
||||
unknown = 21
|
||||
};
|
||||
|
||||
//! Enum to unit type
|
||||
enum class UnitType : uint8_t {
|
||||
length,
|
||||
mass,
|
||||
time,
|
||||
current,
|
||||
temperature,
|
||||
energy,
|
||||
angle,
|
||||
unknown
|
||||
};
|
||||
|
||||
//! Enum to hold unit
|
||||
enum class UnitValue : uint8_t {
|
||||
meter,
|
||||
gram,
|
||||
second,
|
||||
ampere,
|
||||
kelvin,
|
||||
joule,
|
||||
erg,
|
||||
degree,
|
||||
radian,
|
||||
unknown
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
Units();
|
||||
|
||||
//! Constructor
|
||||
explicit Units( const std::string& unit );
|
||||
|
||||
//! Constructor
|
||||
explicit Units( UnitPrefix, UnitValue );
|
||||
|
||||
//! Get the prefix
|
||||
inline UnitPrefix getPrefix() const noexcept { return d_prefix; }
|
||||
|
||||
//! Get the unit
|
||||
inline UnitValue getUnit() const noexcept { return d_unit; }
|
||||
|
||||
//! Get the unit
|
||||
inline UnitType getUnitType() const noexcept { return getUnitType( d_unit ); }
|
||||
|
||||
//! Get the unit
|
||||
static UnitType getUnitType( UnitValue ) noexcept;
|
||||
|
||||
//! Get the prefix from a string
|
||||
static UnitPrefix getUnitPrefix( const std::string& ) noexcept;
|
||||
|
||||
//! Get the unit value from a string
|
||||
static UnitValue getUnitValue( const std::string& ) noexcept;
|
||||
|
||||
//! Convert to the given unit system
|
||||
double convert( const Units& ) const noexcept;
|
||||
|
||||
//! Convert a prefix to a scalar
|
||||
static inline double convert( UnitPrefix x ) noexcept
|
||||
{
|
||||
return d_pow10[static_cast<int8_t>( x )];
|
||||
}
|
||||
|
||||
//! Get a string representation of the units
|
||||
std::string str() const;
|
||||
|
||||
//! Get a string representation for the prefix
|
||||
static std::array<char, 3> str( UnitPrefix ) noexcept;
|
||||
|
||||
//! Get a string representation for the unit value
|
||||
static std::string str( UnitValue );
|
||||
|
||||
//! Operator ==
|
||||
inline bool operator==( const Units& rhs ) const noexcept
|
||||
{
|
||||
return d_prefix == rhs.d_prefix && d_unit == rhs.d_unit;
|
||||
}
|
||||
|
||||
//! Operator !=
|
||||
inline bool operator!=( const Units& rhs ) const noexcept
|
||||
{
|
||||
return d_prefix != rhs.d_prefix || d_unit != rhs.d_unit;
|
||||
}
|
||||
|
||||
//! Check if unit is null
|
||||
bool isNull() const { return d_prefix == UnitPrefix::unknown || d_unit == UnitValue::unknown; }
|
||||
|
||||
protected:
|
||||
UnitPrefix d_prefix;
|
||||
UnitValue d_unit;
|
||||
|
||||
private:
|
||||
constexpr static double d_pow10[22] = { 1e-24, 1e-21, 1e-18, 1e-15, 1e-12, 1e-9, 1e-6, 1e-3,
|
||||
1e-2, 0.1, 1, 10, 100, 1000, 1e6, 1e9, 1e12, 1e15, 1e18, 1e21, 1e24, 0 };
|
||||
constexpr static char d_prefixSymbol[] = "yzafpnumcd\0dhkMGTPEZYu";
|
||||
};
|
||||
|
||||
#endif
|
@ -9,7 +9,35 @@
|
||||
#include "common/ScaLBL.h"
|
||||
#include "common/MPI_Helpers.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
std::shared_ptr<Database> loadInputs( int nprocs )
|
||||
{
|
||||
auto db = std::make_shared<Database>( "Domain.in" );
|
||||
const int dim = 50;
|
||||
db->putScalar<int>( "BC", 0 );
|
||||
if ( nprocs == 1 ){
|
||||
db->putVector<int>( "nproc", { 1, 1, 1 } );
|
||||
db->putVector<int>( "n", { 3, 1, 1 } );
|
||||
db->putScalar<int>( "nspheres", 0 );
|
||||
db->putVector<double>( "L", { 1, 1, 1 } );
|
||||
} else if ( nprocs == 2 ) {
|
||||
db->putVector<int>( "nproc", { 2, 1, 1 } );
|
||||
db->putVector<int>( "n", { dim, dim, dim } );
|
||||
db->putScalar<int>( "nspheres", 0 );
|
||||
db->putVector<double>( "L", { 1, 1, 1 } );
|
||||
} else if ( nprocs == 4 ) {
|
||||
db->putVector<int>( "nproc", { 2, 2, 1 } );
|
||||
db->putVector<int>( "n", { dim, dim, dim } );
|
||||
db->putScalar<int>( "nspheres", 0 );
|
||||
db->putVector<double>( "L", { 1, 1, 1 } );
|
||||
} else if (nprocs==8){
|
||||
db->putVector<int>( "nproc", { 2, 2, 2 } );
|
||||
db->putVector<int>( "n", { dim, dim, dim } );
|
||||
db->putScalar<int>( "nspheres", 0 );
|
||||
db->putVector<double>( "L", { 1, 1, 1 } );
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
|
||||
//***************************************************************************************
|
||||
@ -26,11 +54,6 @@ int main(int argc, char **argv)
|
||||
MPI_Comm_size(comm,&nprocs);
|
||||
int check;
|
||||
{
|
||||
// parallel domain size (# of sub-domains)
|
||||
int nprocx,nprocy,nprocz;
|
||||
int iproc,jproc,kproc;
|
||||
|
||||
|
||||
if (rank == 0){
|
||||
printf("********************************************************\n");
|
||||
printf("Running Color Model: TestColor \n");
|
||||
@ -43,11 +66,8 @@ int main(int argc, char **argv)
|
||||
int timestepMax, interval;
|
||||
double Fx,Fy,Fz,tol;
|
||||
// Domain variables
|
||||
double Lx,Ly,Lz;
|
||||
int nspheres;
|
||||
int Nx,Ny,Nz;
|
||||
int i,j,k,n;
|
||||
int dim = 50;
|
||||
|
||||
//if (rank == 0) printf("dim=%d\n",dim);
|
||||
int timestep = 1;
|
||||
int timesteps = 100;
|
||||
@ -78,90 +98,25 @@ int main(int argc, char **argv)
|
||||
flux = 10.f;
|
||||
dout=1.f;
|
||||
|
||||
if (rank==0){
|
||||
//.......................................................................
|
||||
// Reading the domain information file
|
||||
//.......................................................................
|
||||
ifstream domain("Domain.in");
|
||||
if (domain.good()){
|
||||
domain >> nprocx;
|
||||
domain >> nprocy;
|
||||
domain >> nprocz;
|
||||
domain >> Nx;
|
||||
domain >> Ny;
|
||||
domain >> Nz;
|
||||
domain >> nspheres;
|
||||
domain >> Lx;
|
||||
domain >> Ly;
|
||||
domain >> Lz;
|
||||
}
|
||||
else if (nprocs==1){
|
||||
nprocx=nprocy=nprocz=1;
|
||||
Nx=3; Ny = 1;
|
||||
Nz = 1;
|
||||
nspheres=0;
|
||||
Lx=Ly=Lz=1;
|
||||
}
|
||||
else if (nprocs==2){
|
||||
nprocx=2; nprocy=1;
|
||||
nprocz=1;
|
||||
Nx=Ny=Nz=dim;
|
||||
Nx = dim; Ny = dim; Nz = dim;
|
||||
nspheres=0;
|
||||
Lx=Ly=Lz=1;
|
||||
}
|
||||
else if (nprocs==4){
|
||||
nprocx=nprocy=2;
|
||||
nprocz=1;
|
||||
Nx=Ny=Nz=dim;
|
||||
nspheres=0;
|
||||
Lx=Ly=Lz=1;
|
||||
}
|
||||
else if (nprocs==8){
|
||||
nprocx=nprocy=nprocz=2;
|
||||
Nx=Ny=Nz=dim;
|
||||
nspheres=0;
|
||||
Lx=Ly=Lz=1;
|
||||
}
|
||||
//.......................................................................
|
||||
}
|
||||
// **************************************************************
|
||||
// Broadcast simulation parameters from rank 0 to all other procs
|
||||
MPI_Barrier(comm);
|
||||
//.................................................
|
||||
MPI_Bcast(&Nx,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Ny,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Nz,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocx,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocy,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocz,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nspheres,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Lx,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Bcast(&Ly,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Bcast(&Lz,1,MPI_DOUBLE,0,comm);
|
||||
//.................................................
|
||||
MPI_Barrier(comm);
|
||||
// **************************************************************
|
||||
// **************************************************************
|
||||
|
||||
if (nprocs != nprocx*nprocy*nprocz){
|
||||
printf("nprocx = %i \n",nprocx);
|
||||
printf("nprocy = %i \n",nprocy);
|
||||
printf("nprocz = %i \n",nprocz);
|
||||
INSIST(nprocs == nprocx*nprocy*nprocz,"Fatal error in processor count!");
|
||||
}
|
||||
// Load inputs
|
||||
auto db = loadInputs( nprocs );
|
||||
int Nx = db->getVector<int>( "n" )[0];
|
||||
int Ny = db->getVector<int>( "n" )[1];
|
||||
int Nz = db->getVector<int>( "n" )[2];
|
||||
int nprocx = db->getVector<int>( "nproc" )[0];
|
||||
int nprocy = db->getVector<int>( "nproc" )[1];
|
||||
int nprocz = db->getVector<int>( "nproc" )[2];
|
||||
|
||||
if (rank==0){
|
||||
printf("********************************************************\n");
|
||||
printf("Sub-domain size = %i x %i x %i\n",Nx,Ny,Nz);
|
||||
printf("********************************************************\n");
|
||||
}
|
||||
MPI_Barrier(comm);
|
||||
|
||||
double iVol_global = 1.0/Nx/Ny/Nz/nprocx/nprocy/nprocz;
|
||||
int BoundaryCondition=0;
|
||||
|
||||
Domain Dm(Nx,Ny,Nz,rank,nprocx,nprocy,nprocz,Lx,Ly,Lz,BoundaryCondition);
|
||||
|
||||
Domain Dm(db);
|
||||
|
||||
Nx += 2;
|
||||
Ny += 2;
|
||||
@ -186,9 +141,9 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
kproc = rank/(nprocx*nprocy);
|
||||
jproc = (rank-nprocx*nprocy*kproc)/nprocx;
|
||||
iproc = rank-nprocx*nprocy*kproc-nprocx*jproc;
|
||||
int kproc = rank/(nprocx*nprocy);
|
||||
int jproc = (rank-nprocx*nprocy*kproc)/nprocx;
|
||||
int iproc = rank-nprocx*nprocy*kproc-nprocx*jproc;
|
||||
printf("rank=%i, %i,%i,%i \n",rank,iproc,jproc,kproc);
|
||||
// Initialize a square tube
|
||||
for (k=1;k<Nz-1;k++){
|
||||
|
@ -11,6 +11,36 @@
|
||||
using namespace std;
|
||||
|
||||
|
||||
std::shared_ptr<Database> loadInputs( int nprocs )
|
||||
{
|
||||
auto db = std::make_shared<Database>( "Domain.in" );
|
||||
const int dim = 50;
|
||||
db->putScalar<int>( "BC", 0 );
|
||||
if ( nprocs == 1 ){
|
||||
db->putVector<int>( "nproc", { 1, 1, 1 } );
|
||||
db->putVector<int>( "n", { 3, 1, 1 } );
|
||||
db->putScalar<int>( "nspheres", 0 );
|
||||
db->putVector<double>( "L", { 1, 1, 1 } );
|
||||
} else if ( nprocs == 2 ) {
|
||||
db->putVector<int>( "nproc", { 2, 1, 1 } );
|
||||
db->putVector<int>( "n", { dim, dim, dim } );
|
||||
db->putScalar<int>( "nspheres", 0 );
|
||||
db->putVector<double>( "L", { 1, 1, 1 } );
|
||||
} else if ( nprocs == 4 ) {
|
||||
db->putVector<int>( "nproc", { 2, 2, 1 } );
|
||||
db->putVector<int>( "n", { dim, dim, dim } );
|
||||
db->putScalar<int>( "nspheres", 0 );
|
||||
db->putVector<double>( "L", { 1, 1, 1 } );
|
||||
} else if (nprocs==8){
|
||||
db->putVector<int>( "nproc", { 2, 2, 2 } );
|
||||
db->putVector<int>( "n", { dim, dim, dim } );
|
||||
db->putScalar<int>( "nspheres", 0 );
|
||||
db->putVector<double>( "L", { 1, 1, 1 } );
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
|
||||
extern void GlobalFlipScaLBL_D3Q19_Init(double *dist, IntArray Map, int Np, int Nx, int Ny, int Nz,
|
||||
int iproc, int jproc, int kproc, int nprocx, int nprocy, int nprocz)
|
||||
{
|
||||
@ -176,88 +206,13 @@ int main(int argc, char **argv)
|
||||
int timestepMax, interval;
|
||||
double tau,Fx,Fy,Fz,tol;
|
||||
// Domain variables
|
||||
double Lx,Ly,Lz;
|
||||
int nspheres;
|
||||
int Nx,Ny,Nz;
|
||||
int i,j,k,n;
|
||||
|
||||
if (rank==0){
|
||||
//.......................................................................
|
||||
// Reading the domain information file
|
||||
//.......................................................................
|
||||
ifstream domain("Domain.in");
|
||||
if (domain.good()){
|
||||
domain >> nprocx;
|
||||
domain >> nprocy;
|
||||
domain >> nprocz;
|
||||
domain >> Nx;
|
||||
domain >> Ny;
|
||||
domain >> Nz;
|
||||
domain >> nspheres;
|
||||
domain >> Lx;
|
||||
domain >> Ly;
|
||||
domain >> Lz;
|
||||
}
|
||||
else if (nprocs==1){
|
||||
nprocx=nprocy=nprocz=1;
|
||||
Nx=Ny=Nz=50;
|
||||
nspheres=0;
|
||||
Lx=Ly=Lz=1;
|
||||
}
|
||||
else if (nprocs==2){
|
||||
nprocx=nprocy=1;
|
||||
nprocz=2;
|
||||
Nx=Ny=Nz=50;
|
||||
nspheres=0;
|
||||
Lx=Ly=Lz=1;
|
||||
}
|
||||
else if (nprocs==4){
|
||||
nprocx=nprocy=2;
|
||||
nprocz=1;
|
||||
Nx=Ny=Nz=50;
|
||||
nspheres=0;
|
||||
Lx=Ly=Lz=1;
|
||||
}
|
||||
else if (nprocs==8){
|
||||
nprocx=nprocy=nprocz=2;
|
||||
Nx=Ny=Nz=50;
|
||||
nspheres=0;
|
||||
Lx=Ly=Lz=1;
|
||||
}
|
||||
//.......................................................................
|
||||
}
|
||||
// **************************************************************
|
||||
// Broadcast simulation parameters from rank 0 to all other procs
|
||||
MPI_Barrier(comm);
|
||||
//.................................................
|
||||
MPI_Bcast(&Nx,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Ny,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Nz,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nBlocks,1,MPI_UNSIGNED,0,comm);
|
||||
MPI_Bcast(&nthreads,1,MPI_UNSIGNED,0,comm);
|
||||
MPI_Bcast(×tepMax,1,MPI_INT,0,comm);
|
||||
|
||||
MPI_Bcast(&Nx,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Ny,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Nz,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocx,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocy,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocz,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nspheres,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Lx,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Bcast(&Ly,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Bcast(&Lz,1,MPI_DOUBLE,0,comm);
|
||||
//.................................................
|
||||
MPI_Barrier(comm);
|
||||
// **************************************************************
|
||||
// **************************************************************
|
||||
|
||||
if (nprocs != nprocx*nprocy*nprocz){
|
||||
printf("nprocx = %i \n",nprocx);
|
||||
printf("nprocy = %i \n",nprocy);
|
||||
printf("nprocz = %i \n",nprocz);
|
||||
INSIST(nprocs == nprocx*nprocy*nprocz,"Fatal error in processor count!");
|
||||
}
|
||||
// Load inputs
|
||||
auto db = loadInputs( nprocs );
|
||||
int Nx = db->getVector<int>( "n" )[0];
|
||||
int Ny = db->getVector<int>( "n" )[1];
|
||||
int Nz = db->getVector<int>( "n" )[2];
|
||||
|
||||
if (rank==0){
|
||||
printf("********************************************************\n");
|
||||
@ -272,8 +227,9 @@ int main(int argc, char **argv)
|
||||
iproc = rank-nprocx*nprocy*kproc-nprocz*jproc;
|
||||
|
||||
double iVol_global = 1.0/Nx/Ny/Nz/nprocx/nprocy/nprocz;
|
||||
int BoundaryCondition=0;
|
||||
Domain Dm(Nx,Ny,Nz,rank,nprocx,nprocy,nprocz,Lx,Ly,Lz,BoundaryCondition);
|
||||
|
||||
Domain Dm(db);
|
||||
|
||||
|
||||
InitializeRanks( rank, nprocx, nprocy, nprocz, iproc, jproc, kproc,
|
||||
rank_x, rank_y, rank_z, rank_X, rank_Y, rank_Z,
|
||||
|
@ -30,6 +30,22 @@ extern void PrintNeighborList(int * neighborList, int Np, int rank) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<Database> loadInputs( int nprocs )
|
||||
{
|
||||
auto db = std::make_shared<Database>( "Domain.in" );
|
||||
const int dim = 50;
|
||||
db->putScalar<int>( "BC", 0 );
|
||||
if ( nprocs == 1 ){
|
||||
db->putVector<int>( "nproc", { 1, 1, 1 } );
|
||||
db->putVector<int>( "n", { 3, 3, 3 } );
|
||||
db->putScalar<int>( "nspheres", 0 );
|
||||
db->putVector<double>( "L", { 1, 1, 1 } );
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
|
||||
//***************************************************************************************
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
@ -45,7 +61,6 @@ int main(int argc, char **argv)
|
||||
int check;
|
||||
{
|
||||
// parallel domain size (# of sub-domains)
|
||||
int nprocx,nprocy,nprocz;
|
||||
int iproc,jproc,kproc;
|
||||
|
||||
|
||||
@ -61,9 +76,6 @@ int main(int argc, char **argv)
|
||||
int timestepMax, interval;
|
||||
double tau,Fx,Fy,Fz,tol;
|
||||
// Domain variables
|
||||
double Lx,Ly,Lz;
|
||||
int nspheres;
|
||||
int Nx,Ny,Nz;
|
||||
int i,j,k,n;
|
||||
int dim = 3; if (rank == 0) printf("dim=%d\n",dim);
|
||||
int timestep = 0;
|
||||
@ -76,58 +88,15 @@ int main(int argc, char **argv)
|
||||
Fx = Fy = 1.0;
|
||||
Fz = 1.0;
|
||||
|
||||
if (rank==0){
|
||||
//.......................................................................
|
||||
// Reading the domain information file
|
||||
//.......................................................................
|
||||
ifstream domain("Domain.in");
|
||||
if (domain.good()){
|
||||
printf("domain.good == true \n");
|
||||
domain >> nprocx;
|
||||
domain >> nprocy;
|
||||
domain >> nprocz;
|
||||
domain >> Nx;
|
||||
domain >> Ny;
|
||||
domain >> Nz;
|
||||
domain >> nspheres;
|
||||
domain >> Lx;
|
||||
domain >> Ly;
|
||||
domain >> Lz;
|
||||
}
|
||||
else if (nprocs==1){
|
||||
nprocx=nprocy=nprocz=1;
|
||||
Nx=3; Ny = 3;
|
||||
Nz = 3;
|
||||
nspheres=0;
|
||||
Lx=Ly=Lz=1;
|
||||
}
|
||||
//.......................................................................
|
||||
}
|
||||
// **************************************************************
|
||||
// Broadcast simulation parameters from rank 0 to all other procs
|
||||
MPI_Barrier(comm);
|
||||
//.................................................
|
||||
MPI_Bcast(&Nx,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Ny,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Nz,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocx,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocy,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocz,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nspheres,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Lx,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Bcast(&Ly,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Bcast(&Lz,1,MPI_DOUBLE,0,comm);
|
||||
//.................................................
|
||||
MPI_Barrier(comm);
|
||||
// **************************************************************
|
||||
// **************************************************************
|
||||
|
||||
if (nprocs != nprocx*nprocy*nprocz){
|
||||
printf("nprocx = %i \n",nprocx);
|
||||
printf("nprocy = %i \n",nprocy);
|
||||
printf("nprocz = %i \n",nprocz);
|
||||
INSIST(nprocs == nprocx*nprocy*nprocz,"Fatal error in processor count!");
|
||||
}
|
||||
// Load inputs
|
||||
auto db = loadInputs( nprocs );
|
||||
int Nx = db->getVector<int>( "n" )[0];
|
||||
int Ny = db->getVector<int>( "n" )[1];
|
||||
int Nz = db->getVector<int>( "n" )[2];
|
||||
int nprocx = db->getVector<int>( "nproc" )[0];
|
||||
int nprocy = db->getVector<int>( "nproc" )[1];
|
||||
int nprocz = db->getVector<int>( "nproc" )[2];
|
||||
|
||||
if (rank==0){
|
||||
printf("********************************************************\n");
|
||||
@ -150,9 +119,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
double iVol_global = 1.0/Nx/Ny/Nz/nprocx/nprocy/nprocz;
|
||||
int BoundaryCondition=0;
|
||||
|
||||
Domain Dm(Nx,Ny,Nz,rank,nprocx,nprocy,nprocz,Lx,Ly,Lz,BoundaryCondition);
|
||||
Domain Dm(db);
|
||||
|
||||
Nx += 2;
|
||||
Ny += 2;
|
||||
|
@ -15,6 +15,20 @@
|
||||
#define SPEED -1
|
||||
#define PI 3.14159
|
||||
|
||||
|
||||
std::shared_ptr<Database> loadInputs( int nprocs )
|
||||
{
|
||||
auto db = std::make_shared<Database>( );
|
||||
const int dim = 50;
|
||||
db->putScalar<int>( "BC", 0 );
|
||||
db->putVector<int>( "nproc", { 1, 1, 1 } );
|
||||
db->putVector<int>( "n", { N, N, N } );
|
||||
db->putScalar<int>( "nspheres", 0 );
|
||||
db->putVector<double>( "L", { 1, 1, 1 } );
|
||||
return db;
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
// Initialize MPI
|
||||
@ -24,16 +38,11 @@ int main (int argc, char *argv[])
|
||||
MPI_Comm_rank(comm,&rank);
|
||||
MPI_Comm_size(comm,&nprocs);
|
||||
|
||||
int npx,npy,npz;
|
||||
int i,j,k,n;
|
||||
int Nx,Ny,Nz;
|
||||
double Lx,Ly,Lz;
|
||||
Nx=Ny=Nz=N;
|
||||
npx=npy=npz=1;
|
||||
Lx=Ly=Lz=1.0;
|
||||
int BC=0; // periodic boundary condition
|
||||
// Load inputs
|
||||
auto db = loadInputs( nprocs );
|
||||
|
||||
Domain Dm(Nx,Ny,Nz,rank,npx,npy,npz,Lx,Ly,Lz,BC);
|
||||
Domain Dm(db);
|
||||
|
||||
for (i=0; i<Dm.Nx*Dm.Ny*Dm.Nz; i++) Dm.id[i] = 1;
|
||||
|
||||
@ -42,9 +51,9 @@ int main (int argc, char *argv[])
|
||||
TwoPhase Averages(Dm);
|
||||
int timestep=0;
|
||||
|
||||
Nx = Dm.Nx;
|
||||
Ny = Dm.Ny;
|
||||
Nz = Dm.Nz;
|
||||
int Nx = Dm.Nx;
|
||||
int Ny = Dm.Ny;
|
||||
int Nz = Dm.Nz;
|
||||
|
||||
double Cx,Cy,Cz;
|
||||
double dist1,dist2;
|
||||
|
@ -9,7 +9,35 @@
|
||||
#include "common/ScaLBL.h"
|
||||
#include "common/MPI_Helpers.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool exists( const std::string& filename )
|
||||
{
|
||||
ifstream domain( filename );
|
||||
return domain.good();
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<Database> loadInputs( int nprocs )
|
||||
{
|
||||
const int dim = 12;
|
||||
std::shared_ptr<Database> db;
|
||||
if ( exists( "Domain.in" ) ) {
|
||||
db = std::make_shared<Database>( "Domain.in" );
|
||||
} else if (nprocs==1) {
|
||||
db->putVector<int>( "nproc", { 1, 1, 1 } );
|
||||
db->putVector<int>( "n", { dim, dim, dim } );
|
||||
db->putScalar<int>( "nspheres", 0 );
|
||||
db->putVector<double>( "L", { 1, 1, 1 } );
|
||||
} else if (nprocs==2) {
|
||||
db->putVector<int>( "nproc", { 1, 1, 1 } );
|
||||
db->putVector<int>( "n", { dim/2, dim/2, dim/2 } );
|
||||
db->putScalar<int>( "nspheres", 0 );
|
||||
db->putVector<double>( "L", { 1, 1, 1 } );
|
||||
}
|
||||
db->putScalar<int>( "BC", 0 );
|
||||
return db;
|
||||
}
|
||||
|
||||
|
||||
//***************************************************************************************
|
||||
int main(int argc, char **argv)
|
||||
@ -25,11 +53,6 @@ int main(int argc, char **argv)
|
||||
MPI_Comm_size(comm,&nprocs);
|
||||
int check;
|
||||
{
|
||||
// parallel domain size (# of sub-domains)
|
||||
int nprocx,nprocy,nprocz;
|
||||
int iproc,jproc,kproc;
|
||||
|
||||
|
||||
if (rank == 0){
|
||||
printf("********************************************************\n");
|
||||
printf("Running Unit Test: TestPoiseuille \n");
|
||||
@ -42,11 +65,7 @@ int main(int argc, char **argv)
|
||||
int timestepMax, interval;
|
||||
double tau,Fx,Fy,Fz,tol;
|
||||
// Domain variables
|
||||
double Lx,Ly,Lz;
|
||||
int nspheres;
|
||||
int Nx,Ny,Nz;
|
||||
int i,j,k,n;
|
||||
int dim = 12; if (rank == 0) printf("dim=%d\n",dim);
|
||||
int timestep = 0;
|
||||
|
||||
|
||||
@ -56,68 +75,16 @@ int main(int argc, char **argv)
|
||||
double rlx_setB = 8.f*(2.f-rlx_setA)/(8.f-rlx_setA);
|
||||
Fx = 0; Fy = 0;
|
||||
Fz = 1e-3; //1.f; // 1e-3;
|
||||
if (rank==0){
|
||||
//.......................................................................
|
||||
// Reading the domain information file
|
||||
//.......................................................................
|
||||
ifstream domain("Domain.in");
|
||||
if (domain.good()){
|
||||
printf("domain.good == true \n");
|
||||
domain >> nprocx;
|
||||
domain >> nprocy;
|
||||
domain >> nprocz;
|
||||
domain >> Nx;
|
||||
domain >> Ny;
|
||||
domain >> Nz;
|
||||
domain >> nspheres;
|
||||
domain >> Lx;
|
||||
domain >> Ly;
|
||||
domain >> Lz;
|
||||
}
|
||||
else if (nprocs==1){
|
||||
printf("domain.good == false - using predefined parameters \n");
|
||||
nprocx=nprocy=nprocz=1;
|
||||
Nx=dim; Ny = dim;
|
||||
Nz = dim;
|
||||
nspheres=0;
|
||||
Lx=Ly=Lz=1;
|
||||
}
|
||||
else if (nprocs==2){
|
||||
printf("domain.good == false - using predefined parameters \n");
|
||||
nprocx=2;
|
||||
nprocy=nprocz=1;
|
||||
Nx=0.5*dim; Ny = 0.5*dim;
|
||||
Nz = 0.5*dim;
|
||||
nspheres=0;
|
||||
Lx=Ly=Lz=1;
|
||||
}
|
||||
//.......................................................................
|
||||
}
|
||||
// **************************************************************
|
||||
// Broadcast simulation parameters from rank 0 to all other procs
|
||||
MPI_Barrier(comm);
|
||||
//.................................................
|
||||
MPI_Bcast(&Nx,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Ny,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Nz,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocx,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocy,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocz,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nspheres,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Lx,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Bcast(&Ly,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Bcast(&Lz,1,MPI_DOUBLE,0,comm);
|
||||
//.................................................
|
||||
MPI_Barrier(comm);
|
||||
// **************************************************************
|
||||
// **************************************************************
|
||||
|
||||
if (nprocs != nprocx*nprocy*nprocz){
|
||||
printf("nprocx = %i \n",nprocx);
|
||||
printf("nprocy = %i \n",nprocy);
|
||||
printf("nprocz = %i \n",nprocz);
|
||||
INSIST(nprocs == nprocx*nprocy*nprocz,"Fatal error in processor count!");
|
||||
}
|
||||
// Load inputs
|
||||
auto db = loadInputs( nprocs );
|
||||
int Nx = db->getVector<int>( "n" )[0];
|
||||
int Ny = db->getVector<int>( "n" )[1];
|
||||
int Nz = db->getVector<int>( "n" )[2];
|
||||
int nprocx = db->getVector<int>( "nproc" )[0];
|
||||
int nprocy = db->getVector<int>( "nproc" )[1];
|
||||
int nprocz = db->getVector<int>( "nproc" )[2];
|
||||
|
||||
|
||||
if (rank==0){
|
||||
printf("********************************************************\n");
|
||||
@ -126,9 +93,9 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
MPI_Barrier(comm);
|
||||
kproc = rank/(nprocx*nprocy);
|
||||
jproc = (rank-nprocx*nprocy*kproc)/nprocx;
|
||||
iproc = rank-nprocx*nprocy*kproc-nprocz*jproc;
|
||||
int kproc = rank/(nprocx*nprocy);
|
||||
int jproc = (rank-nprocx*nprocy*kproc)/nprocx;
|
||||
int iproc = rank-nprocx*nprocy*kproc-nprocz*jproc;
|
||||
|
||||
if (rank == 0) {
|
||||
printf("i,j,k proc=%d %d %d \n",iproc,jproc,kproc);
|
||||
@ -140,9 +107,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
double iVol_global = 1.0/Nx/Ny/Nz/nprocx/nprocy/nprocz;
|
||||
int BoundaryCondition=0;
|
||||
|
||||
Domain Dm(Nx,Ny,Nz,rank,nprocx,nprocy,nprocz,Lx,Ly,Lz,BoundaryCondition);
|
||||
Domain Dm(db);
|
||||
|
||||
Nx += 2;
|
||||
Ny += 2;
|
||||
|
@ -9,7 +9,21 @@
|
||||
#include "common/ScaLBL.h"
|
||||
#include "common/MPI_Helpers.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
std::shared_ptr<Database> loadInputs( int nprocs )
|
||||
{
|
||||
auto db = std::make_shared<Database>( "Domain.in" );
|
||||
const int dim = 50;
|
||||
db->putScalar<int>( "BC", 0 );
|
||||
if ( nprocs == 1 ){
|
||||
db->putVector<int>( "nproc", { 1, 1, 1 } );
|
||||
db->putVector<int>( "n", { 4, 4, 4 } );
|
||||
db->putScalar<int>( "nspheres", 0 );
|
||||
db->putVector<double>( "L", { 1, 1, 1 } );
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
|
||||
//***************************************************************************************
|
||||
int main(int argc, char **argv)
|
||||
@ -25,11 +39,6 @@ int main(int argc, char **argv)
|
||||
MPI_Comm_size(comm,&nprocs);
|
||||
int check;
|
||||
{
|
||||
// parallel domain size (# of sub-domains)
|
||||
int nprocx,nprocy,nprocz;
|
||||
int iproc,jproc,kproc;
|
||||
|
||||
|
||||
if (rank == 0){
|
||||
printf("********************************************************\n");
|
||||
printf("Running Unit Test: TestPressVel \n");
|
||||
@ -42,67 +51,21 @@ int main(int argc, char **argv)
|
||||
int timestepMax, interval;
|
||||
double tau,Fx,Fy,Fz,tol;
|
||||
// Domain variables
|
||||
double Lx,Ly,Lz;
|
||||
int nspheres;
|
||||
int Nx,Ny,Nz;
|
||||
int i,j,k,n;
|
||||
int dim = 50; if (rank == 0) printf("dim=%d\n",dim);
|
||||
double rlx_setA=1.0;
|
||||
double rlx_setB=1.0;
|
||||
|
||||
Fx = Fy = 0.f;
|
||||
Fz = 1.0e-4;
|
||||
if (rank==0){
|
||||
//.......................................................................
|
||||
// Reading the domain information file
|
||||
//.......................................................................
|
||||
ifstream domain("Domain.in");
|
||||
if (domain.good()){
|
||||
domain >> nprocx;
|
||||
domain >> nprocy;
|
||||
domain >> nprocz;
|
||||
domain >> Nx;
|
||||
domain >> Ny;
|
||||
domain >> Nz;
|
||||
domain >> nspheres;
|
||||
domain >> Lx;
|
||||
domain >> Ly;
|
||||
domain >> Lz;
|
||||
}
|
||||
else if (nprocs==1){
|
||||
nprocx=nprocy=nprocz=1;
|
||||
Nx=4; Ny = 4;
|
||||
Nz = 4;
|
||||
nspheres=0;
|
||||
Lx=Ly=Lz=1;
|
||||
}
|
||||
//.......................................................................
|
||||
}
|
||||
// **************************************************************
|
||||
// Broadcast simulation parameters from rank 0 to all other procs
|
||||
MPI_Barrier(comm);
|
||||
//.................................................
|
||||
MPI_Bcast(&Nx,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Ny,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Nz,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocx,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocy,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocz,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nspheres,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Lx,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Bcast(&Ly,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Bcast(&Lz,1,MPI_DOUBLE,0,comm);
|
||||
//.................................................
|
||||
MPI_Barrier(comm);
|
||||
// **************************************************************
|
||||
// **************************************************************
|
||||
|
||||
if (nprocs != nprocx*nprocy*nprocz){
|
||||
printf("nprocx = %i \n",nprocx);
|
||||
printf("nprocy = %i \n",nprocy);
|
||||
printf("nprocz = %i \n",nprocz);
|
||||
INSIST(nprocs == nprocx*nprocy*nprocz,"Fatal error in processor count!");
|
||||
}
|
||||
// Load inputs
|
||||
auto db = loadInputs( nprocs );
|
||||
int Nx = db->getVector<int>( "n" )[0];
|
||||
int Ny = db->getVector<int>( "n" )[1];
|
||||
int Nz = db->getVector<int>( "n" )[2];
|
||||
int nprocx = db->getVector<int>( "nproc" )[0];
|
||||
int nprocy = db->getVector<int>( "nproc" )[1];
|
||||
int nprocz = db->getVector<int>( "nproc" )[2];
|
||||
|
||||
if (rank==0){
|
||||
printf("********************************************************\n");
|
||||
@ -111,9 +74,9 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
MPI_Barrier(comm);
|
||||
kproc = rank/(nprocx*nprocy);
|
||||
jproc = (rank-nprocx*nprocy*kproc)/nprocx;
|
||||
iproc = rank-nprocx*nprocy*kproc-nprocz*jproc;
|
||||
int kproc = rank/(nprocx*nprocy);
|
||||
int jproc = (rank-nprocx*nprocy*kproc)/nprocx;
|
||||
int iproc = rank-nprocx*nprocy*kproc-nprocz*jproc;
|
||||
|
||||
if (rank == 0) {
|
||||
printf("i,j,k proc=%d %d %d \n",iproc,jproc,kproc);
|
||||
@ -125,9 +88,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
double iVol_global = 1.0/Nx/Ny/Nz/nprocx/nprocy/nprocz;
|
||||
int BoundaryCondition=0;
|
||||
|
||||
Domain Dm(Nx,Ny,Nz,rank,nprocx,nprocy,nprocz,Lx,Ly,Lz,BoundaryCondition);
|
||||
Domain Dm(db);
|
||||
|
||||
|
||||
Nx += 2;
|
||||
|
@ -14,6 +14,20 @@
|
||||
#include "analysis/eikonal.h"
|
||||
|
||||
|
||||
std::shared_ptr<Database> loadInputs( int nprocs )
|
||||
{
|
||||
INSIST(nprocs==8, "TestSegDist: Number of MPI processes must be equal to 8");
|
||||
auto db = std::make_shared<Database>( );
|
||||
db->putScalar<int>( "BC", 0 );
|
||||
db->putVector<int>( "nproc", { 2, 2, 2 } );
|
||||
db->putVector<int>( "n", { 50, 50, 50 } );
|
||||
db->putScalar<int>( "nspheres", 0 );
|
||||
db->putVector<double>( "L", { 1, 1, 1 } );
|
||||
return db;
|
||||
}
|
||||
|
||||
|
||||
//***************************************************************************************
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Initialize MPI
|
||||
@ -25,39 +39,35 @@ int main(int argc, char **argv)
|
||||
{
|
||||
int i,j,k,n,nn;
|
||||
int iproc,jproc,kproc;
|
||||
int nx,ny,nz;
|
||||
int Nx, Ny, Nz, N;
|
||||
int nprocx, nprocy, nprocz, nspheres;
|
||||
double Lx, Ly, Lz;
|
||||
Nx = Ny = Nz = 50;
|
||||
nx = ny = nz = 50;
|
||||
N = Nx*Ny*Nz;
|
||||
nprocx=nprocy=nprocz=2;
|
||||
Lx = Ly = Lz = 1.0;
|
||||
int BC=0;
|
||||
|
||||
if (nprocs != 8){
|
||||
ERROR("TestSegDist: Number of MPI processes must be equal to 8");
|
||||
}
|
||||
|
||||
if (nprocx !=2 || nprocz !=2 || nprocy !=2 ){
|
||||
ERROR("TestSegDist: MPI process grid must be 2x2x2");
|
||||
}
|
||||
|
||||
// Load inputs
|
||||
auto db = loadInputs( nprocs );
|
||||
int Nx = db->getVector<int>( "n" )[0];
|
||||
int Ny = db->getVector<int>( "n" )[1];
|
||||
int Nz = db->getVector<int>( "n" )[2];
|
||||
int nprocx = db->getVector<int>( "nproc" )[0];
|
||||
int nprocy = db->getVector<int>( "nproc" )[1];
|
||||
int nprocz = db->getVector<int>( "nproc" )[2];
|
||||
|
||||
|
||||
// Get the rank info
|
||||
Domain Dm(nx,ny,nz,rank,nprocx,nprocy,nprocz,Lx,Ly,Lz,BC);
|
||||
for (k=0;k<nz;k++){
|
||||
for (j=0;j<ny;j++){
|
||||
for (i=0;i<nx;i++){
|
||||
n = k*nx*ny+j*nx+i;
|
||||
Domain Dm(db);
|
||||
for (k=0;k<Nz;k++){
|
||||
for (j=0;j<Ny;j++){
|
||||
for (i=0;i<Nx;i++){
|
||||
n = k*Nx*Ny+j*Nx+i;
|
||||
Dm.id[n] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Dm.CommInit(comm);
|
||||
|
||||
nx+=2; ny+=2; nz+=2;
|
||||
N = nx*ny*nz;
|
||||
int nx = Nx+2;
|
||||
int ny = Ny+2;
|
||||
int nz = Nz+2;
|
||||
int N = nx*ny*nz;
|
||||
int count = 0;
|
||||
|
||||
char *id;
|
||||
|
@ -9,10 +9,17 @@
|
||||
#include "analysis/analysis.h"
|
||||
#include "analysis/TwoPhase.h"
|
||||
|
||||
//#include "Domain.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
std::shared_ptr<Database> loadInputs( int nprocs )
|
||||
{
|
||||
auto db = std::make_shared<Database>( "Domain.in" );
|
||||
db->putScalar<int>( "BC", 0 );
|
||||
db->putVector<int>( "nproc", { 1, 1, 1 } );
|
||||
db->putVector<int>( "n", { 100, 100, 100 } );
|
||||
db->putScalar<int>( "nspheres", 1 );
|
||||
db->putVector<double>( "L", { 1, 1, 1 } );
|
||||
return db;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
@ -34,65 +41,33 @@ int main(int argc, char **argv)
|
||||
//.......................................................................
|
||||
// Reading the domain information file
|
||||
//.......................................................................
|
||||
int nprocx, nprocy, nprocz, nx, ny, nz, nspheres;
|
||||
double Lx, Ly, Lz;
|
||||
int Nx,Ny,Nz;
|
||||
int i,j,k,n;
|
||||
|
||||
if (rank==0){
|
||||
/* ifstream domain("Domain.in");
|
||||
domain >> nprocx;
|
||||
domain >> nprocy;
|
||||
domain >> nprocz;
|
||||
domain >> nx;
|
||||
domain >> ny;
|
||||
domain >> nz;
|
||||
domain >> nspheres;
|
||||
domain >> Lx;
|
||||
domain >> Ly;
|
||||
domain >> Lz;
|
||||
*/
|
||||
// Set the domain for single processor test
|
||||
nprocx=nprocy=nprocz=1;
|
||||
nx=ny=nz=100;
|
||||
nspheres=1;
|
||||
Lx=Ly=Lz=1;
|
||||
}
|
||||
MPI_Barrier(comm);
|
||||
// Computational domain
|
||||
MPI_Bcast(&nx,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&ny,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nz,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocx,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocy,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocz,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nspheres,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Lx,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Bcast(&Ly,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Bcast(&Lz,1,MPI_DOUBLE,0,comm);
|
||||
//.................................................
|
||||
MPI_Barrier(comm);
|
||||
// Load inputs
|
||||
auto db = loadInputs( nprocs );
|
||||
int Nx = db->getVector<int>( "n" )[0];
|
||||
int Ny = db->getVector<int>( "n" )[1];
|
||||
int Nz = db->getVector<int>( "n" )[2];
|
||||
int nprocx = db->getVector<int>( "nproc" )[0];
|
||||
int nprocy = db->getVector<int>( "nproc" )[1];
|
||||
int nprocz = db->getVector<int>( "nproc" )[2];
|
||||
|
||||
if (rank==0){
|
||||
printf("********************************************************\n");
|
||||
printf("Sub-domain size = %i x %i x %i\n",Nx,Ny,Nz);
|
||||
printf("********************************************************\n");
|
||||
}
|
||||
|
||||
|
||||
// Check that the number of processors >= the number of ranks
|
||||
if ( rank==0 ) {
|
||||
printf("Number of MPI ranks required: %i \n", nprocx*nprocy*nprocz);
|
||||
printf("Number of MPI ranks used: %i \n", nprocs);
|
||||
printf("Full domain size: %i x %i x %i \n",nx*nprocx,ny*nprocy,nz*nprocz);
|
||||
}
|
||||
if ( nprocs < nprocx*nprocy*nprocz )
|
||||
ERROR("Insufficient number of processors");
|
||||
|
||||
// Set up the domain
|
||||
int BC=0;
|
||||
// Get the rank info
|
||||
Domain Dm(nx,ny,nz,rank,nprocx,nprocy,nprocz,Lx,Ly,Lz,BC);
|
||||
Domain Dm(db);
|
||||
// const RankInfoStruct rank_info(rank,nprocx,nprocy,nprocz);
|
||||
TwoPhase Averages(Dm);
|
||||
int N = (nx+2)*(ny+2)*(nz+2);
|
||||
Nx = nx+2;
|
||||
Ny = ny+2;
|
||||
Nz = nz+2;
|
||||
if (rank == 0) cout << "Domain set." << endl;
|
||||
Nx += 2;
|
||||
Ny += 2;
|
||||
Nz += 2;
|
||||
int N = Nx*Ny*Nz;
|
||||
//.......................................................................
|
||||
for ( k=1;k<Nz-1;k++){
|
||||
for ( j=1;j<Ny-1;j++){
|
||||
|
@ -21,7 +21,7 @@ inline bool approx_equal( const Point& A, const Point& B )
|
||||
}
|
||||
inline bool approx_equal( const double& A, const double& B )
|
||||
{
|
||||
return fabs(A-B)<=1e-7*fabs(A+B);
|
||||
return fabs(A-B) <= std::max<double>(1e-7*fabs(A+B),1e-20);
|
||||
}
|
||||
|
||||
|
||||
@ -85,7 +85,7 @@ void testWriter( const std::string& format, std::vector<IO::MeshDataStruct>& mes
|
||||
|
||||
// Get a list of the timesteps
|
||||
PROFILE_START(format+"-read-timesteps");
|
||||
std::vector<std::string> timesteps = IO::readTimesteps( path + "/" + summary_name );
|
||||
auto timesteps = IO::readTimesteps( path + "/" + summary_name );
|
||||
PROFILE_STOP(format+"-read-timesteps");
|
||||
if ( timesteps.size()==2 )
|
||||
ut.passes(format+": Corrent number of timesteps");
|
||||
@ -117,7 +117,7 @@ void testWriter( const std::string& format, std::vector<IO::MeshDataStruct>& mes
|
||||
pass = true;
|
||||
for (size_t k=0; k<database.domains.size(); k++) {
|
||||
PROFILE_START(format+"-read-getMesh");
|
||||
std::shared_ptr<IO::Mesh> mesh = IO::getMesh(path,timestep,database,k);
|
||||
auto mesh = IO::getMesh(path,timestep,database,k);
|
||||
PROFILE_STOP(format+"-read-getMesh");
|
||||
if ( mesh.get()==NULL ) {
|
||||
printf("Failed to load %s\n",database.name.c_str());
|
||||
@ -126,7 +126,7 @@ void testWriter( const std::string& format, std::vector<IO::MeshDataStruct>& mes
|
||||
}
|
||||
if ( database.name=="pointmesh" ) {
|
||||
// Check the pointmesh
|
||||
std::shared_ptr<IO::PointList> pmesh = IO::getPointList(mesh);
|
||||
auto pmesh = IO::getPointList(mesh);
|
||||
if ( pmesh.get()==NULL ) {
|
||||
pass = false;
|
||||
break;
|
||||
@ -138,8 +138,8 @@ void testWriter( const std::string& format, std::vector<IO::MeshDataStruct>& mes
|
||||
}
|
||||
if ( database.name=="trimesh" || database.name=="trilist" ) {
|
||||
// Check the trimesh/trilist
|
||||
std::shared_ptr<IO::TriMesh> mesh1 = IO::getTriMesh(mesh);
|
||||
std::shared_ptr<IO::TriList> mesh2 = IO::getTriList(mesh);
|
||||
auto mesh1 = IO::getTriMesh(mesh);
|
||||
auto mesh2 = IO::getTriList(mesh);
|
||||
if ( mesh1.get()==NULL || mesh2.get()==NULL ) {
|
||||
pass = false;
|
||||
break;
|
||||
@ -198,8 +198,7 @@ void testWriter( const std::string& format, std::vector<IO::MeshDataStruct>& mes
|
||||
auto mesh = IO::getMesh(path,timestep,database,k);
|
||||
for (size_t v=0; v<mesh0->vars.size(); v++) {
|
||||
PROFILE_START(format+"-read-getVariable");
|
||||
std::shared_ptr<IO::Variable> variable =
|
||||
IO::getVariable(path,timestep,database,k,mesh0->vars[v]->name);
|
||||
auto variable = IO::getVariable(path,timestep,database,k,mesh0->vars[v]->name);
|
||||
if ( format=="new" )
|
||||
IO::reformatVariable( *mesh, *variable );
|
||||
PROFILE_STOP(format+"-read-getVariable");
|
||||
@ -251,19 +250,19 @@ int main(int argc, char **argv)
|
||||
};
|
||||
|
||||
// Create the meshes
|
||||
std::shared_ptr<IO::PointList> set1( new IO::PointList(N_points) );
|
||||
auto set1 = std::make_shared<IO::PointList>(N_points);
|
||||
for (int i=0; i<N_points; i++) {
|
||||
set1->points[i].x = x[i];
|
||||
set1->points[i].y = y[i];
|
||||
set1->points[i].z = z[i];
|
||||
}
|
||||
std::shared_ptr<IO::TriMesh> trimesh( new IO::TriMesh(N_tri,set1) );
|
||||
auto trimesh = std::make_shared<IO::TriMesh>(N_tri,set1);
|
||||
for (int i=0; i<N_tri; i++) {
|
||||
trimesh->A[i] = tri[i][0];
|
||||
trimesh->B[i] = tri[i][1];
|
||||
trimesh->C[i] = tri[i][2];
|
||||
}
|
||||
std::shared_ptr<IO::TriList> trilist( new IO::TriList(*trimesh) );
|
||||
auto trilist = std::make_shared<IO::TriList>(*trimesh);
|
||||
for (int i=0; i<N_tri; i++) {
|
||||
Point A(x[tri[i][0]],y[tri[i][0]],z[tri[i][0]]);
|
||||
Point B(x[tri[i][1]],y[tri[i][1]],z[tri[i][1]]);
|
||||
@ -275,25 +274,25 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
RankInfoStruct rank_data( rank, nprocs, 1, 1 );
|
||||
std::shared_ptr<IO::DomainMesh> domain( new IO::DomainMesh(rank_data,6,7,8,1.0,1.0,1.0) );
|
||||
auto domain = std::make_shared<IO::DomainMesh>(rank_data,6,7,8,1.0,1.0,1.0);
|
||||
|
||||
// Create the variables
|
||||
const auto NodeVar = IO::VariableType::NodeVariable;
|
||||
const auto VolVar = IO::VariableType::VolumeVariable;
|
||||
std::shared_ptr<IO::Variable> set_node_mag( new IO::Variable(1,NodeVar,"Node_set_mag") );
|
||||
std::shared_ptr<IO::Variable> set_node_vec( new IO::Variable(3,NodeVar,"Node_set_vec") );
|
||||
std::shared_ptr<IO::Variable> list_node_mag( new IO::Variable(1,NodeVar,"Node_list_mag") );
|
||||
std::shared_ptr<IO::Variable> list_node_vec( new IO::Variable(3,NodeVar,"Node_list_vec") );
|
||||
std::shared_ptr<IO::Variable> point_node_mag( new IO::Variable(1,NodeVar,"Node_point_mag") );
|
||||
std::shared_ptr<IO::Variable> point_node_vec( new IO::Variable(3,NodeVar,"Node_point_vec") );
|
||||
std::shared_ptr<IO::Variable> domain_node_mag( new IO::Variable(1,NodeVar,"Node_domain_mag") );
|
||||
std::shared_ptr<IO::Variable> domain_node_vec( new IO::Variable(3,NodeVar,"Node_domain_vec") );
|
||||
std::shared_ptr<IO::Variable> set_cell_mag( new IO::Variable(1,VolVar,"Cell_set_mag") );
|
||||
std::shared_ptr<IO::Variable> set_cell_vec( new IO::Variable(3,VolVar,"Cell_set_vec") );
|
||||
std::shared_ptr<IO::Variable> list_cell_mag( new IO::Variable(1,VolVar,"Cell_list_mag") );
|
||||
std::shared_ptr<IO::Variable> list_cell_vec( new IO::Variable(3,VolVar,"Cell_list_vec") );
|
||||
std::shared_ptr<IO::Variable> domain_cell_mag( new IO::Variable(1,VolVar,"Cell_domain_mag") );
|
||||
std::shared_ptr<IO::Variable> domain_cell_vec( new IO::Variable(3,VolVar,"Cell_domain_vec") );
|
||||
const auto NodeVar = IO::VariableType::NodeVariable;
|
||||
const auto VolVar = IO::VariableType::VolumeVariable;
|
||||
auto set_node_mag = std::make_shared<IO::Variable>(1,NodeVar,"Node_set_mag");
|
||||
auto set_node_vec = std::make_shared<IO::Variable>(3,NodeVar,"Node_set_vec");
|
||||
auto list_node_mag = std::make_shared<IO::Variable>(1,NodeVar,"Node_list_mag");
|
||||
auto list_node_vec = std::make_shared<IO::Variable>(3,NodeVar,"Node_list_vec");
|
||||
auto point_node_mag = std::make_shared<IO::Variable>(1,NodeVar,"Node_point_mag");
|
||||
auto point_node_vec = std::make_shared<IO::Variable>(3,NodeVar,"Node_point_vec");
|
||||
auto domain_node_mag = std::make_shared<IO::Variable>(1,NodeVar,"Node_domain_mag");
|
||||
auto domain_node_vec = std::make_shared<IO::Variable>(3,NodeVar,"Node_domain_vec");
|
||||
auto set_cell_mag = std::make_shared<IO::Variable>(1,VolVar,"Cell_set_mag");
|
||||
auto set_cell_vec = std::make_shared<IO::Variable>(3,VolVar,"Cell_set_vec");
|
||||
auto list_cell_mag = std::make_shared<IO::Variable>(1,VolVar,"Cell_list_mag");
|
||||
auto list_cell_vec = std::make_shared<IO::Variable>(3,VolVar,"Cell_list_vec");
|
||||
auto domain_cell_mag = std::make_shared<IO::Variable>(1,VolVar,"Cell_domain_mag");
|
||||
auto domain_cell_vec = std::make_shared<IO::Variable>(3,VolVar,"Cell_domain_vec");
|
||||
point_node_mag->data.resize( N_points );
|
||||
point_node_vec->data.resize( N_points, 3 );
|
||||
for (int i=0; i<N_points; i++) {
|
||||
|
@ -11,6 +11,17 @@
|
||||
#include "analysis/TwoPhase.h"
|
||||
#include "common/MPI_Helpers.h"
|
||||
|
||||
|
||||
std::shared_ptr<Database> loadInputs( )
|
||||
{
|
||||
auto db = std::make_shared<Database>( "Domain.in" );
|
||||
const int dim = 50;
|
||||
db->putScalar<int>( "BC", 0 );
|
||||
return db;
|
||||
}
|
||||
|
||||
|
||||
//***************************************************************************************
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
//*****************************************
|
||||
@ -24,8 +35,6 @@ int main(int argc, char **argv)
|
||||
MPI_Comm_size(comm,&nprocs);
|
||||
{
|
||||
// parallel domain size (# of sub-domains)
|
||||
int nprocx,nprocy,nprocz;
|
||||
int iproc,jproc,kproc;
|
||||
int sendtag,recvtag;
|
||||
//*****************************************
|
||||
// MPI ranks for all 18 neighbors
|
||||
@ -54,55 +63,24 @@ int main(int argc, char **argv)
|
||||
|
||||
// Variables that specify the computational domain
|
||||
string FILENAME;
|
||||
int Nx,Ny,Nz; // local sub-domain size
|
||||
int nspheres; // number of spheres in the packing
|
||||
double Lx,Ly,Lz; // Domain length
|
||||
int i,j,k,n;
|
||||
|
||||
// pmmc threshold values
|
||||
|
||||
if (rank==0){
|
||||
//.......................................................................
|
||||
// Reading the domain information file
|
||||
//.......................................................................
|
||||
ifstream domain("Domain.in");
|
||||
domain >> nprocx;
|
||||
domain >> nprocy;
|
||||
domain >> nprocz;
|
||||
domain >> Nx;
|
||||
domain >> Ny;
|
||||
domain >> Nz;
|
||||
domain >> nspheres;
|
||||
domain >> Lx;
|
||||
domain >> Ly;
|
||||
domain >> Lz;
|
||||
//.......................................................................
|
||||
}
|
||||
// **************************************************************
|
||||
// Broadcast simulation parameters from rank 0 to all other procs
|
||||
MPI_Barrier(comm);
|
||||
// Computational domain
|
||||
MPI_Bcast(&Nx,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Ny,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Nz,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocx,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocy,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocz,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nspheres,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Lx,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Bcast(&Ly,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Bcast(&Lz,1,MPI_DOUBLE,0,comm);
|
||||
//.................................................
|
||||
MPI_Barrier(comm);
|
||||
|
||||
// **************************************************************
|
||||
if (nprocs != nprocx*nprocy*nprocz){
|
||||
printf("nprocx = %i \n",nprocx);
|
||||
printf("nprocy = %i \n",nprocy);
|
||||
printf("nprocz = %i \n",nprocz);
|
||||
INSIST(nprocs == nprocx*nprocy*nprocz,"Fatal error in processor count!");
|
||||
}
|
||||
|
||||
// Load inputs
|
||||
auto db = loadInputs( );
|
||||
int Nx = db->getVector<int>( "n" )[0];
|
||||
int Ny = db->getVector<int>( "n" )[1];
|
||||
int Nz = db->getVector<int>( "n" )[2];
|
||||
int nprocx = db->getVector<int>( "nproc" )[0];
|
||||
int nprocy = db->getVector<int>( "nproc" )[1];
|
||||
int nprocz = db->getVector<int>( "nproc" )[2];
|
||||
int kproc = rank/(nprocx*nprocy);
|
||||
int jproc = (rank-nprocx*nprocy*kproc)/nprocx;
|
||||
int iproc = rank-nprocx*nprocy*kproc-nprocx*jproc;
|
||||
|
||||
if (rank==0){
|
||||
printf("********************************************************\n");
|
||||
printf("Sub-domain size = %i x %i x %i\n",Nz,Nz,Nz);
|
||||
@ -111,7 +89,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
// Initialized domain and averaging framework for Two-Phase Flow
|
||||
Domain Dm(Nx,Ny,Nz,rank,nprocx,nprocy,nprocz,Lx,Ly,Lz,BC);
|
||||
Domain Dm(db);
|
||||
Dm.CommInit(comm);
|
||||
TwoPhase Averages(Dm);
|
||||
|
||||
|
@ -96,7 +96,7 @@ int main(int argc, char **argv)
|
||||
int RESTART_INTERVAL=20000;
|
||||
//int ANALYSIS_)INTERVAL=1000;
|
||||
int BLOB_ANALYSIS_INTERVAL=1000;
|
||||
int timestep = 0;
|
||||
int timestep = 6;
|
||||
|
||||
if (rank==0){
|
||||
//.............................................................
|
||||
@ -492,7 +492,7 @@ int main(int argc, char **argv)
|
||||
ScaLBL_CopyToDevice(dvcMap, TmpMap, sizeof(int)*Np);
|
||||
ScaLBL_DeviceBarrier();
|
||||
delete [] TmpMap;
|
||||
|
||||
|
||||
// Compute the solid interaction potential and copy result to device
|
||||
if (rank==0) printf("Computing solid interaction potential \n");
|
||||
double *Tmp;
|
||||
@ -523,14 +523,14 @@ int main(int argc, char **argv)
|
||||
for (int kk=0; kk<5; kk++){
|
||||
for (int jj=0; jj<5; jj++){
|
||||
for (int ii=0; ii<5; ii++){
|
||||
|
||||
|
||||
int index = kk*25+jj*5+ii;
|
||||
double distval= Dst[index];
|
||||
|
||||
int idi=i+ii-2;
|
||||
int idj=j+jj-2;
|
||||
int idk=k+kk-2;
|
||||
|
||||
|
||||
if (idi < 0) idi=0;
|
||||
if (idj < 0) idj=0;
|
||||
if (idk < 0) idk=0;
|
||||
@ -540,16 +540,16 @@ int main(int argc, char **argv)
|
||||
|
||||
int nn = idk*Nx*Ny + idj*Nx + idi;
|
||||
if (!(Mask.id[nn] > 0)){
|
||||
double vec_x = double(ii-2);
|
||||
double vec_y = double(jj-2);
|
||||
double vec_z = double(kk-2);
|
||||
|
||||
double ALPHA=PhaseLabel[nn];
|
||||
double GAMMA=-2.f;
|
||||
if (distval > 2.f) ALPHA=0.f; // symmetric cutoff distance
|
||||
phi_x += ALPHA*exp(GAMMA*distval)*vec_x/distval;
|
||||
phi_y += ALPHA*exp(GAMMA*distval)*vec_y/distval;
|
||||
phi_z += ALPHA*exp(GAMMA*distval)*vec_z/distval;
|
||||
double vec_x = double(ii-2);
|
||||
double vec_y = double(jj-2);
|
||||
double vec_z = double(kk-2);
|
||||
|
||||
double ALPHA=PhaseLabel[nn];
|
||||
double GAMMA=-2.f;
|
||||
if (distval > 2.f) ALPHA=0.f; // symmetric cutoff distance
|
||||
phi_x += ALPHA*exp(GAMMA*distval)*vec_x/distval;
|
||||
phi_y += ALPHA*exp(GAMMA*distval)*vec_y/distval;
|
||||
phi_z += ALPHA*exp(GAMMA*distval)*vec_z/distval;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -557,17 +557,17 @@ int main(int argc, char **argv)
|
||||
Tmp[idx] = phi_x;
|
||||
Tmp[idx+Np] = phi_y;
|
||||
Tmp[idx+2*Np] = phi_z;
|
||||
|
||||
|
||||
/* double d = Averages->SDs(n);
|
||||
double dx = Averages->SDs_x(n);
|
||||
double dy = Averages->SDs_y(n);
|
||||
double dz = Averages->SDs_z(n);
|
||||
double value=cns*exp(-bns*fabs(d))-cws*exp(-bns*fabs(d));
|
||||
|
||||
|
||||
Tmp[idx] = value*dx;
|
||||
Tmp[idx+Np] = value*dy;
|
||||
Tmp[idx+2*Np] = value*dz;
|
||||
*/
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -642,7 +642,7 @@ int main(int argc, char **argv)
|
||||
// Copy the phase from the GPU -> CPU
|
||||
//...........................................................................
|
||||
ScaLBL_DeviceBarrier();
|
||||
ScaLBL_Comm.RegularLayout(Map,Phi,Averages->Phase);
|
||||
ScaLBL_CopyToHost(Averages->Phase.data(),Phi,Np*sizeof(double));
|
||||
ScaLBL_Comm.RegularLayout(Map,Pressure,Averages->Press);
|
||||
ScaLBL_Comm.RegularLayout(Map,&Velocity[0],Averages->Vel_x);
|
||||
ScaLBL_Comm.RegularLayout(Map,&Velocity[Np],Averages->Vel_y);
|
||||
@ -751,7 +751,7 @@ int main(int argc, char **argv)
|
||||
PROFILE_STOP("Update");
|
||||
|
||||
// Run the analysis
|
||||
analysis.run( timestep, *Averages, Phi, Pressure, Velocity, fq, Den );
|
||||
// analysis.run( timestep, *Averages, Phi, Pressure, Velocity, fq, Den );
|
||||
|
||||
}
|
||||
analysis.finish();
|
||||
@ -782,8 +782,7 @@ int main(int argc, char **argv)
|
||||
FILE *OUTFILE;
|
||||
sprintf(LocalRankFilename,"Phase.%05i.raw",rank);
|
||||
OUTFILE = fopen(LocalRankFilename,"wb");
|
||||
//fwrite(PhaseField.data(),8,N,OUTFILE);
|
||||
fwrite(Averages->Phase.data(),8,N,OUTFILE);
|
||||
fwrite(PhaseField.data(),8,N,OUTFILE);
|
||||
fclose(OUTFILE);
|
||||
|
||||
PROFILE_STOP("Main");
|
||||
|
@ -274,7 +274,7 @@ int main(int argc, char **argv)
|
||||
n=k*nx*ny+j*nx+i;
|
||||
total++;
|
||||
Dm.id[n] = newIDs[n];
|
||||
if (!(Dm.id[n] > 0)){
|
||||
if (Dm.id[n] == 0){
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@ -307,7 +307,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
float porosity = float(totalGlobal-countGlobal)/totalGlobal;
|
||||
//printf("Original Porosity=%f\n",porosity);
|
||||
printf("Original Porosity=%f\n",porosity);
|
||||
}
|
||||
|
||||
count = 0;
|
||||
|
@ -228,40 +228,18 @@ int main(int argc, char **argv)
|
||||
// DoubleArray Distance(nx,ny,nz);
|
||||
// DoubleArray Phase(nx,ny,nz);
|
||||
|
||||
int count = 0;
|
||||
// Solve for the position of the solid phase
|
||||
for (k=0;k<nz;k++){
|
||||
for (j=0;j<ny;j++){
|
||||
for (i=0;i<nx;i++){
|
||||
n = k*nx*ny+j*nx+i;
|
||||
// Initialize the solid phase
|
||||
if (!(Dm.id[n] > 0)) id[n] = 0;
|
||||
if (Dm.id[n] == 0) id[n] = 0;
|
||||
else id[n] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int count = 0;
|
||||
int total = 0;
|
||||
int totalGlobal = 0;
|
||||
int countGlobal = 0;
|
||||
for (k=1;k<nz-1;k++){
|
||||
for (j=1;j<ny-1;j++){
|
||||
for (i=1;i<nx-1;i++){
|
||||
n=k*nx*ny+j*nx+i;
|
||||
total++;
|
||||
if (!(id[n] > 0)){
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MPI_Allreduce(&total,&totalGlobal,1,MPI_INT,MPI_SUM,comm);
|
||||
MPI_Allreduce(&count,&countGlobal,1,MPI_INT,MPI_SUM,comm);
|
||||
float poros = float(totalGlobal-countGlobal)/totalGlobal;
|
||||
if (rank==0) printf("Porosity=%f\n",poros);
|
||||
|
||||
|
||||
// Initialize the signed distance function
|
||||
for (k=0;k<nz;k++){
|
||||
for (j=0;j<ny;j++){
|
||||
|
Loading…
Reference in New Issue
Block a user