merge LBPM with spock
This commit is contained in:
commit
aa0b3a1cb0
111
.clang-format
111
.clang-format
|
@ -1,108 +1,13 @@
|
|||
# To run clang tools:
|
||||
# cd to root directory
|
||||
# To update format only:
|
||||
# find . -name "*.cpp" -or -name "*.cc" -or -name "*.h" -or -name "*.hpp" -or -name "*.I" | xargs -I{} clang-format -i {}
|
||||
# git status -s . | sed s/^...// | grep -E "(\.cpp|\.h|\.cc|\.hpp|\.I)" | xargs -I{} clang-format -i {}
|
||||
|
||||
# To run modernize
|
||||
# export CLANG_PATH=/packages/llvm/build/llvm-60
|
||||
# export PATH=${CLANG_PATH}/bin:${CLANG_PATH}/share/clang:$PATH
|
||||
# find src -name "*.cpp" -or -name "*.cc" | xargs -I{} clang-tidy -checks=modernize* -p=/projects/AtomicModel/build/debug -fix {}
|
||||
# find src -name "*.cpp" -or -name "*.cc" -or -name "*.h" -or -name "*.hpp" -or -name "*.I" | xargs -I{} clang-format -i {}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# clang-format
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: DontAlign
|
||||
AlignConsecutiveAssignments: true
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlinesLeft: true
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: true
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: true
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
BreakBeforeBinaryOperators: None
|
||||
#BreakBeforeBraces: Stroustrup
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeTernaryOperators: false
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
ColumnLimit: 100
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: false
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
- Regex: '^(<|"(gtest|isl|json)/)'
|
||||
Priority: 3
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
IndentCaseLabels: false
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 2
|
||||
NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 4
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: true
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: true
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
...
|
||||
|
||||
# Our includes are not order-agnostic
|
||||
SortIncludes: false
|
||||
|
||||
# Some of our comments include insightful insight
|
||||
ReflowComments: false
|
||||
...
|
||||
|
|
13
.clang-format-2
Normal file
13
.clang-format-2
Normal file
|
@ -0,0 +1,13 @@
|
|||
# clang-format
|
||||
---
|
||||
Language: Cpp
|
||||
BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -4
|
||||
IndentWidth: 4
|
||||
|
||||
# Our includes are not order-agnostic
|
||||
SortIncludes: false
|
||||
|
||||
# Some of our comments include insightful insight
|
||||
ReflowComments: false
|
||||
...
|
124
.github/workflows/c-cpp.yml
vendored
Normal file
124
.github/workflows/c-cpp.yml
vendored
Normal file
|
@ -0,0 +1,124 @@
|
|||
name: LBPM CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build-and-test:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
LBPM_ZLIB_DIR: /home/runner/extlib/zlib
|
||||
LBPM_HDF5_DIR: /home/runner/extlib/hdf5
|
||||
LBPM_SILO_DIR: /home/runner/extlib/silo
|
||||
MPI_DIR: /home/runner/.openmpi
|
||||
|
||||
steps:
|
||||
|
||||
- name: download dependencies
|
||||
run: |
|
||||
echo $LBPM_ZLIB_DIR
|
||||
echo $LBPM_HDF5_DIR
|
||||
echo $LBPM_SILO_DIR
|
||||
echo $GITHUB_PATH
|
||||
echo $GITHUB_WORKSPACE
|
||||
|
||||
sudo apt-get update -y
|
||||
|
||||
wget https://bitbucket.org/AdvancedMultiPhysics/tpl-builder/downloads/silo-4.10.2.tar.gz
|
||||
wget https://www.zlib.net/zlib-1.2.11.tar.gz
|
||||
wget https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.8/hdf5-1.8.12/src/hdf5-1.8.12.tar.gz
|
||||
#wget https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.8/hdf5-1.8.10/src/hdf5-1.8.10.tar.gz
|
||||
|
||||
tar -xzvf zlib-1.2.11.tar.gz
|
||||
tar -xzvf hdf5-1.8.12.tar.gz
|
||||
tar -xzvf silo-4.10.2.tar.gz
|
||||
|
||||
|
||||
- name: check out commit
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
path: LBPM
|
||||
|
||||
|
||||
|
||||
- name: install-openmpi
|
||||
run: |
|
||||
wget https://download.open-mpi.org/release/open-mpi/v3.1/openmpi-3.1.2.tar.gz
|
||||
tar -xvf ./openmpi-3.1.2.tar.gz
|
||||
./openmpi-3.1.2/configure --prefix="$HOME/.openmpi"
|
||||
make -j
|
||||
sudo make install
|
||||
echo "$HOME/.openmpi/bin" >> $GITHUB_PATH
|
||||
|
||||
|
||||
|
||||
- name: install zlib dependencies
|
||||
run: |
|
||||
cd zlib-1.2.11
|
||||
./configure --prefix=$LBPM_ZLIB_DIR
|
||||
make
|
||||
sudo make install
|
||||
cd ..
|
||||
|
||||
|
||||
- name: install hdf5 dependencies
|
||||
run: |
|
||||
cd hdf5-1.8.12
|
||||
CC=/home/runner/.openmpi/bin/mpicc CXX=/home/runner/.openmpi/bin/mpicxx CXXFLAGS="-fPIC -O3 -std=c++14" \
|
||||
./configure --prefix=$LBPM_HDF5_DIR --enable-parallel --enable-shared --with-zlib=$LBPM_ZLIB_DIR
|
||||
make
|
||||
sudo make install
|
||||
cd ..
|
||||
|
||||
|
||||
- name: install silo dependencies
|
||||
run: |
|
||||
cd silo-4.10.2
|
||||
CC=$MPI_DIR/bin/mpicc CXX=$MPI_DIR/bin/mpicxx CXXFLAGS="-fPIC -O3 -std=c++14" \
|
||||
./configure --prefix=$LBPM_SILO_DIR -with-hdf5="$LBPM_HDF5_DIR/include,$LBPM_HDF5_DIR/lib" --enable-static
|
||||
make
|
||||
sudo make install
|
||||
cd ..
|
||||
|
||||
|
||||
- name: configure cmake
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
rm -rf CMake*
|
||||
cmake \
|
||||
-D CMAKE_BUILD_TYPE:STRING=Release \
|
||||
-D CMAKE_C_COMPILER:PATH=$MPI_DIR/bin/mpicc \
|
||||
-D CMAKE_CXX_COMPILER:PATH=$MPI_DIR/bin/mpicxx \
|
||||
-D MPI_CXX_COMPILER=$MPI_DIR/bin/mpicxx \
|
||||
-D CMAKE_C_FLAGS="-fPIC" \
|
||||
-D CMAKE_CXX_FLAGS="-fPIC" \
|
||||
-D CMAKE_CXX_STD=14 \
|
||||
-D TEST_MAX_PROCS=1 \
|
||||
-D USE_TIMER=0 \
|
||||
-D TIMER_DIRECTORY=$LBPM_TIMER_DIR \
|
||||
-D USE_NETCDF=0 \
|
||||
-D NETCDF_DIRECTORY=$LBPM_NETCDF_DIR \
|
||||
-D USE_SILO=1 \
|
||||
-D HDF5_DIRECTORY=$LBPM_HDF5_DIR \
|
||||
-D SILO_DIRECTORY=$LBPM_SILO_DIR \
|
||||
-D USE_CUDA=0 \
|
||||
$GITHUB_WORKSPACE/LBPM
|
||||
|
||||
|
||||
|
||||
- name: build and make
|
||||
run: |
|
||||
cd build
|
||||
make
|
||||
sudo make install
|
||||
cd ..
|
||||
|
||||
- name: tests
|
||||
run: |
|
||||
cd build
|
||||
ctest
|
41
.github/workflows/test_install_openmpi.yml
vendored
Normal file
41
.github/workflows/test_install_openmpi.yml
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
name: Install OpenMPI test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
install-openmpi:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: check path
|
||||
run: |
|
||||
echo $PATH
|
||||
echo $GITHUB_PATH
|
||||
cmake --version
|
||||
|
||||
- name: download-openmpi
|
||||
run: wget https://download.open-mpi.org/release/open-mpi/v4.0/openmpi-4.0.2.tar.gz
|
||||
|
||||
- name: extract-openmpi
|
||||
run: tar -xvf ./openmpi-4.0.2.tar.gz
|
||||
|
||||
- name: configure-openmpi
|
||||
run: ./openmpi-4.0.2/configure --prefix="/home/${USER}/.openmpi"
|
||||
|
||||
- name: install-openmpi
|
||||
run: |
|
||||
make -j
|
||||
sudo make install
|
||||
|
||||
- name: setting path
|
||||
run: |
|
||||
echo "/home/${USER}/.openmpi/bin" >> $GITHUB_PATH
|
||||
#echo "/home/${USER}/.openmpi/bin" >> $PATH
|
||||
- name: checking version
|
||||
run: mpirun --version
|
||||
|
|
@ -14,7 +14,6 @@ MESSAGE("====================")
|
|||
SET( PROJ LBPM ) # Set the project name for CMake
|
||||
SET( LBPM_LIB lbpm-wia ) # Set the final library name
|
||||
SET( LBPM_INC ) # Set an optional subfolder for includes (e.g. include/name/...)
|
||||
SET( TEST_MAX_PROCS 16 )
|
||||
|
||||
|
||||
# Initialize the project
|
||||
|
|
|
@ -274,7 +274,7 @@ std::vector<IO::MeshDatabase> writeMeshesHDF5( const std::vector<IO::MeshDataStr
|
|||
|
||||
|
||||
std::vector<IO::MeshDatabase> writeMeshesHDF5(
|
||||
const std::vector<IO::MeshDataStruct> &, const std::string &, IO::FileFormat, int )
|
||||
const std::vector<IO::MeshDataStruct> &, const std::string &, IO::FileFormat, int, Xdmf & )
|
||||
{
|
||||
return std::vector<IO::MeshDatabase>();
|
||||
}
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef IO_HELPERS_INC
|
||||
#define IO_HELPERS_INC
|
||||
|
||||
|
|
30
IO/Mesh.cpp
30
IO/Mesh.cpp
|
@ -1,3 +1,33 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "Mesh.h"
|
||||
#include "IO/IOHelpers.h"
|
||||
#include "common/Utilities.h"
|
||||
|
|
15
IO/Mesh.h
15
IO/Mesh.h
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef MESH_INC
|
||||
#define MESH_INC
|
||||
|
||||
|
|
|
@ -1,3 +1,33 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "IO/MeshDatabase.h"
|
||||
#include "IO/IOHelpers.h"
|
||||
#include "IO/Mesh.h"
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef MeshDatabase_INC
|
||||
#define MeshDatabase_INC
|
||||
|
||||
|
|
15
IO/PIO.cpp
15
IO/PIO.cpp
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "IO/PIO.h"
|
||||
#include "common/MPI.h"
|
||||
#include "common/Utilities.h"
|
||||
|
|
15
IO/PIO.h
15
IO/PIO.h
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef included_PIO
|
||||
#define included_PIO
|
||||
|
||||
|
|
30
IO/PIO.hpp
30
IO/PIO.hpp
|
@ -1,3 +1,33 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef included_PIO_hpp
|
||||
#define included_PIO_hpp
|
||||
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "IO/Reader.h"
|
||||
#include "IO/HDF5_IO.h"
|
||||
#include "IO/IOHelpers.h"
|
||||
|
|
15
IO/Reader.h
15
IO/Reader.h
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef READER_INC
|
||||
#define READER_INC
|
||||
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "IO/Writer.h"
|
||||
#include "IO/HDF5_IO.h"
|
||||
#include "IO/IOHelpers.h"
|
||||
|
|
15
IO/Writer.h
15
IO/Writer.h
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef WRITER_INC
|
||||
#define WRITER_INC
|
||||
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "IO/netcdf.h"
|
||||
#include "common/MPI.h"
|
||||
#include "common/Utilities.h"
|
||||
|
|
15
IO/netcdf.h
15
IO/netcdf.h
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef NETCDF_READER
|
||||
#define NETCDF_READER
|
||||
|
||||
|
|
15
IO/silo.cpp
15
IO/silo.cpp
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "IO/silo.h"
|
||||
#include "common/MPI.h"
|
||||
#include "common/Utilities.h"
|
||||
|
|
15
IO/silo.h
15
IO/silo.h
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef SILO_INTERFACE
|
||||
#define SILO_INTERFACE
|
||||
|
||||
|
|
30
IO/silo.hpp
30
IO/silo.hpp
|
@ -1,3 +1,33 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef SILO_INTERFACE_HPP
|
||||
#define SILO_INTERFACE_HPP
|
||||
|
||||
|
|
675
LICENSE
675
LICENSE
|
@ -1,3 +1,677 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
Copyright (c) 2015, JamesEMcClure
|
||||
All rights reserved.
|
||||
|
||||
|
@ -21,4 +695,3 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ Configure, build & install procedure
|
|||
|
||||
* edit configure script from sample_scripts directory and configure (e.g.)
|
||||
|
||||
`/path/to/LBPM-WIA/sample_scripts/configure_desktop`
|
||||
`/path/to/LBPM/sample_scripts/configure_desktop`
|
||||
|
||||
* compile and install
|
||||
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef included_StackTrace
|
||||
#define included_StackTrace
|
||||
|
||||
|
|
|
@ -1,33 +1,54 @@
|
|||
#include "analysis/ElectroChemistry.h"
|
||||
|
||||
ElectroChemistryAnalyzer::ElectroChemistryAnalyzer(std::shared_ptr<Domain> dm)
|
||||
: Dm(dm) {
|
||||
|
||||
ElectroChemistryAnalyzer::ElectroChemistryAnalyzer(std::shared_ptr <Domain> dm):
|
||||
Dm(dm)
|
||||
{
|
||||
Nx = dm->Nx;
|
||||
Ny = dm->Ny;
|
||||
Nz = dm->Nz;
|
||||
Volume = (Nx - 2) * (Ny - 2) * (Nz - 2) * Dm->nprocx() * Dm->nprocy() *
|
||||
Dm->nprocz() * 1.0;
|
||||
|
||||
Nx=dm->Nx; Ny=dm->Ny; Nz=dm->Nz;
|
||||
Volume=(Nx-2)*(Ny-2)*(Nz-2)*Dm->nprocx()*Dm->nprocy()*Dm->nprocz()*1.0;
|
||||
|
||||
ChemicalPotential.resize(Nx,Ny,Nz); ChemicalPotential.fill(0);
|
||||
ElectricalPotential.resize(Nx,Ny,Nz); ElectricalPotential.fill(0);
|
||||
ElectricalField_x.resize(Nx,Ny,Nz); ElectricalField_x.fill(0);
|
||||
ElectricalField_y.resize(Nx,Ny,Nz); ElectricalField_y.fill(0);
|
||||
ElectricalField_z.resize(Nx,Ny,Nz); ElectricalField_z.fill(0);
|
||||
Pressure.resize(Nx,Ny,Nz); Pressure.fill(0);
|
||||
Rho.resize(Nx,Ny,Nz); Rho.fill(0);
|
||||
Vel_x.resize(Nx,Ny,Nz); Vel_x.fill(0); // Gradient of the phase indicator field
|
||||
Vel_y.resize(Nx,Ny,Nz); Vel_y.fill(0);
|
||||
Vel_z.resize(Nx,Ny,Nz); Vel_z.fill(0);
|
||||
SDs.resize(Nx,Ny,Nz); SDs.fill(0);
|
||||
IonFluxDiffusive_x.resize(Nx,Ny,Nz); IonFluxDiffusive_x.fill(0);
|
||||
IonFluxDiffusive_y.resize(Nx,Ny,Nz); IonFluxDiffusive_y.fill(0);
|
||||
IonFluxDiffusive_z.resize(Nx,Ny,Nz); IonFluxDiffusive_z.fill(0);
|
||||
IonFluxAdvective_x.resize(Nx,Ny,Nz); IonFluxAdvective_x.fill(0);
|
||||
IonFluxAdvective_y.resize(Nx,Ny,Nz); IonFluxAdvective_y.fill(0);
|
||||
IonFluxAdvective_z.resize(Nx,Ny,Nz); IonFluxAdvective_z.fill(0);
|
||||
IonFluxElectrical_x.resize(Nx,Ny,Nz); IonFluxElectrical_x.fill(0);
|
||||
IonFluxElectrical_y.resize(Nx,Ny,Nz); IonFluxElectrical_y.fill(0);
|
||||
IonFluxElectrical_z.resize(Nx,Ny,Nz); IonFluxElectrical_z.fill(0);
|
||||
ChemicalPotential.resize(Nx, Ny, Nz);
|
||||
ChemicalPotential.fill(0);
|
||||
ElectricalPotential.resize(Nx, Ny, Nz);
|
||||
ElectricalPotential.fill(0);
|
||||
ElectricalField_x.resize(Nx, Ny, Nz);
|
||||
ElectricalField_x.fill(0);
|
||||
ElectricalField_y.resize(Nx, Ny, Nz);
|
||||
ElectricalField_y.fill(0);
|
||||
ElectricalField_z.resize(Nx, Ny, Nz);
|
||||
ElectricalField_z.fill(0);
|
||||
Pressure.resize(Nx, Ny, Nz);
|
||||
Pressure.fill(0);
|
||||
Rho.resize(Nx, Ny, Nz);
|
||||
Rho.fill(0);
|
||||
Vel_x.resize(Nx, Ny, Nz);
|
||||
Vel_x.fill(0); // Gradient of the phase indicator field
|
||||
Vel_y.resize(Nx, Ny, Nz);
|
||||
Vel_y.fill(0);
|
||||
Vel_z.resize(Nx, Ny, Nz);
|
||||
Vel_z.fill(0);
|
||||
SDs.resize(Nx, Ny, Nz);
|
||||
SDs.fill(0);
|
||||
IonFluxDiffusive_x.resize(Nx, Ny, Nz);
|
||||
IonFluxDiffusive_x.fill(0);
|
||||
IonFluxDiffusive_y.resize(Nx, Ny, Nz);
|
||||
IonFluxDiffusive_y.fill(0);
|
||||
IonFluxDiffusive_z.resize(Nx, Ny, Nz);
|
||||
IonFluxDiffusive_z.fill(0);
|
||||
IonFluxAdvective_x.resize(Nx, Ny, Nz);
|
||||
IonFluxAdvective_x.fill(0);
|
||||
IonFluxAdvective_y.resize(Nx, Ny, Nz);
|
||||
IonFluxAdvective_y.fill(0);
|
||||
IonFluxAdvective_z.resize(Nx, Ny, Nz);
|
||||
IonFluxAdvective_z.fill(0);
|
||||
IonFluxElectrical_x.resize(Nx, Ny, Nz);
|
||||
IonFluxElectrical_x.fill(0);
|
||||
IonFluxElectrical_y.resize(Nx, Ny, Nz);
|
||||
IonFluxElectrical_y.fill(0);
|
||||
IonFluxElectrical_z.resize(Nx, Ny, Nz);
|
||||
IonFluxElectrical_z.fill(0);
|
||||
|
||||
if (Dm->rank() == 0) {
|
||||
bool WriteHeader = false;
|
||||
|
@ -38,14 +59,12 @@ ElectroChemistryAnalyzer::ElectroChemistryAnalyzer(std::shared_ptr <Domain> dm):
|
|||
WriteHeader = true;
|
||||
|
||||
TIMELOG = fopen("electrokinetic.csv", "a+");
|
||||
if (WriteHeader)
|
||||
{
|
||||
if (WriteHeader) {
|
||||
// If timelog is empty, write a short header to list the averages
|
||||
//fprintf(TIMELOG,"--------------------------------------------------------------------------------------\n");
|
||||
fprintf(TIMELOG, "TBD TBD\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ElectroChemistryAnalyzer::~ElectroChemistryAnalyzer() {
|
||||
|
@ -54,11 +73,11 @@ ElectroChemistryAnalyzer::~ElectroChemistryAnalyzer(){
|
|||
}
|
||||
}
|
||||
|
||||
void ElectroChemistryAnalyzer::SetParams(){
|
||||
void ElectroChemistryAnalyzer::SetParams() {}
|
||||
|
||||
}
|
||||
|
||||
void ElectroChemistryAnalyzer::Basic(ScaLBL_IonModel &Ion, ScaLBL_Poisson &Poisson, ScaLBL_StokesModel &Stokes, int timestep){
|
||||
void ElectroChemistryAnalyzer::Basic(ScaLBL_IonModel &Ion,
|
||||
ScaLBL_Poisson &Poisson,
|
||||
ScaLBL_StokesModel &Stokes, int timestep) {
|
||||
|
||||
int i, j, k;
|
||||
double Vin = 0.0;
|
||||
|
@ -102,13 +121,16 @@ void ElectroChemistryAnalyzer::Basic(ScaLBL_IonModel &Ion, ScaLBL_Poisson &Poiss
|
|||
for (i = 1; i < Nx; i++) {
|
||||
rho_avg_local[ion] += Rho(i, j, k);
|
||||
rho_mu_avg_local[ion] += Rho(i, j, k) * Rho(i, j, k);
|
||||
rho_psi_avg_local[ion] += Rho(i,j,k)*ElectricalPotential(i,j,k);
|
||||
rho_psi_avg_local[ion] +=
|
||||
Rho(i, j, k) * ElectricalPotential(i, j, k);
|
||||
}
|
||||
}
|
||||
}
|
||||
rho_avg_global[ion] = Dm->Comm.sumReduce(rho_avg_local[ion]) / Volume;
|
||||
rho_mu_avg_global[ion]=Dm->Comm.sumReduce( rho_mu_avg_local[ion]) / Volume;
|
||||
rho_psi_avg_global[ion]=Dm->Comm.sumReduce( rho_psi_avg_local[ion]) / Volume;
|
||||
rho_mu_avg_global[ion] =
|
||||
Dm->Comm.sumReduce(rho_mu_avg_local[ion]) / Volume;
|
||||
rho_psi_avg_global[ion] =
|
||||
Dm->Comm.sumReduce(rho_psi_avg_local[ion]) / Volume;
|
||||
|
||||
if (rho_avg_global[ion] > 0.0) {
|
||||
rho_mu_avg_global[ion] /= rho_avg_global[ion];
|
||||
|
@ -123,13 +145,18 @@ void ElectroChemistryAnalyzer::Basic(ScaLBL_IonModel &Ion, ScaLBL_Poisson &Poiss
|
|||
for (k = 1; k < Nz; k++) {
|
||||
for (j = 1; j < Ny; j++) {
|
||||
for (i = 1; i < Nx; i++) {
|
||||
rho_mu_fluctuation_local[ion] += (Rho(i,j,k)*Rho(i,j,k) - rho_mu_avg_global[ion]);
|
||||
rho_psi_fluctuation_local[ion] += (Rho(i,j,k)*ElectricalPotential(i,j,k) - rho_psi_avg_global[ion]);
|
||||
rho_mu_fluctuation_local[ion] +=
|
||||
(Rho(i, j, k) * Rho(i, j, k) - rho_mu_avg_global[ion]);
|
||||
rho_psi_fluctuation_local[ion] +=
|
||||
(Rho(i, j, k) * ElectricalPotential(i, j, k) -
|
||||
rho_psi_avg_global[ion]);
|
||||
}
|
||||
}
|
||||
}
|
||||
rho_mu_fluctuation_global[ion]=Dm->Comm.sumReduce( rho_mu_fluctuation_local[ion]);
|
||||
rho_psi_fluctuation_global[ion]=Dm->Comm.sumReduce( rho_psi_fluctuation_local[ion]);
|
||||
rho_mu_fluctuation_global[ion] =
|
||||
Dm->Comm.sumReduce(rho_mu_fluctuation_local[ion]);
|
||||
rho_psi_fluctuation_global[ion] =
|
||||
Dm->Comm.sumReduce(rho_psi_fluctuation_local[ion]);
|
||||
}
|
||||
|
||||
if (Dm->rank() == 0) {
|
||||
|
@ -157,20 +184,29 @@ void ElectroChemistryAnalyzer::Basic(ScaLBL_IonModel &Ion, ScaLBL_Poisson &Poiss
|
|||
} */
|
||||
}
|
||||
|
||||
void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &Poisson, ScaLBL_StokesModel &Stokes, std::shared_ptr<Database> input_db, int timestep){
|
||||
void ElectroChemistryAnalyzer::WriteVis(ScaLBL_IonModel &Ion,
|
||||
ScaLBL_Poisson &Poisson,
|
||||
ScaLBL_StokesModel &Stokes,
|
||||
std::shared_ptr<Database> input_db,
|
||||
int timestep) {
|
||||
|
||||
auto vis_db = input_db->getDatabase("Visualization");
|
||||
char VisName[40];
|
||||
auto format = vis_db->getWithDefault<string>( "format", "hdf5" );
|
||||
|
||||
std::vector<IO::MeshDataStruct> visData;
|
||||
fillHalo<double> fillData(Dm->Comm,Dm->rank_info,{Dm->Nx-2,Dm->Ny-2,Dm->Nz-2},{1,1,1},0,1);
|
||||
fillHalo<double> fillData(Dm->Comm, Dm->rank_info,
|
||||
{Dm->Nx - 2, Dm->Ny - 2, Dm->Nz - 2}, {1, 1, 1},
|
||||
0, 1);
|
||||
|
||||
IO::initialize("","silo","false");
|
||||
IO::initialize("",format,"false");
|
||||
// Create the MeshDataStruct
|
||||
visData.resize(1);
|
||||
|
||||
visData[0].meshName = "domain";
|
||||
visData[0].mesh = std::make_shared<IO::DomainMesh>( Dm->rank_info,Dm->Nx-2,Dm->Ny-2,Dm->Nz-2,Dm->Lx,Dm->Ly,Dm->Lz );
|
||||
visData[0].mesh =
|
||||
std::make_shared<IO::DomainMesh>(Dm->rank_info, Dm->Nx - 2, Dm->Ny - 2,
|
||||
Dm->Nz - 2, Dm->Lx, Dm->Ly, Dm->Lz);
|
||||
//electric potential
|
||||
auto ElectricPotentialVar = std::make_shared<IO::Variable>();
|
||||
//electric field
|
||||
|
@ -228,7 +264,8 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P
|
|||
IonConcentration[ion]->name = VisName;
|
||||
IonConcentration[ion]->type = IO::VariableType::VolumeVariable;
|
||||
IonConcentration[ion]->dim = 1;
|
||||
IonConcentration[ion]->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2);
|
||||
IonConcentration[ion]->data.resize(Dm->Nx - 2, Dm->Ny - 2,
|
||||
Dm->Nz - 2);
|
||||
visData[0].vars.push_back(IonConcentration[ion]);
|
||||
}
|
||||
}
|
||||
|
@ -256,23 +293,29 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P
|
|||
// x-component of diffusive flux
|
||||
sprintf(VisName, "Ion%zu_FluxDiffusive_x", ion + 1);
|
||||
IonFluxDiffusive[3 * ion + 0]->name = VisName;
|
||||
IonFluxDiffusive[3*ion+0]->type = IO::VariableType::VolumeVariable;
|
||||
IonFluxDiffusive[3 * ion + 0]->type =
|
||||
IO::VariableType::VolumeVariable;
|
||||
IonFluxDiffusive[3 * ion + 0]->dim = 1;
|
||||
IonFluxDiffusive[3*ion+0]->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2);
|
||||
IonFluxDiffusive[3 * ion + 0]->data.resize(Dm->Nx - 2, Dm->Ny - 2,
|
||||
Dm->Nz - 2);
|
||||
visData[0].vars.push_back(IonFluxDiffusive[3 * ion + 0]);
|
||||
// y-component of diffusive flux
|
||||
sprintf(VisName, "Ion%zu_FluxDiffusive_y", ion + 1);
|
||||
IonFluxDiffusive[3 * ion + 1]->name = VisName;
|
||||
IonFluxDiffusive[3*ion+1]->type = IO::VariableType::VolumeVariable;
|
||||
IonFluxDiffusive[3 * ion + 1]->type =
|
||||
IO::VariableType::VolumeVariable;
|
||||
IonFluxDiffusive[3 * ion + 1]->dim = 1;
|
||||
IonFluxDiffusive[3*ion+1]->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2);
|
||||
IonFluxDiffusive[3 * ion + 1]->data.resize(Dm->Nx - 2, Dm->Ny - 2,
|
||||
Dm->Nz - 2);
|
||||
visData[0].vars.push_back(IonFluxDiffusive[3 * ion + 1]);
|
||||
// z-component of diffusive flux
|
||||
sprintf(VisName, "Ion%zu_FluxDiffusive_z", ion + 1);
|
||||
IonFluxDiffusive[3 * ion + 2]->name = VisName;
|
||||
IonFluxDiffusive[3*ion+2]->type = IO::VariableType::VolumeVariable;
|
||||
IonFluxDiffusive[3 * ion + 2]->type =
|
||||
IO::VariableType::VolumeVariable;
|
||||
IonFluxDiffusive[3 * ion + 2]->dim = 1;
|
||||
IonFluxDiffusive[3*ion+2]->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2);
|
||||
IonFluxDiffusive[3 * ion + 2]->data.resize(Dm->Nx - 2, Dm->Ny - 2,
|
||||
Dm->Nz - 2);
|
||||
visData[0].vars.push_back(IonFluxDiffusive[3 * ion + 2]);
|
||||
}
|
||||
}
|
||||
|
@ -282,23 +325,29 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P
|
|||
// x-component of advective flux
|
||||
sprintf(VisName, "Ion%zu_FluxAdvective_x", ion + 1);
|
||||
IonFluxAdvective[3 * ion + 0]->name = VisName;
|
||||
IonFluxAdvective[3*ion+0]->type = IO::VariableType::VolumeVariable;
|
||||
IonFluxAdvective[3 * ion + 0]->type =
|
||||
IO::VariableType::VolumeVariable;
|
||||
IonFluxAdvective[3 * ion + 0]->dim = 1;
|
||||
IonFluxAdvective[3*ion+0]->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2);
|
||||
IonFluxAdvective[3 * ion + 0]->data.resize(Dm->Nx - 2, Dm->Ny - 2,
|
||||
Dm->Nz - 2);
|
||||
visData[0].vars.push_back(IonFluxAdvective[3 * ion + 0]);
|
||||
// y-component of advective flux
|
||||
sprintf(VisName, "Ion%zu_FluxAdvective_y", ion + 1);
|
||||
IonFluxAdvective[3 * ion + 1]->name = VisName;
|
||||
IonFluxAdvective[3*ion+1]->type = IO::VariableType::VolumeVariable;
|
||||
IonFluxAdvective[3 * ion + 1]->type =
|
||||
IO::VariableType::VolumeVariable;
|
||||
IonFluxAdvective[3 * ion + 1]->dim = 1;
|
||||
IonFluxAdvective[3*ion+1]->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2);
|
||||
IonFluxAdvective[3 * ion + 1]->data.resize(Dm->Nx - 2, Dm->Ny - 2,
|
||||
Dm->Nz - 2);
|
||||
visData[0].vars.push_back(IonFluxAdvective[3 * ion + 1]);
|
||||
// z-component of advective flux
|
||||
sprintf(VisName, "Ion%zu_FluxAdvective_z", ion + 1);
|
||||
IonFluxAdvective[3 * ion + 2]->name = VisName;
|
||||
IonFluxAdvective[3*ion+2]->type = IO::VariableType::VolumeVariable;
|
||||
IonFluxAdvective[3 * ion + 2]->type =
|
||||
IO::VariableType::VolumeVariable;
|
||||
IonFluxAdvective[3 * ion + 2]->dim = 1;
|
||||
IonFluxAdvective[3*ion+2]->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2);
|
||||
IonFluxAdvective[3 * ion + 2]->data.resize(Dm->Nx - 2, Dm->Ny - 2,
|
||||
Dm->Nz - 2);
|
||||
visData[0].vars.push_back(IonFluxAdvective[3 * ion + 2]);
|
||||
}
|
||||
}
|
||||
|
@ -308,23 +357,29 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P
|
|||
// x-component of electro-migrational flux
|
||||
sprintf(VisName, "Ion%zu_FluxElectrical_x", ion + 1);
|
||||
IonFluxElectrical[3 * ion + 0]->name = VisName;
|
||||
IonFluxElectrical[3*ion+0]->type = IO::VariableType::VolumeVariable;
|
||||
IonFluxElectrical[3 * ion + 0]->type =
|
||||
IO::VariableType::VolumeVariable;
|
||||
IonFluxElectrical[3 * ion + 0]->dim = 1;
|
||||
IonFluxElectrical[3*ion+0]->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2);
|
||||
IonFluxElectrical[3 * ion + 0]->data.resize(Dm->Nx - 2, Dm->Ny - 2,
|
||||
Dm->Nz - 2);
|
||||
visData[0].vars.push_back(IonFluxElectrical[3 * ion + 0]);
|
||||
// y-component of electro-migrational flux
|
||||
sprintf(VisName, "Ion%zu_FluxElectrical_y", ion + 1);
|
||||
IonFluxElectrical[3 * ion + 1]->name = VisName;
|
||||
IonFluxElectrical[3*ion+1]->type = IO::VariableType::VolumeVariable;
|
||||
IonFluxElectrical[3 * ion + 1]->type =
|
||||
IO::VariableType::VolumeVariable;
|
||||
IonFluxElectrical[3 * ion + 1]->dim = 1;
|
||||
IonFluxElectrical[3*ion+1]->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2);
|
||||
IonFluxElectrical[3 * ion + 1]->data.resize(Dm->Nx - 2, Dm->Ny - 2,
|
||||
Dm->Nz - 2);
|
||||
visData[0].vars.push_back(IonFluxElectrical[3 * ion + 1]);
|
||||
// z-component of electro-migrational flux
|
||||
sprintf(VisName, "Ion%zu_FluxElectrical_z", ion + 1);
|
||||
IonFluxElectrical[3 * ion + 2]->name = VisName;
|
||||
IonFluxElectrical[3*ion+2]->type = IO::VariableType::VolumeVariable;
|
||||
IonFluxElectrical[3 * ion + 2]->type =
|
||||
IO::VariableType::VolumeVariable;
|
||||
IonFluxElectrical[3 * ion + 2]->dim = 1;
|
||||
IonFluxElectrical[3*ion+2]->data.resize(Dm->Nx-2,Dm->Ny-2,Dm->Nz-2);
|
||||
IonFluxElectrical[3 * ion + 2]->data.resize(Dm->Nx - 2, Dm->Ny - 2,
|
||||
Dm->Nz - 2);
|
||||
visData[0].vars.push_back(IonFluxElectrical[3 * ion + 2]);
|
||||
}
|
||||
}
|
||||
|
@ -361,20 +416,27 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P
|
|||
sprintf(VisName, "IonConcentration_%zu", ion + 1);
|
||||
//IonConcentration[ion]->name = VisName;
|
||||
ASSERT(visData[0].vars[1 + ion]->name == VisName);
|
||||
Array<double>& IonConcentrationData = visData[0].vars[1+ion]->data;
|
||||
Array<double> &IonConcentrationData =
|
||||
visData[0].vars[1 + ion]->data;
|
||||
Ion.getIonConcentration(Rho, ion);
|
||||
fillData.copy(Rho, IonConcentrationData);
|
||||
}
|
||||
}
|
||||
|
||||
if (vis_db->getWithDefault<bool>("save_velocity", false)) {
|
||||
ASSERT(visData[0].vars[1+Ion.number_ion_species+0]->name=="Velocity_x");
|
||||
ASSERT(visData[0].vars[1+Ion.number_ion_species+1]->name=="Velocity_y");
|
||||
ASSERT(visData[0].vars[1+Ion.number_ion_species+2]->name=="Velocity_z");
|
||||
ASSERT(visData[0].vars[1 + Ion.number_ion_species + 0]->name ==
|
||||
"Velocity_x");
|
||||
ASSERT(visData[0].vars[1 + Ion.number_ion_species + 1]->name ==
|
||||
"Velocity_y");
|
||||
ASSERT(visData[0].vars[1 + Ion.number_ion_species + 2]->name ==
|
||||
"Velocity_z");
|
||||
Stokes.getVelocity(Vel_x, Vel_y, Vel_z);
|
||||
Array<double>& VelxData = visData[0].vars[1+Ion.number_ion_species+0]->data;
|
||||
Array<double>& VelyData = visData[0].vars[1+Ion.number_ion_species+1]->data;
|
||||
Array<double>& VelzData = visData[0].vars[1+Ion.number_ion_species+2]->data;
|
||||
Array<double> &VelxData =
|
||||
visData[0].vars[1 + Ion.number_ion_species + 0]->data;
|
||||
Array<double> &VelyData =
|
||||
visData[0].vars[1 + Ion.number_ion_species + 1]->data;
|
||||
Array<double> &VelzData =
|
||||
visData[0].vars[1 + Ion.number_ion_species + 2]->data;
|
||||
fillData.copy(Vel_x, VelxData);
|
||||
fillData.copy(Vel_y, VelyData);
|
||||
fillData.copy(Vel_z, VelzData);
|
||||
|
@ -386,20 +448,30 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P
|
|||
// x-component of diffusive flux
|
||||
sprintf(VisName, "Ion%zu_FluxDiffusive_x", ion + 1);
|
||||
//IonFluxDiffusive[3*ion+0]->name = VisName;
|
||||
ASSERT(visData[0].vars[4+Ion.number_ion_species+3*ion+0]->name==VisName);
|
||||
ASSERT(visData[0]
|
||||
.vars[4 + Ion.number_ion_species + 3 * ion + 0]
|
||||
->name == VisName);
|
||||
// y-component of diffusive flux
|
||||
sprintf(VisName, "Ion%zu_FluxDiffusive_y", ion + 1);
|
||||
//IonFluxDiffusive[3*ion+1]->name = VisName;
|
||||
ASSERT(visData[0].vars[4+Ion.number_ion_species+3*ion+1]->name==VisName);
|
||||
ASSERT(visData[0]
|
||||
.vars[4 + Ion.number_ion_species + 3 * ion + 1]
|
||||
->name == VisName);
|
||||
// z-component of diffusive flux
|
||||
sprintf(VisName, "Ion%zu_FluxDiffusive_z", ion + 1);
|
||||
//IonFluxDiffusive[3*ion+2]->name = VisName;
|
||||
ASSERT(visData[0].vars[4+Ion.number_ion_species+3*ion+2]->name==VisName);
|
||||
ASSERT(visData[0]
|
||||
.vars[4 + Ion.number_ion_species + 3 * ion + 2]
|
||||
->name == VisName);
|
||||
|
||||
Array<double>& IonFluxData_x = visData[0].vars[4+Ion.number_ion_species+3*ion+0]->data;
|
||||
Array<double>& IonFluxData_y = visData[0].vars[4+Ion.number_ion_species+3*ion+1]->data;
|
||||
Array<double>& IonFluxData_z = visData[0].vars[4+Ion.number_ion_species+3*ion+2]->data;
|
||||
Ion.getIonFluxDiffusive(IonFluxDiffusive_x,IonFluxDiffusive_y,IonFluxDiffusive_z,ion);
|
||||
Array<double> &IonFluxData_x =
|
||||
visData[0].vars[4 + Ion.number_ion_species + 3 * ion + 0]->data;
|
||||
Array<double> &IonFluxData_y =
|
||||
visData[0].vars[4 + Ion.number_ion_species + 3 * ion + 1]->data;
|
||||
Array<double> &IonFluxData_z =
|
||||
visData[0].vars[4 + Ion.number_ion_species + 3 * ion + 2]->data;
|
||||
Ion.getIonFluxDiffusive(IonFluxDiffusive_x, IonFluxDiffusive_y,
|
||||
IonFluxDiffusive_z, ion);
|
||||
fillData.copy(IonFluxDiffusive_x, IonFluxData_x);
|
||||
fillData.copy(IonFluxDiffusive_y, IonFluxData_y);
|
||||
fillData.copy(IonFluxDiffusive_z, IonFluxData_z);
|
||||
|
@ -412,20 +484,36 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P
|
|||
// x-component of diffusive flux
|
||||
sprintf(VisName, "Ion%zu_FluxAdvective_x", ion + 1);
|
||||
//IonFluxDiffusive[3*ion+0]->name = VisName;
|
||||
ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+3)+3*ion+0]->name==VisName);
|
||||
ASSERT(visData[0]
|
||||
.vars[4 + Ion.number_ion_species * (1 + 3) + 3 * ion + 0]
|
||||
->name == VisName);
|
||||
// y-component of diffusive flux
|
||||
sprintf(VisName, "Ion%zu_FluxAdvective_y", ion + 1);
|
||||
//IonFluxDiffusive[3*ion+1]->name = VisName;
|
||||
ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+3)+3*ion+1]->name==VisName);
|
||||
ASSERT(visData[0]
|
||||
.vars[4 + Ion.number_ion_species * (1 + 3) + 3 * ion + 1]
|
||||
->name == VisName);
|
||||
// z-component of diffusive flux
|
||||
sprintf(VisName, "Ion%zu_FluxAdvective_z", ion + 1);
|
||||
//IonFluxDiffusive[3*ion+2]->name = VisName;
|
||||
ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+3)+3*ion+2]->name==VisName);
|
||||
ASSERT(visData[0]
|
||||
.vars[4 + Ion.number_ion_species * (1 + 3) + 3 * ion + 2]
|
||||
->name == VisName);
|
||||
|
||||
Array<double>& IonFluxData_x = visData[0].vars[4+Ion.number_ion_species*(1+3)+3*ion+0]->data;
|
||||
Array<double>& IonFluxData_y = visData[0].vars[4+Ion.number_ion_species*(1+3)+3*ion+1]->data;
|
||||
Array<double>& IonFluxData_z = visData[0].vars[4+Ion.number_ion_species*(1+3)+3*ion+2]->data;
|
||||
Ion.getIonFluxAdvective(IonFluxAdvective_x,IonFluxAdvective_y,IonFluxAdvective_z,ion);
|
||||
Array<double> &IonFluxData_x =
|
||||
visData[0]
|
||||
.vars[4 + Ion.number_ion_species * (1 + 3) + 3 * ion + 0]
|
||||
->data;
|
||||
Array<double> &IonFluxData_y =
|
||||
visData[0]
|
||||
.vars[4 + Ion.number_ion_species * (1 + 3) + 3 * ion + 1]
|
||||
->data;
|
||||
Array<double> &IonFluxData_z =
|
||||
visData[0]
|
||||
.vars[4 + Ion.number_ion_species * (1 + 3) + 3 * ion + 2]
|
||||
->data;
|
||||
Ion.getIonFluxAdvective(IonFluxAdvective_x, IonFluxAdvective_y,
|
||||
IonFluxAdvective_z, ion);
|
||||
fillData.copy(IonFluxAdvective_x, IonFluxData_x);
|
||||
fillData.copy(IonFluxAdvective_y, IonFluxData_y);
|
||||
fillData.copy(IonFluxAdvective_z, IonFluxData_z);
|
||||
|
@ -438,20 +526,36 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P
|
|||
// x-component of diffusive flux
|
||||
sprintf(VisName, "Ion%zu_FluxElectrical_x", ion + 1);
|
||||
//IonFluxDiffusive[3*ion+0]->name = VisName;
|
||||
ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+6)+3*ion+0]->name==VisName);
|
||||
ASSERT(visData[0]
|
||||
.vars[4 + Ion.number_ion_species * (1 + 6) + 3 * ion + 0]
|
||||
->name == VisName);
|
||||
// y-component of diffusive flux
|
||||
sprintf(VisName, "Ion%zu_FluxElectrical_y", ion + 1);
|
||||
//IonFluxDiffusive[3*ion+1]->name = VisName;
|
||||
ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+6)+3*ion+1]->name==VisName);
|
||||
ASSERT(visData[0]
|
||||
.vars[4 + Ion.number_ion_species * (1 + 6) + 3 * ion + 1]
|
||||
->name == VisName);
|
||||
// z-component of diffusive flux
|
||||
sprintf(VisName, "Ion%zu_FluxElectrical_z", ion + 1);
|
||||
//IonFluxDiffusive[3*ion+2]->name = VisName;
|
||||
ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+6)+3*ion+2]->name==VisName);
|
||||
ASSERT(visData[0]
|
||||
.vars[4 + Ion.number_ion_species * (1 + 6) + 3 * ion + 2]
|
||||
->name == VisName);
|
||||
|
||||
Array<double>& IonFluxData_x = visData[0].vars[4+Ion.number_ion_species*(1+6)+3*ion+0]->data;
|
||||
Array<double>& IonFluxData_y = visData[0].vars[4+Ion.number_ion_species*(1+6)+3*ion+1]->data;
|
||||
Array<double>& IonFluxData_z = visData[0].vars[4+Ion.number_ion_species*(1+6)+3*ion+2]->data;
|
||||
Ion.getIonFluxElectrical(IonFluxElectrical_x,IonFluxElectrical_y,IonFluxElectrical_z,ion);
|
||||
Array<double> &IonFluxData_x =
|
||||
visData[0]
|
||||
.vars[4 + Ion.number_ion_species * (1 + 6) + 3 * ion + 0]
|
||||
->data;
|
||||
Array<double> &IonFluxData_y =
|
||||
visData[0]
|
||||
.vars[4 + Ion.number_ion_species * (1 + 6) + 3 * ion + 1]
|
||||
->data;
|
||||
Array<double> &IonFluxData_z =
|
||||
visData[0]
|
||||
.vars[4 + Ion.number_ion_species * (1 + 6) + 3 * ion + 2]
|
||||
->data;
|
||||
Ion.getIonFluxElectrical(IonFluxElectrical_x, IonFluxElectrical_y,
|
||||
IonFluxElectrical_z, ion);
|
||||
fillData.copy(IonFluxElectrical_x, IonFluxData_x);
|
||||
fillData.copy(IonFluxElectrical_y, IonFluxData_y);
|
||||
fillData.copy(IonFluxElectrical_z, IonFluxData_z);
|
||||
|
@ -459,13 +563,23 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P
|
|||
}
|
||||
|
||||
if (vis_db->getWithDefault<bool>("save_electric_field", false)) {
|
||||
ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+9)+0]->name=="ElectricField_x");
|
||||
ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+9)+1]->name=="ElectricField_y");
|
||||
ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+9)+2]->name=="ElectricField_z");
|
||||
Poisson.getElectricField(ElectricalField_x, ElectricalField_y, ElectricalField_z);
|
||||
Array<double>& ElectricalFieldxData = visData[0].vars[4+Ion.number_ion_species*(1+9)+0]->data;
|
||||
Array<double>& ElectricalFieldyData = visData[0].vars[4+Ion.number_ion_species*(1+9)+1]->data;
|
||||
Array<double>& ElectricalFieldzData = visData[0].vars[4+Ion.number_ion_species*(1+9)+2]->data;
|
||||
ASSERT(
|
||||
visData[0].vars[4 + Ion.number_ion_species * (1 + 9) + 0]->name ==
|
||||
"ElectricField_x");
|
||||
ASSERT(
|
||||
visData[0].vars[4 + Ion.number_ion_species * (1 + 9) + 1]->name ==
|
||||
"ElectricField_y");
|
||||
ASSERT(
|
||||
visData[0].vars[4 + Ion.number_ion_species * (1 + 9) + 2]->name ==
|
||||
"ElectricField_z");
|
||||
Poisson.getElectricField(ElectricalField_x, ElectricalField_y,
|
||||
ElectricalField_z);
|
||||
Array<double> &ElectricalFieldxData =
|
||||
visData[0].vars[4 + Ion.number_ion_species * (1 + 9) + 0]->data;
|
||||
Array<double> &ElectricalFieldyData =
|
||||
visData[0].vars[4 + Ion.number_ion_species * (1 + 9) + 1]->data;
|
||||
Array<double> &ElectricalFieldzData =
|
||||
visData[0].vars[4 + Ion.number_ion_species * (1 + 9) + 2]->data;
|
||||
fillData.copy(ElectricalField_x, ElectricalFieldxData);
|
||||
fillData.copy(ElectricalField_y, ElectricalFieldyData);
|
||||
fillData.copy(ElectricalField_z, ElectricalFieldzData);
|
||||
|
|
|
@ -57,11 +57,13 @@ public:
|
|||
~ElectroChemistryAnalyzer();
|
||||
|
||||
void SetParams();
|
||||
void Basic( ScaLBL_IonModel &Ion, ScaLBL_Poisson &Poisson, ScaLBL_StokesModel &Stokes, int timestep);
|
||||
void WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &Poisson, ScaLBL_StokesModel &Stokes, std::shared_ptr<Database> input_db, int timestep);
|
||||
void Basic(ScaLBL_IonModel &Ion, ScaLBL_Poisson &Poisson,
|
||||
ScaLBL_StokesModel &Stokes, int timestep);
|
||||
void WriteVis(ScaLBL_IonModel &Ion, ScaLBL_Poisson &Poisson,
|
||||
ScaLBL_StokesModel &Stokes,
|
||||
std::shared_ptr<Database> input_db, int timestep);
|
||||
|
||||
private:
|
||||
FILE *TIMELOG;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -11,8 +11,10 @@ FlowAdaptor::FlowAdaptor(ScaLBL_ColorModel &M){
|
|||
timestep = -1;
|
||||
timestep_previous = -1;
|
||||
|
||||
phi.resize(Nx,Ny,Nz); phi.fill(0); // phase indicator field
|
||||
phi_t.resize(Nx,Ny,Nz); phi_t.fill(0); // time derivative for the phase indicator field
|
||||
phi.resize(Nx, Ny, Nz);
|
||||
phi.fill(0); // phase indicator field
|
||||
phi_t.resize(Nx, Ny, Nz);
|
||||
phi_t.fill(0); // time derivative for the phase indicator field
|
||||
}
|
||||
|
||||
FlowAdaptor::~FlowAdaptor() {
|
||||
|
@ -21,11 +23,16 @@ FlowAdaptor::~FlowAdaptor(){
|
|||
|
||||
double FlowAdaptor::ImageInit(ScaLBL_ColorModel &M, std::string Filename) {
|
||||
int rank = M.rank;
|
||||
int Nx = M.Nx; int Ny = M.Ny; int Nz = M.Nz;
|
||||
if (rank==0) printf("Re-initializing fluids from file: %s \n", Filename.c_str());
|
||||
int Nx = M.Nx;
|
||||
int Ny = M.Ny;
|
||||
int Nz = M.Nz;
|
||||
if (rank == 0)
|
||||
printf("Re-initializing fluids from file: %s \n", Filename.c_str());
|
||||
M.Mask->Decomp(Filename);
|
||||
for (int i=0; i<Nx*Ny*Nz; i++) M.id[i] = M.Mask->id[i]; // save what was read
|
||||
for (int i=0; i<Nx*Ny*Nz; i++) M.Dm->id[i] = M.Mask->id[i]; // save what was read
|
||||
for (int i = 0; i < Nx * Ny * Nz; i++)
|
||||
M.id[i] = M.Mask->id[i]; // save what was read
|
||||
for (int i = 0; i < Nx * Ny * Nz; i++)
|
||||
M.Dm->id[i] = M.Mask->id[i]; // save what was read
|
||||
|
||||
double *PhaseLabel;
|
||||
PhaseLabel = new double[Nx * Ny * Nz];
|
||||
|
@ -39,8 +46,7 @@ double FlowAdaptor::ImageInit(ScaLBL_ColorModel &M, std::string Filename){
|
|||
if (M.id[Nx * Ny * k + Nx * j + i] == 2) {
|
||||
PoreCount++;
|
||||
Count++;
|
||||
}
|
||||
else if (M.id[Nx*Ny*k+Nx*j+i] == 1){
|
||||
} else if (M.id[Nx * Ny * k + Nx * j + i] == 1) {
|
||||
PoreCount++;
|
||||
}
|
||||
}
|
||||
|
@ -50,30 +56,38 @@ double FlowAdaptor::ImageInit(ScaLBL_ColorModel &M, std::string Filename){
|
|||
Count = M.Dm->Comm.sumReduce(Count);
|
||||
PoreCount = M.Dm->Comm.sumReduce(PoreCount);
|
||||
|
||||
if (rank==0) printf(" new saturation: %f (%f / %f) \n", Count / PoreCount, Count, PoreCount);
|
||||
if (rank == 0)
|
||||
printf(" new saturation: %f (%f / %f) \n", Count / PoreCount, Count,
|
||||
PoreCount);
|
||||
ScaLBL_CopyToDevice(M.Phi, PhaseLabel, Nx * Ny * Nz * sizeof(double));
|
||||
M.Dm->Comm.barrier();
|
||||
|
||||
ScaLBL_D3Q19_Init(M.fq, M.Np);
|
||||
ScaLBL_PhaseField_Init(M.dvcMap, M.Phi, M.Den, M.Aq, M.Bq, 0, M.ScaLBL_Comm->LastExterior(), M.Np);
|
||||
ScaLBL_PhaseField_Init(M.dvcMap, M.Phi, M.Den, M.Aq, M.Bq, M.ScaLBL_Comm->FirstInterior(), M.ScaLBL_Comm->LastInterior(), M.Np);
|
||||
ScaLBL_PhaseField_Init(M.dvcMap, M.Phi, M.Den, M.Aq, M.Bq, 0,
|
||||
M.ScaLBL_Comm->LastExterior(), M.Np);
|
||||
ScaLBL_PhaseField_Init(M.dvcMap, M.Phi, M.Den, M.Aq, M.Bq,
|
||||
M.ScaLBL_Comm->FirstInterior(),
|
||||
M.ScaLBL_Comm->LastInterior(), M.Np);
|
||||
M.Dm->Comm.barrier();
|
||||
|
||||
ScaLBL_CopyToHost(M.Averages->Phi.data(),M.Phi,Nx*Ny*Nz*sizeof(double));
|
||||
ScaLBL_CopyToHost(M.Averages->Phi.data(), M.Phi,
|
||||
Nx * Ny * Nz * sizeof(double));
|
||||
|
||||
delete PhaseLabel;
|
||||
double saturation = Count / PoreCount;
|
||||
return saturation;
|
||||
}
|
||||
|
||||
|
||||
double FlowAdaptor::UpdateFractionalFlow(ScaLBL_ColorModel &M) {
|
||||
|
||||
double MASS_FRACTION_CHANGE = 0.006;
|
||||
double FRACTIONAL_FLOW_EPSILON = 5e-6;
|
||||
if (M.db->keyExists("FlowAdaptor")) {
|
||||
auto flow_db = M.db->getDatabase("FlowAdaptor");
|
||||
MASS_FRACTION_CHANGE = flow_db->getWithDefault<double>( "mass_fraction_factor", 0.006);
|
||||
FRACTIONAL_FLOW_EPSILON = flow_db->getWithDefault<double>( "fractional_flow_epsilon", 5e-6);
|
||||
MASS_FRACTION_CHANGE =
|
||||
flow_db->getWithDefault<double>("mass_fraction_factor", 0.006);
|
||||
FRACTIONAL_FLOW_EPSILON =
|
||||
flow_db->getWithDefault<double>("fractional_flow_epsilon", 5e-6);
|
||||
}
|
||||
int Np = M.Np;
|
||||
double dA, dB, phi;
|
||||
|
@ -96,7 +110,9 @@ double FlowAdaptor::UpdateFractionalFlow(ScaLBL_ColorModel &M){
|
|||
ScaLBL_CopyToHost(Vel_y, &M.Velocity[Np], Np * sizeof(double));
|
||||
ScaLBL_CopyToHost(Vel_z, &M.Velocity[2 * Np], Np * sizeof(double));
|
||||
|
||||
int Nx = M.Nx; int Ny = M.Ny; int Nz = M.Nz;
|
||||
int Nx = M.Nx;
|
||||
int Ny = M.Ny;
|
||||
int Nz = M.Nz;
|
||||
|
||||
mass_a = mass_b = 0.0;
|
||||
double maxSpeed = 0.0;
|
||||
|
@ -110,8 +126,12 @@ double FlowAdaptor::UpdateFractionalFlow(ScaLBL_ColorModel &M){
|
|||
int n = M.Map(i, j, k);
|
||||
//double distance = M.Averages->SDs(i,j,k);
|
||||
if (!(n < 0)) {
|
||||
dA = Aq_tmp[n] + Aq_tmp[n+Np] + Aq_tmp[n+2*Np] + Aq_tmp[n+3*Np] + Aq_tmp[n+4*Np] + Aq_tmp[n+5*Np] + Aq_tmp[n+6*Np];
|
||||
dB = Bq_tmp[n] + Bq_tmp[n+Np] + Bq_tmp[n+2*Np] + Bq_tmp[n+3*Np] + Bq_tmp[n+4*Np] + Bq_tmp[n+5*Np] + Bq_tmp[n+6*Np];
|
||||
dA = Aq_tmp[n] + Aq_tmp[n + Np] + Aq_tmp[n + 2 * Np] +
|
||||
Aq_tmp[n + 3 * Np] + Aq_tmp[n + 4 * Np] +
|
||||
Aq_tmp[n + 5 * Np] + Aq_tmp[n + 6 * Np];
|
||||
dB = Bq_tmp[n] + Bq_tmp[n + Np] + Bq_tmp[n + 2 * Np] +
|
||||
Bq_tmp[n + 3 * Np] + Bq_tmp[n + 4 * Np] +
|
||||
Bq_tmp[n + 5 * Np] + Bq_tmp[n + 6 * Np];
|
||||
phi = (dA - dB) / (dA + dB);
|
||||
Phase[n] = phi;
|
||||
mass_a += dA;
|
||||
|
@ -120,11 +140,11 @@ double FlowAdaptor::UpdateFractionalFlow(ScaLBL_ColorModel &M){
|
|||
vy = Vel_y[n];
|
||||
vz = Vel_z[n];
|
||||
double local_momentum = sqrt(vx * vx + vy * vy + vz * vz);
|
||||
double local_weight = (FRACTIONAL_FLOW_EPSILON + local_momentum);
|
||||
double local_weight =
|
||||
(FRACTIONAL_FLOW_EPSILON + local_momentum);
|
||||
if (phi > 0.0) {
|
||||
sum_weights_A += local_weight * dA;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sum_weights_B += local_weight * dB;
|
||||
}
|
||||
if (local_momentum > localMaxSpeed) {
|
||||
|
@ -145,7 +165,8 @@ double FlowAdaptor::UpdateFractionalFlow(ScaLBL_ColorModel &M){
|
|||
//double total_momentum_A = sqrt(vax_global*vax_global+vay_global*vay_global+vaz_global*vaz_global);
|
||||
//double total_momentum_B = sqrt(vbx_global*vbx_global+vby_global*vby_global+vbz_global*vbz_global);
|
||||
/* compute the total mass change */
|
||||
double TOTAL_MASS_CHANGE = MASS_FRACTION_CHANGE*(mass_a_global + mass_b_global);
|
||||
double TOTAL_MASS_CHANGE =
|
||||
MASS_FRACTION_CHANGE * (mass_a_global + mass_b_global);
|
||||
if (fabs(TOTAL_MASS_CHANGE) > 0.1 * mass_a_global)
|
||||
TOTAL_MASS_CHANGE = 0.1 * mass_a_global;
|
||||
if (fabs(TOTAL_MASS_CHANGE) > 0.1 * mass_b_global)
|
||||
|
@ -165,29 +186,42 @@ double FlowAdaptor::UpdateFractionalFlow(ScaLBL_ColorModel &M){
|
|||
vy = Vel_y[n];
|
||||
vz = Vel_z[n];
|
||||
double local_momentum = sqrt(vx * vx + vy * vy + vz * vz);
|
||||
double local_weight = (FRACTIONAL_FLOW_EPSILON + local_momentum)/(FRACTIONAL_FLOW_EPSILON + maxSpeed);
|
||||
double local_weight =
|
||||
(FRACTIONAL_FLOW_EPSILON + local_momentum) /
|
||||
(FRACTIONAL_FLOW_EPSILON + maxSpeed);
|
||||
/* impose ceiling for spurious currents */
|
||||
//if (local_momentum > maxSpeed) local_momentum = maxSpeed;
|
||||
if (phi > 0.0) {
|
||||
LOCAL_MASS_CHANGE = MASS_FACTOR_A * local_weight;
|
||||
Aq_tmp[n] -= 0.3333333333333333 * LOCAL_MASS_CHANGE;
|
||||
Aq_tmp[n+Np] -= 0.1111111111111111*LOCAL_MASS_CHANGE;
|
||||
Aq_tmp[n+2*Np] -= 0.1111111111111111*LOCAL_MASS_CHANGE;
|
||||
Aq_tmp[n+3*Np] -= 0.1111111111111111*LOCAL_MASS_CHANGE;
|
||||
Aq_tmp[n+4*Np] -= 0.1111111111111111*LOCAL_MASS_CHANGE;
|
||||
Aq_tmp[n+5*Np] -= 0.1111111111111111*LOCAL_MASS_CHANGE;
|
||||
Aq_tmp[n+6*Np] -= 0.1111111111111111*LOCAL_MASS_CHANGE;
|
||||
Aq_tmp[n + Np] -=
|
||||
0.1111111111111111 * LOCAL_MASS_CHANGE;
|
||||
Aq_tmp[n + 2 * Np] -=
|
||||
0.1111111111111111 * LOCAL_MASS_CHANGE;
|
||||
Aq_tmp[n + 3 * Np] -=
|
||||
0.1111111111111111 * LOCAL_MASS_CHANGE;
|
||||
Aq_tmp[n + 4 * Np] -=
|
||||
0.1111111111111111 * LOCAL_MASS_CHANGE;
|
||||
Aq_tmp[n + 5 * Np] -=
|
||||
0.1111111111111111 * LOCAL_MASS_CHANGE;
|
||||
Aq_tmp[n + 6 * Np] -=
|
||||
0.1111111111111111 * LOCAL_MASS_CHANGE;
|
||||
//DebugMassA[n] = (-1.0)*LOCAL_MASS_CHANGE;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
LOCAL_MASS_CHANGE = MASS_FACTOR_B * local_weight;
|
||||
Bq_tmp[n] += 0.3333333333333333 * LOCAL_MASS_CHANGE;
|
||||
Bq_tmp[n+Np] += 0.1111111111111111*LOCAL_MASS_CHANGE;
|
||||
Bq_tmp[n+2*Np] += 0.1111111111111111*LOCAL_MASS_CHANGE;
|
||||
Bq_tmp[n+3*Np] += 0.1111111111111111*LOCAL_MASS_CHANGE;
|
||||
Bq_tmp[n+4*Np] += 0.1111111111111111*LOCAL_MASS_CHANGE;
|
||||
Bq_tmp[n+5*Np] += 0.1111111111111111*LOCAL_MASS_CHANGE;
|
||||
Bq_tmp[n+6*Np] += 0.1111111111111111*LOCAL_MASS_CHANGE;
|
||||
Bq_tmp[n + Np] +=
|
||||
0.1111111111111111 * LOCAL_MASS_CHANGE;
|
||||
Bq_tmp[n + 2 * Np] +=
|
||||
0.1111111111111111 * LOCAL_MASS_CHANGE;
|
||||
Bq_tmp[n + 3 * Np] +=
|
||||
0.1111111111111111 * LOCAL_MASS_CHANGE;
|
||||
Bq_tmp[n + 4 * Np] +=
|
||||
0.1111111111111111 * LOCAL_MASS_CHANGE;
|
||||
Bq_tmp[n + 5 * Np] +=
|
||||
0.1111111111111111 * LOCAL_MASS_CHANGE;
|
||||
Bq_tmp[n + 6 * Np] +=
|
||||
0.1111111111111111 * LOCAL_MASS_CHANGE;
|
||||
//DebugMassB[n] = LOCAL_MASS_CHANGE;
|
||||
}
|
||||
}
|
||||
|
@ -195,27 +229,41 @@ double FlowAdaptor::UpdateFractionalFlow(ScaLBL_ColorModel &M){
|
|||
}
|
||||
}
|
||||
|
||||
if (M.rank == 0) printf("Update Fractional Flow: change mass of fluid B by %f \n",TOTAL_MASS_CHANGE/mass_b_global);
|
||||
if (M.rank == 0)
|
||||
printf("Update Fractional Flow: change mass of fluid B by %f \n",
|
||||
TOTAL_MASS_CHANGE / mass_b_global);
|
||||
|
||||
// Need to initialize Aq, Bq, Den, Phi directly
|
||||
//ScaLBL_CopyToDevice(Phi,phase.data(),7*Np*sizeof(double));
|
||||
ScaLBL_CopyToDevice(M.Aq, Aq_tmp, 7 * Np * sizeof(double));
|
||||
ScaLBL_CopyToDevice(M.Bq, Bq_tmp, 7 * Np * sizeof(double));
|
||||
|
||||
delete Aq_tmp;
|
||||
delete Bq_tmp;
|
||||
delete Vel_x;
|
||||
delete Vel_y;
|
||||
delete Vel_z;
|
||||
delete Phase;
|
||||
|
||||
return (TOTAL_MASS_CHANGE);
|
||||
}
|
||||
|
||||
void FlowAdaptor::Flatten(ScaLBL_ColorModel &M) {
|
||||
|
||||
ScaLBL_D3Q19_Init(M.fq, M.Np);
|
||||
ScaLBL_PhaseField_Init(M.dvcMap, M.Phi, M.Den, M.Aq, M.Bq, 0, M.ScaLBL_Comm->LastExterior(), M.Np);
|
||||
ScaLBL_PhaseField_Init(M.dvcMap, M.Phi, M.Den, M.Aq, M.Bq, M.ScaLBL_Comm->FirstInterior(), M.ScaLBL_Comm->LastInterior(), M.Np);
|
||||
ScaLBL_PhaseField_Init(M.dvcMap, M.Phi, M.Den, M.Aq, M.Bq, 0,
|
||||
M.ScaLBL_Comm->LastExterior(), M.Np);
|
||||
ScaLBL_PhaseField_Init(M.dvcMap, M.Phi, M.Den, M.Aq, M.Bq,
|
||||
M.ScaLBL_Comm->FirstInterior(),
|
||||
M.ScaLBL_Comm->LastInterior(), M.Np);
|
||||
}
|
||||
|
||||
double FlowAdaptor::MoveInterface(ScaLBL_ColorModel &M) {
|
||||
|
||||
double INTERFACE_CUTOFF = M.color_db->getWithDefault<double>( "move_interface_cutoff", 0.1 );
|
||||
double MOVE_INTERFACE_FACTOR = M.color_db->getWithDefault<double>( "move_interface_factor", 10.0 );
|
||||
double INTERFACE_CUTOFF =
|
||||
M.color_db->getWithDefault<double>("move_interface_cutoff", 0.1);
|
||||
double MOVE_INTERFACE_FACTOR =
|
||||
M.color_db->getWithDefault<double>("move_interface_factor", 10.0);
|
||||
|
||||
ScaLBL_CopyToHost(phi.data(), M.Phi, Nx * Ny * Nz * sizeof(double));
|
||||
/* compute the local derivative of phase indicator field */
|
||||
|
@ -230,13 +278,16 @@ double FlowAdaptor::MoveInterface(ScaLBL_ColorModel &M){
|
|||
double value2 = phi(n);
|
||||
double dist2 = factor * log((1.0 + value2) / (1.0 - value2));
|
||||
phi_t(n) = value2;
|
||||
if (value1 < INTERFACE_CUTOFF && value1 > -1*INTERFACE_CUTOFF && value2 < INTERFACE_CUTOFF && value2 > -1*INTERFACE_CUTOFF ){
|
||||
if (value1 < INTERFACE_CUTOFF && value1 > -1 * INTERFACE_CUTOFF &&
|
||||
value2 < INTERFACE_CUTOFF && value2 > -1 * INTERFACE_CUTOFF) {
|
||||
/* time derivative of distance */
|
||||
double dxdt = 0.125 * (dist2 - dist1);
|
||||
/* extrapolate to move the distance further */
|
||||
double dist3 = dist2 + MOVE_INTERFACE_FACTOR * dxdt;
|
||||
/* compute the new phase interface */
|
||||
phi_t(n) = (2.f*(exp(-2.f*beta*(dist3)))/(1.f+exp(-2.f*beta*(dist3))) - 1.f);
|
||||
phi_t(n) = (2.f * (exp(-2.f * beta * (dist3))) /
|
||||
(1.f + exp(-2.f * beta * (dist3))) -
|
||||
1.f);
|
||||
total_interface_displacement += fabs(MOVE_INTERFACE_FACTOR * dxdt);
|
||||
total_interface_sites += 1.0;
|
||||
}
|
||||
|
@ -245,11 +296,14 @@ double FlowAdaptor::MoveInterface(ScaLBL_ColorModel &M){
|
|||
return total_interface_sites;
|
||||
}
|
||||
|
||||
double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_delta_volume){
|
||||
double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M,
|
||||
const double target_delta_volume) {
|
||||
|
||||
const RankInfoStruct rank_info(M.rank, M.nprocx, M.nprocy, M.nprocz);
|
||||
auto rank = M.rank;
|
||||
auto Nx = M.Nx; auto Ny = M.Ny; auto Nz = M.Nz;
|
||||
auto Nx = M.Nx;
|
||||
auto Ny = M.Ny;
|
||||
auto Nz = M.Nz;
|
||||
auto N = Nx * Ny * Nz;
|
||||
double vF = 0.f;
|
||||
double vS = 0.f;
|
||||
|
@ -258,10 +312,12 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
|
|||
bool USE_CONNECTED_NWP = false;
|
||||
|
||||
DoubleArray phase(Nx, Ny, Nz);
|
||||
IntArray phase_label(Nx,Ny,Nz);;
|
||||
IntArray phase_label(Nx, Ny, Nz);
|
||||
;
|
||||
DoubleArray phase_distance(Nx, Ny, Nz);
|
||||
Array<char> phase_id(Nx, Ny, Nz);
|
||||
fillHalo<double> fillDouble(M.Dm->Comm,M.Dm->rank_info,{Nx-2,Ny-2,Nz-2},{1,1,1},0,1);
|
||||
fillHalo<double> fillDouble(M.Dm->Comm, M.Dm->rank_info,
|
||||
{Nx - 2, Ny - 2, Nz - 2}, {1, 1, 1}, 0, 1);
|
||||
|
||||
// Basic algorithm to
|
||||
// 1. Copy phase field to CPU
|
||||
|
@ -271,7 +327,8 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
|
|||
for (int k = 1; k < Nz - 1; k++) {
|
||||
for (int j = 1; j < Ny - 1; j++) {
|
||||
for (int i = 1; i < Nx - 1; i++) {
|
||||
if (phase(i,j,k) > 0.f && M.Averages->SDs(i,j,k) > 0.f) count+=1.f;
|
||||
if (phase(i, j, k) > 0.f && M.Averages->SDs(i, j, k) > 0.f)
|
||||
count += 1.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -287,7 +344,8 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
|
|||
double volume_connected = 0.0;
|
||||
double second_biggest = 0.0;
|
||||
if (USE_CONNECTED_NWP) {
|
||||
ComputeGlobalBlobIDs(Nx-2,Ny-2,Nz-2,rank_info,phase,M.Averages->SDs,vF,vS,phase_label,M.Dm->Comm);
|
||||
ComputeGlobalBlobIDs(Nx - 2, Ny - 2, Nz - 2, rank_info, phase,
|
||||
M.Averages->SDs, vF, vS, phase_label, M.Dm->Comm);
|
||||
M.Dm->Comm.barrier();
|
||||
|
||||
// only operate on component "0"ScaLBL_ColorModel &M,
|
||||
|
@ -300,8 +358,7 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
|
|||
if (label == 0) {
|
||||
phase_id(i, j, k) = 0;
|
||||
count += 1.0;
|
||||
}
|
||||
else
|
||||
} else
|
||||
phase_id(i, j, k) = 1;
|
||||
if (label == 1) {
|
||||
second_biggest += 1.0;
|
||||
|
@ -311,8 +368,7 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
|
|||
}
|
||||
volume_connected = M.Dm->Comm.sumReduce(count);
|
||||
second_biggest = M.Dm->Comm.sumReduce(second_biggest);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// use the whole NWP
|
||||
for (int k = 0; k < Nz; k++) {
|
||||
for (int j = 0; j < Ny; j++) {
|
||||
|
@ -320,12 +376,10 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
|
|||
if (M.Averages->SDs(i, j, k) > 0.f) {
|
||||
if (phase(i, j, k) > 0.f) {
|
||||
phase_id(i, j, k) = 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
phase_id(i, j, k) = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
phase_id(i, j, k) = 1;
|
||||
}
|
||||
}
|
||||
|
@ -343,8 +397,10 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
|
|||
for (int i = 0; i < Nx; i++) {
|
||||
if (phase_distance(i, j, k) < 3.f) {
|
||||
value = phase(i, j, k);
|
||||
if (value > 1.f) value=1.f;
|
||||
if (value < -1.f) value=-1.f;
|
||||
if (value > 1.f)
|
||||
value = 1.f;
|
||||
if (value < -1.f)
|
||||
value = -1.f;
|
||||
// temp -- distance based on analytical form McClure, Prins et al, Comp. Phys. Comm.
|
||||
temp = -factor * log((1.0 + value) / (1.0 - value));
|
||||
/// use this approximation close to the object
|
||||
|
@ -357,22 +413,30 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
|
|||
}
|
||||
}
|
||||
}
|
||||
if (rank == 0)
|
||||
printf("Pathway volume / next largest ganglion %f \n",
|
||||
volume_connected / second_biggest);
|
||||
|
||||
|
||||
if (rank==0) printf("Pathway volume / next largest ganglion %f \n",volume_connected/second_biggest );
|
||||
|
||||
if (rank==0) printf("MorphGrow with target volume fraction change %f \n", target_delta_volume/volume_initial);
|
||||
if (rank == 0)
|
||||
printf("MorphGrow with target volume fraction change %f \n",
|
||||
target_delta_volume / volume_initial);
|
||||
double target_delta_volume_incremental = target_delta_volume;
|
||||
if (fabs(target_delta_volume) > 0.01 * volume_initial)
|
||||
target_delta_volume_incremental = 0.01*volume_initial*target_delta_volume/fabs(target_delta_volume);
|
||||
target_delta_volume_incremental = 0.01 * volume_initial *
|
||||
target_delta_volume /
|
||||
fabs(target_delta_volume);
|
||||
|
||||
delta_volume = MorphGrow(M.Averages->SDs,phase_distance,phase_id,M.Averages->Dm, target_delta_volume_incremental, WallFactor);
|
||||
delta_volume =
|
||||
MorphGrow(M.Averages->SDs, phase_distance, phase_id, M.Averages->Dm,
|
||||
target_delta_volume_incremental, WallFactor);
|
||||
|
||||
for (int k = 0; k < Nz; k++) {
|
||||
for (int j = 0; j < Ny; j++) {
|
||||
for (int i = 0; i < Nx; i++) {
|
||||
if (phase_distance(i,j,k) < 0.0 ) phase_id(i,j,k) = 0;
|
||||
else phase_id(i,j,k) = 1;
|
||||
if (phase_distance(i, j, k) < 0.0)
|
||||
phase_id(i, j, k) = 0;
|
||||
else
|
||||
phase_id(i, j, k) = 1;
|
||||
//if (phase_distance(i,j,k) < 0.0 ) phase(i,j,k) = 1.0;
|
||||
}
|
||||
}
|
||||
|
@ -388,7 +452,9 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
|
|||
if (M.Averages->SDs(i, j, k) > 0.f) {
|
||||
if (d < 3.f) {
|
||||
//phase(i,j,k) = -1.0;
|
||||
phase(i,j,k) = (2.f*(exp(-2.f*M.beta*d))/(1.f+exp(-2.f*M.beta*d))-1.f);
|
||||
phase(i, j, k) = (2.f * (exp(-2.f * M.beta * d)) /
|
||||
(1.f + exp(-2.f * M.beta * d)) -
|
||||
1.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -409,18 +475,28 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
|
|||
double volume_final = M.Dm->Comm.sumReduce(count);
|
||||
|
||||
delta_volume = (volume_final - volume_initial);
|
||||
if (rank == 0) printf("Shell Aggregation: change fluid volume fraction by %f \n", delta_volume/volume_initial);
|
||||
if (rank == 0) printf(" new saturation = %f \n", volume_final/(M.Mask->Porosity()*double((Nx-2)*(Ny-2)*(Nz-2)*M.nprocs)));
|
||||
if (rank == 0)
|
||||
printf("Shell Aggregation: change fluid volume fraction by %f \n",
|
||||
delta_volume / volume_initial);
|
||||
if (rank == 0)
|
||||
printf(" new saturation = %f \n",
|
||||
volume_final /
|
||||
(M.Mask->Porosity() *
|
||||
double((Nx - 2) * (Ny - 2) * (Nz - 2) * M.nprocs)));
|
||||
|
||||
// 6. copy back to the device
|
||||
//if (rank==0) printf("MorphInit: copy data back to device\n");
|
||||
ScaLBL_CopyToDevice(M.Phi, phase.data(), N * sizeof(double));
|
||||
|
||||
// 7. Re-initialize phase field and density
|
||||
ScaLBL_PhaseField_Init(M.dvcMap, M.Phi, M.Den, M.Aq, M.Bq, 0, M.ScaLBL_Comm->LastExterior(), M.Np);
|
||||
ScaLBL_PhaseField_Init(M.dvcMap, M.Phi, M.Den, M.Aq, M.Bq, M.ScaLBL_Comm->FirstInterior(), M.ScaLBL_Comm->LastInterior(), M.Np);
|
||||
ScaLBL_PhaseField_Init(M.dvcMap, M.Phi, M.Den, M.Aq, M.Bq, 0,
|
||||
M.ScaLBL_Comm->LastExterior(), M.Np);
|
||||
ScaLBL_PhaseField_Init(M.dvcMap, M.Phi, M.Den, M.Aq, M.Bq,
|
||||
M.ScaLBL_Comm->FirstInterior(),
|
||||
M.ScaLBL_Comm->LastInterior(), M.Np);
|
||||
auto BoundaryCondition = M.BoundaryCondition;
|
||||
if (BoundaryCondition == 1 || BoundaryCondition == 2 || BoundaryCondition == 3 || BoundaryCondition == 4){
|
||||
if (BoundaryCondition == 1 || BoundaryCondition == 2 ||
|
||||
BoundaryCondition == 3 || BoundaryCondition == 4) {
|
||||
if (M.Dm->kproc() == 0) {
|
||||
ScaLBL_SetSlice_z(M.Phi, 1.0, Nx, Ny, Nz, 0);
|
||||
ScaLBL_SetSlice_z(M.Phi, 1.0, Nx, Ny, Nz, 1);
|
||||
|
@ -435,8 +511,8 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
|
|||
return delta_volume;
|
||||
}
|
||||
|
||||
|
||||
double FlowAdaptor::SeedPhaseField(ScaLBL_ColorModel &M, const double seed_water_in_oil){
|
||||
double FlowAdaptor::SeedPhaseField(ScaLBL_ColorModel &M,
|
||||
const double seed_water_in_oil) {
|
||||
srand(time(NULL));
|
||||
auto rank = M.rank;
|
||||
auto Np = M.Np;
|
||||
|
@ -450,11 +526,14 @@ double FlowAdaptor::SeedPhaseField(ScaLBL_ColorModel &M, const double seed_water
|
|||
ScaLBL_CopyToHost(Aq_tmp, M.Aq, 7 * Np * sizeof(double));
|
||||
ScaLBL_CopyToHost(Bq_tmp, M.Bq, 7 * Np * sizeof(double));
|
||||
|
||||
|
||||
for (int n = 0; n < M.ScaLBL_Comm->LastExterior(); n++) {
|
||||
double random_value = seed_water_in_oil * double(rand()) / RAND_MAX;
|
||||
double dA = Aq_tmp[n] + Aq_tmp[n+Np] + Aq_tmp[n+2*Np] + Aq_tmp[n+3*Np] + Aq_tmp[n+4*Np] + Aq_tmp[n+5*Np] + Aq_tmp[n+6*Np];
|
||||
double dB = Bq_tmp[n] + Bq_tmp[n+Np] + Bq_tmp[n+2*Np] + Bq_tmp[n+3*Np] + Bq_tmp[n+4*Np] + Bq_tmp[n+5*Np] + Bq_tmp[n+6*Np];
|
||||
double dA = Aq_tmp[n] + Aq_tmp[n + Np] + Aq_tmp[n + 2 * Np] +
|
||||
Aq_tmp[n + 3 * Np] + Aq_tmp[n + 4 * Np] +
|
||||
Aq_tmp[n + 5 * Np] + Aq_tmp[n + 6 * Np];
|
||||
double dB = Bq_tmp[n] + Bq_tmp[n + Np] + Bq_tmp[n + 2 * Np] +
|
||||
Bq_tmp[n + 3 * Np] + Bq_tmp[n + 4 * Np] +
|
||||
Bq_tmp[n + 5 * Np] + Bq_tmp[n + 6 * Np];
|
||||
double phase_id = (dA - dB) / (dA + dB);
|
||||
if (phase_id > 0.0) {
|
||||
Aq_tmp[n] -= 0.3333333333333333 * random_value;
|
||||
|
@ -476,10 +555,15 @@ double FlowAdaptor::SeedPhaseField(ScaLBL_ColorModel &M, const double seed_water
|
|||
mass_loss += random_value * seed_water_in_oil;
|
||||
}
|
||||
|
||||
for (int n=M.ScaLBL_Comm->FirstInterior(); n < M.ScaLBL_Comm->LastInterior(); n++){
|
||||
for (int n = M.ScaLBL_Comm->FirstInterior();
|
||||
n < M.ScaLBL_Comm->LastInterior(); n++) {
|
||||
double random_value = seed_water_in_oil * double(rand()) / RAND_MAX;
|
||||
double dA = Aq_tmp[n] + Aq_tmp[n+Np] + Aq_tmp[n+2*Np] + Aq_tmp[n+3*Np] + Aq_tmp[n+4*Np] + Aq_tmp[n+5*Np] + Aq_tmp[n+6*Np];
|
||||
double dB = Bq_tmp[n] + Bq_tmp[n+Np] + Bq_tmp[n+2*Np] + Bq_tmp[n+3*Np] + Bq_tmp[n+4*Np] + Bq_tmp[n+5*Np] + Bq_tmp[n+6*Np];
|
||||
double dA = Aq_tmp[n] + Aq_tmp[n + Np] + Aq_tmp[n + 2 * Np] +
|
||||
Aq_tmp[n + 3 * Np] + Aq_tmp[n + 4 * Np] +
|
||||
Aq_tmp[n + 5 * Np] + Aq_tmp[n + 6 * Np];
|
||||
double dB = Bq_tmp[n] + Bq_tmp[n + Np] + Bq_tmp[n + 2 * Np] +
|
||||
Bq_tmp[n + 3 * Np] + Bq_tmp[n + 4 * Np] +
|
||||
Bq_tmp[n + 5 * Np] + Bq_tmp[n + 6 * Np];
|
||||
double phase_id = (dA - dB) / (dA + dB);
|
||||
if (phase_id > 0.0) {
|
||||
Aq_tmp[n] -= 0.3333333333333333 * random_value;
|
||||
|
@ -503,12 +587,15 @@ double FlowAdaptor::SeedPhaseField(ScaLBL_ColorModel &M, const double seed_water
|
|||
|
||||
count = M.Dm->Comm.sumReduce(count);
|
||||
mass_loss = M.Dm->Comm.sumReduce(mass_loss);
|
||||
if (rank == 0) printf("Remove mass %f from %f voxels \n",mass_loss,count);
|
||||
if (rank == 0)
|
||||
printf("Remove mass %f from %f voxels \n", mass_loss, count);
|
||||
|
||||
// Need to initialize Aq, Bq, Den, Phi directly
|
||||
//ScaLBL_CopyToDevice(Phi,phase.data(),7*Np*sizeof(double));
|
||||
ScaLBL_CopyToDevice(M.Aq, Aq_tmp, 7 * Np * sizeof(double));
|
||||
ScaLBL_CopyToDevice(M.Bq, Bq_tmp, 7 * Np * sizeof(double));
|
||||
|
||||
delete Aq_tmp;
|
||||
delete Bq_tmp;
|
||||
return (mass_loss);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
#include "models/ColorModel.h"
|
||||
|
||||
|
||||
/**
|
||||
* \class FlowAdaptor
|
||||
* @brief
|
||||
|
@ -22,8 +21,6 @@
|
|||
|
||||
class FlowAdaptor {
|
||||
public:
|
||||
|
||||
|
||||
/**
|
||||
* \brief Create a flow adaptor to operate on the LB model
|
||||
* @param M ScaLBL_ColorModel
|
||||
|
@ -65,7 +62,8 @@ public:
|
|||
* \details Update fractional flow condition. Mass will be preferentially added or removed from
|
||||
* phase regions based on where flow is occurring
|
||||
* @param M ScaLBL_ColorModel
|
||||
*/ double UpdateFractionalFlow(ScaLBL_ColorModel &M);
|
||||
*/
|
||||
double UpdateFractionalFlow(ScaLBL_ColorModel &M);
|
||||
|
||||
/**
|
||||
* \brief image re-initialization
|
||||
|
@ -82,6 +80,7 @@ public:
|
|||
void Flatten(ScaLBL_ColorModel &M);
|
||||
DoubleArray phi;
|
||||
DoubleArray phi_t;
|
||||
|
||||
private:
|
||||
int Nx, Ny, Nz;
|
||||
int timestep;
|
||||
|
|
|
@ -1,20 +1,29 @@
|
|||
#include "analysis/FreeEnergy.h"
|
||||
|
||||
FreeEnergyAnalyzer::FreeEnergyAnalyzer(std::shared_ptr <Domain> dm):
|
||||
Dm(dm)
|
||||
{
|
||||
FreeEnergyAnalyzer::FreeEnergyAnalyzer(std::shared_ptr<Domain> dm) : Dm(dm) {
|
||||
|
||||
Nx=dm->Nx; Ny=dm->Ny; Nz=dm->Nz;
|
||||
Volume=(Nx-2)*(Ny-2)*(Nz-2)*Dm->nprocx()*Dm->nprocy()*Dm->nprocz()*1.0;
|
||||
Nx = dm->Nx;
|
||||
Ny = dm->Ny;
|
||||
Nz = dm->Nz;
|
||||
Volume = (Nx - 2) * (Ny - 2) * (Nz - 2) * Dm->nprocx() * Dm->nprocy() *
|
||||
Dm->nprocz() * 1.0;
|
||||
|
||||
ChemicalPotential.resize(Nx,Ny,Nz); ChemicalPotential.fill(0);
|
||||
Phi.resize(Nx,Ny,Nz); Phi.fill(0);
|
||||
Pressure.resize(Nx,Ny,Nz); Pressure.fill(0);
|
||||
Rho.resize(Nx,Ny,Nz); Rho.fill(0);
|
||||
Vel_x.resize(Nx,Ny,Nz); Vel_x.fill(0); // Gradient of the phase indicator field
|
||||
Vel_y.resize(Nx,Ny,Nz); Vel_y.fill(0);
|
||||
Vel_z.resize(Nx,Ny,Nz); Vel_z.fill(0);
|
||||
SDs.resize(Nx,Ny,Nz); SDs.fill(0);
|
||||
ChemicalPotential.resize(Nx, Ny, Nz);
|
||||
ChemicalPotential.fill(0);
|
||||
Phi.resize(Nx, Ny, Nz);
|
||||
Phi.fill(0);
|
||||
Pressure.resize(Nx, Ny, Nz);
|
||||
Pressure.fill(0);
|
||||
Rho.resize(Nx, Ny, Nz);
|
||||
Rho.fill(0);
|
||||
Vel_x.resize(Nx, Ny, Nz);
|
||||
Vel_x.fill(0); // Gradient of the phase indicator field
|
||||
Vel_y.resize(Nx, Ny, Nz);
|
||||
Vel_y.fill(0);
|
||||
Vel_z.resize(Nx, Ny, Nz);
|
||||
Vel_z.fill(0);
|
||||
SDs.resize(Nx, Ny, Nz);
|
||||
SDs.fill(0);
|
||||
|
||||
if (Dm->rank() == 0) {
|
||||
bool WriteHeader = false;
|
||||
|
@ -25,14 +34,12 @@ FreeEnergyAnalyzer::FreeEnergyAnalyzer(std::shared_ptr <Domain> dm):
|
|||
WriteHeader = true;
|
||||
|
||||
TIMELOG = fopen("free.csv", "a+");
|
||||
if (WriteHeader)
|
||||
{
|
||||
if (WriteHeader) {
|
||||
// If timelog is empty, write a short header to list the averages
|
||||
//fprintf(TIMELOG,"--------------------------------------------------------------------------------------\n");
|
||||
fprintf(TIMELOG, "timestep\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
FreeEnergyAnalyzer::~FreeEnergyAnalyzer() {
|
||||
|
@ -41,9 +48,7 @@ FreeEnergyAnalyzer::~FreeEnergyAnalyzer(){
|
|||
}
|
||||
}
|
||||
|
||||
void FreeEnergyAnalyzer::SetParams(){
|
||||
|
||||
}
|
||||
void FreeEnergyAnalyzer::SetParams() {}
|
||||
|
||||
void FreeEnergyAnalyzer::Basic(ScaLBL_FreeLeeModel &LeeModel, int timestep) {
|
||||
|
||||
|
@ -73,19 +78,25 @@ void FreeEnergyAnalyzer::Basic(ScaLBL_FreeLeeModel &LeeModel, int timestep){
|
|||
} */
|
||||
}
|
||||
|
||||
void FreeEnergyAnalyzer::WriteVis( ScaLBL_FreeLeeModel &LeeModel, std::shared_ptr<Database> input_db, int timestep){
|
||||
void FreeEnergyAnalyzer::WriteVis(ScaLBL_FreeLeeModel &LeeModel,
|
||||
std::shared_ptr<Database> input_db,
|
||||
int timestep) {
|
||||
|
||||
auto vis_db = input_db->getDatabase("Visualization");
|
||||
|
||||
std::vector<IO::MeshDataStruct> visData;
|
||||
fillHalo<double> fillData(Dm->Comm,Dm->rank_info,{Dm->Nx-2,Dm->Ny-2,Dm->Nz-2},{1,1,1},0,1);
|
||||
fillHalo<double> fillData(Dm->Comm, Dm->rank_info,
|
||||
{Dm->Nx - 2, Dm->Ny - 2, Dm->Nz - 2}, {1, 1, 1},
|
||||
0, 1);
|
||||
|
||||
IO::initialize("", "silo", "false");
|
||||
// Create the MeshDataStruct
|
||||
visData.resize(1);
|
||||
|
||||
visData[0].meshName = "domain";
|
||||
visData[0].mesh = std::make_shared<IO::DomainMesh>( Dm->rank_info,Dm->Nx-2,Dm->Ny-2,Dm->Nz-2,Dm->Lx,Dm->Ly,Dm->Lz );
|
||||
visData[0].mesh =
|
||||
std::make_shared<IO::DomainMesh>(Dm->rank_info, Dm->Nx - 2, Dm->Ny - 2,
|
||||
Dm->Nz - 2, Dm->Lx, Dm->Ly, Dm->Lz);
|
||||
auto VisPhase = std::make_shared<IO::Variable>();
|
||||
auto VisPressure = std::make_shared<IO::Variable>();
|
||||
auto VisChemicalPotential = std::make_shared<IO::Variable>();
|
||||
|
@ -93,7 +104,6 @@ void FreeEnergyAnalyzer::WriteVis( ScaLBL_FreeLeeModel &LeeModel, std::shared_pt
|
|||
auto VyVar = std::make_shared<IO::Variable>();
|
||||
auto VzVar = std::make_shared<IO::Variable>();
|
||||
|
||||
|
||||
if (vis_db->getWithDefault<bool>("save_phase_field", true)) {
|
||||
VisPhase->name = "Phase";
|
||||
VisPhase->type = IO::VariableType::VolumeVariable;
|
||||
|
|
|
@ -53,10 +53,10 @@ public:
|
|||
|
||||
void SetParams();
|
||||
void Basic(ScaLBL_FreeLeeModel &LeeModel, int timestep);
|
||||
void WriteVis( ScaLBL_FreeLeeModel &LeeModel, std::shared_ptr<Database> input_db, int timestep);
|
||||
void WriteVis(ScaLBL_FreeLeeModel &LeeModel,
|
||||
std::shared_ptr<Database> input_db, int timestep);
|
||||
|
||||
private:
|
||||
FILE *TIMELOG;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,25 +1,35 @@
|
|||
#include "analysis/GreyPhase.h"
|
||||
|
||||
// Constructor
|
||||
GreyPhaseAnalysis::GreyPhaseAnalysis(std::shared_ptr <Domain> dm):
|
||||
Dm(dm)
|
||||
{
|
||||
Nx=dm->Nx; Ny=dm->Ny; Nz=dm->Nz;
|
||||
Volume=(Nx-2)*(Ny-2)*(Nz-2)*Dm->nprocx()*Dm->nprocy()*Dm->nprocz()*1.0;
|
||||
GreyPhaseAnalysis::GreyPhaseAnalysis(std::shared_ptr<Domain> dm) : Dm(dm) {
|
||||
Nx = dm->Nx;
|
||||
Ny = dm->Ny;
|
||||
Nz = dm->Nz;
|
||||
Volume = (Nx - 2) * (Ny - 2) * (Nz - 2) * Dm->nprocx() * Dm->nprocy() *
|
||||
Dm->nprocz() * 1.0;
|
||||
|
||||
// Global arrays
|
||||
SDs.resize(Nx,Ny,Nz); SDs.fill(0);
|
||||
Porosity.resize(Nx,Ny,Nz); Porosity.fill(0);
|
||||
SDs.resize(Nx, Ny, Nz);
|
||||
SDs.fill(0);
|
||||
Porosity.resize(Nx, Ny, Nz);
|
||||
Porosity.fill(0);
|
||||
//PhaseID.resize(Nx,Ny,Nz); PhaseID.fill(0);
|
||||
Rho_n.resize(Nx,Ny,Nz); Rho_n.fill(0);
|
||||
Rho_w.resize(Nx,Ny,Nz); Rho_w.fill(0);
|
||||
Pressure.resize(Nx,Ny,Nz); Pressure.fill(0);
|
||||
Rho_n.resize(Nx, Ny, Nz);
|
||||
Rho_n.fill(0);
|
||||
Rho_w.resize(Nx, Ny, Nz);
|
||||
Rho_w.fill(0);
|
||||
Pressure.resize(Nx, Ny, Nz);
|
||||
Pressure.fill(0);
|
||||
//Phi.resize(Nx,Ny,Nz); Phi.fill(0);
|
||||
//DelPhi.resize(Nx,Ny,Nz); DelPhi.fill(0);
|
||||
Vel_x.resize(Nx,Ny,Nz); Vel_x.fill(0); // Gradient of the phase indicator field
|
||||
Vel_y.resize(Nx,Ny,Nz); Vel_y.fill(0);
|
||||
Vel_z.resize(Nx,Ny,Nz); Vel_z.fill(0);
|
||||
MobilityRatio.resize(Nx,Ny,Nz); MobilityRatio.fill(0);
|
||||
Vel_x.resize(Nx, Ny, Nz);
|
||||
Vel_x.fill(0); // Gradient of the phase indicator field
|
||||
Vel_y.resize(Nx, Ny, Nz);
|
||||
Vel_y.fill(0);
|
||||
Vel_z.resize(Nx, Ny, Nz);
|
||||
Vel_z.fill(0);
|
||||
MobilityRatio.resize(Nx, Ny, Nz);
|
||||
MobilityRatio.fill(0);
|
||||
//.........................................
|
||||
|
||||
if (Dm->rank() == 0) {
|
||||
|
@ -31,8 +41,7 @@ GreyPhaseAnalysis::GreyPhaseAnalysis(std::shared_ptr <Domain> dm):
|
|||
WriteHeader = true;
|
||||
|
||||
TIMELOG = fopen("timelog.csv", "a+");
|
||||
if (WriteHeader)
|
||||
{
|
||||
if (WriteHeader) {
|
||||
// If timelog is empty, write a short header to list the averages
|
||||
//fprintf(TIMELOG,"--------------------------------------------------------------------------------------\n");
|
||||
fprintf(TIMELOG, "sw krw krn vw vn pw pn\n");
|
||||
|
@ -40,20 +49,15 @@ GreyPhaseAnalysis::GreyPhaseAnalysis(std::shared_ptr <Domain> dm):
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Destructor
|
||||
GreyPhaseAnalysis::~GreyPhaseAnalysis()
|
||||
{
|
||||
GreyPhaseAnalysis::~GreyPhaseAnalysis() {}
|
||||
|
||||
}
|
||||
void GreyPhaseAnalysis::Write(int timestep) {}
|
||||
|
||||
void GreyPhaseAnalysis::Write(int timestep)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void GreyPhaseAnalysis::SetParams(double rhoA, double rhoB, double tauA, double tauB, double force_x, double force_y, double force_z, double alpha, double B, double GreyPorosity)
|
||||
{
|
||||
void GreyPhaseAnalysis::SetParams(double rhoA, double rhoB, double tauA,
|
||||
double tauB, double force_x, double force_y,
|
||||
double force_z, double alpha, double B,
|
||||
double GreyPorosity) {
|
||||
Fx = force_x;
|
||||
Fy = force_y;
|
||||
Fz = force_z;
|
||||
|
@ -70,10 +74,13 @@ void GreyPhaseAnalysis::Basic(){
|
|||
int i, j, k, n, imin, jmin, kmin, kmax;
|
||||
|
||||
// If external boundary conditions are set, do not average over the inlet
|
||||
kmin=1; kmax=Nz-1;
|
||||
kmin = 1;
|
||||
kmax = Nz - 1;
|
||||
imin = jmin = 1;
|
||||
if (Dm->inlet_layers_z > 0 && Dm->kproc() == 0) kmin += Dm->inlet_layers_z;
|
||||
if (Dm->outlet_layers_z > 0 && Dm->kproc() == Dm->nprocz()-1) kmax -= Dm->outlet_layers_z;
|
||||
if (Dm->inlet_layers_z > 0 && Dm->kproc() == 0)
|
||||
kmin += Dm->inlet_layers_z;
|
||||
if (Dm->outlet_layers_z > 0 && Dm->kproc() == Dm->nprocz() - 1)
|
||||
kmax -= Dm->outlet_layers_z;
|
||||
|
||||
Water_local.reset();
|
||||
Oil_local.reset();
|
||||
|
@ -93,21 +100,26 @@ void GreyPhaseAnalysis::Basic(){
|
|||
double mobility_ratio = MobilityRatio(n);
|
||||
|
||||
Water_local.M += nB * porosity;
|
||||
Water_local.Px += porosity*(nA+nB)*Vel_x(n)*0.5*(1.0-mobility_ratio);
|
||||
Water_local.Py += porosity*(nA+nB)*Vel_y(n)*0.5*(1.0-mobility_ratio);
|
||||
Water_local.Pz += porosity*(nA+nB)*Vel_z(n)*0.5*(1.0-mobility_ratio);
|
||||
Water_local.Px += porosity * (nA + nB) * Vel_x(n) * 0.5 *
|
||||
(1.0 - mobility_ratio);
|
||||
Water_local.Py += porosity * (nA + nB) * Vel_y(n) * 0.5 *
|
||||
(1.0 - mobility_ratio);
|
||||
Water_local.Pz += porosity * (nA + nB) * Vel_z(n) * 0.5 *
|
||||
(1.0 - mobility_ratio);
|
||||
|
||||
Oil_local.M += nA * porosity;
|
||||
Oil_local.Px += porosity*(nA+nB)*Vel_x(n)*0.5*(1.0+mobility_ratio);
|
||||
Oil_local.Py += porosity*(nA+nB)*Vel_y(n)*0.5*(1.0+mobility_ratio);
|
||||
Oil_local.Pz += porosity*(nA+nB)*Vel_z(n)*0.5*(1.0+mobility_ratio);
|
||||
Oil_local.Px += porosity * (nA + nB) * Vel_x(n) * 0.5 *
|
||||
(1.0 + mobility_ratio);
|
||||
Oil_local.Py += porosity * (nA + nB) * Vel_y(n) * 0.5 *
|
||||
(1.0 + mobility_ratio);
|
||||
Oil_local.Pz += porosity * (nA + nB) * Vel_z(n) * 0.5 *
|
||||
(1.0 + mobility_ratio);
|
||||
|
||||
if (phi > 0.99) {
|
||||
Oil_local.p += Pressure(n);
|
||||
//Oil_local.p += pressure*(rho_n*nA)/(rho_n*nA+rho_w*nB);
|
||||
count_n += 1.0;
|
||||
}
|
||||
else if ( phi < -0.99 ){
|
||||
} else if (phi < -0.99) {
|
||||
Water_local.p += Pressure(n);
|
||||
//Water_local.p += pressure*(rho_w*nB)/(rho_n*nA+rho_w*nB);
|
||||
count_w += 1.0;
|
||||
|
@ -126,7 +138,6 @@ void GreyPhaseAnalysis::Basic(){
|
|||
Water.Py = Dm->Comm.sumReduce(Water_local.Py);
|
||||
Water.Pz = Dm->Comm.sumReduce(Water_local.Pz);
|
||||
|
||||
|
||||
//Oil.p /= Oil.M;
|
||||
//Water.p /= Water.M;
|
||||
count_w = Dm->Comm.sumReduce(count_w);
|
||||
|
@ -142,17 +153,27 @@ void GreyPhaseAnalysis::Basic(){
|
|||
|
||||
// check for NaN
|
||||
bool err = false;
|
||||
if (Water.M != Water.M) err=true;
|
||||
if (Water.p != Water.p) err=true;
|
||||
if (Water.Px != Water.Px) err=true;
|
||||
if (Water.Py != Water.Py) err=true;
|
||||
if (Water.Pz != Water.Pz) err=true;
|
||||
if (Water.M != Water.M)
|
||||
err = true;
|
||||
if (Water.p != Water.p)
|
||||
err = true;
|
||||
if (Water.Px != Water.Px)
|
||||
err = true;
|
||||
if (Water.Py != Water.Py)
|
||||
err = true;
|
||||
if (Water.Pz != Water.Pz)
|
||||
err = true;
|
||||
|
||||
if (Oil.M != Oil.M) err=true;
|
||||
if (Oil.p != Oil.p) err=true;
|
||||
if (Oil.Px != Oil.Px) err=true;
|
||||
if (Oil.Py != Oil.Py) err=true;
|
||||
if (Oil.Pz != Oil.Pz) err=true;
|
||||
if (Oil.M != Oil.M)
|
||||
err = true;
|
||||
if (Oil.p != Oil.p)
|
||||
err = true;
|
||||
if (Oil.Px != Oil.Px)
|
||||
err = true;
|
||||
if (Oil.Py != Oil.Py)
|
||||
err = true;
|
||||
if (Oil.Pz != Oil.Pz)
|
||||
err = true;
|
||||
|
||||
if (Dm->rank() == 0) {
|
||||
double force_mag = sqrt(Fx * Fx + Fy * Fy + Fz * Fz);
|
||||
|
@ -163,14 +184,14 @@ void GreyPhaseAnalysis::Basic(){
|
|||
dir_x = Fx / force_mag;
|
||||
dir_y = Fy / force_mag;
|
||||
dir_z = Fz / force_mag;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// default to z direction
|
||||
dir_x = 0.0;
|
||||
dir_y = 0.0;
|
||||
dir_z = 1.0;
|
||||
}
|
||||
if (Dm->BoundaryCondition == 1 || Dm->BoundaryCondition == 2 || Dm->BoundaryCondition == 3 || Dm->BoundaryCondition == 4 ){
|
||||
if (Dm->BoundaryCondition == 1 || Dm->BoundaryCondition == 2 ||
|
||||
Dm->BoundaryCondition == 3 || Dm->BoundaryCondition == 4) {
|
||||
// compute the pressure drop
|
||||
double pressure_drop = (Pressure(Nx * Ny + Nx + 1) - 1.0) / 3.0;
|
||||
double length = ((Nz - 2) * Dm->nprocz());
|
||||
|
@ -184,21 +205,28 @@ void GreyPhaseAnalysis::Basic(){
|
|||
force_mag = 1.0;
|
||||
}
|
||||
saturation = Water.M / (Water.M + Oil.M); // assume constant density
|
||||
water_flow_rate=grey_porosity*saturation*(Water.Px*dir_x + Water.Py*dir_y + Water.Pz*dir_z)/Water.M;
|
||||
oil_flow_rate =grey_porosity*(1.0-saturation)*(Oil.Px*dir_x + Oil.Py*dir_y + Oil.Pz*dir_z)/Oil.M;
|
||||
water_flow_rate =
|
||||
grey_porosity * saturation *
|
||||
(Water.Px * dir_x + Water.Py * dir_y + Water.Pz * dir_z) / Water.M;
|
||||
oil_flow_rate = grey_porosity * (1.0 - saturation) *
|
||||
(Oil.Px * dir_x + Oil.Py * dir_y + Oil.Pz * dir_z) /
|
||||
Oil.M;
|
||||
|
||||
double h = Dm->voxel_length;
|
||||
//TODO check if need greyporosity or domain porosity ? - compare to analytical solution
|
||||
double krn = h * h * nu_n * oil_flow_rate / force_mag;
|
||||
double krw = h * h * nu_w * water_flow_rate / force_mag;
|
||||
//printf(" water saturation = %f, fractional flow =%f \n",saturation,fractional_flow);
|
||||
fprintf(TIMELOG,"%.5g %.5g %.5g %.5g %.5g %.5g %.5g\n",saturation,krw,krn,h*water_flow_rate,h*oil_flow_rate, Water.p, Oil.p);
|
||||
fprintf(TIMELOG, "%.5g %.5g %.5g %.5g %.5g %.5g %.5g\n", saturation,
|
||||
krw, krn, h * water_flow_rate, h * oil_flow_rate, Water.p,
|
||||
Oil.p);
|
||||
fflush(TIMELOG);
|
||||
}
|
||||
|
||||
if (err == true) {
|
||||
// exception if simulation produceds NaN
|
||||
printf("GreyPhaseAnalysis.cpp: NaN encountered, may need to check simulation parameters \n");
|
||||
printf("GreyPhaseAnalysis.cpp: NaN encountered, may need to check "
|
||||
"simulation parameters \n");
|
||||
}
|
||||
ASSERT(err == false);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include "IO/Reader.h"
|
||||
#include "IO/Writer.h"
|
||||
|
||||
|
||||
/**
|
||||
* \class GreyPhase
|
||||
*
|
||||
|
@ -27,14 +26,11 @@ class GreyPhase{
|
|||
public:
|
||||
double p;
|
||||
double M, Px, Py, Pz;
|
||||
void reset(){
|
||||
p=M=Px=Py=Pz=0.0;
|
||||
}
|
||||
void reset() { p = M = Px = Py = Pz = 0.0; }
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \class GreyPhaseAnalysis
|
||||
*
|
||||
|
@ -76,7 +72,9 @@ public:
|
|||
GreyPhaseAnalysis(std::shared_ptr<Domain> Dm);
|
||||
~GreyPhaseAnalysis();
|
||||
|
||||
void SetParams(double rhoA, double rhoB, double tauA, double tauB, double force_x, double force_y, double force_z, double alpha, double beta, double GreyPorosity);
|
||||
void SetParams(double rhoA, double rhoB, double tauA, double tauB,
|
||||
double force_x, double force_y, double force_z, double alpha,
|
||||
double beta, double GreyPorosity);
|
||||
void Basic();
|
||||
void Write(int time);
|
||||
|
||||
|
@ -85,4 +83,3 @@ private:
|
|||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "analysis/Minkowski.h"
|
||||
#include "analysis/pmmc.h"
|
||||
#include "analysis/analysis.h"
|
||||
|
@ -13,25 +29,28 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
|
||||
#define PI 3.14159265359
|
||||
|
||||
// Constructor
|
||||
Minkowski::Minkowski(std::shared_ptr <Domain> dm):
|
||||
kstart(0), kfinish(0), isovalue(0), Volume(0),
|
||||
LOGFILE(NULL), Dm(dm), Vi(0), Vi_global(0)
|
||||
{
|
||||
Nx=dm->Nx; Ny=dm->Ny; Nz=dm->Nz;
|
||||
Volume=double((Nx-2)*(Ny-2)*(Nz-2))*double(Dm->nprocx()*Dm->nprocy()*Dm->nprocz());
|
||||
Minkowski::Minkowski(std::shared_ptr<Domain> dm)
|
||||
: kstart(0), kfinish(0), isovalue(0), Volume(0), LOGFILE(NULL), Dm(dm),
|
||||
Vi(0), Vi_global(0) {
|
||||
Nx = dm->Nx;
|
||||
Ny = dm->Ny;
|
||||
Nz = dm->Nz;
|
||||
Volume = double((Nx - 2) * (Ny - 2) * (Nz - 2)) *
|
||||
double(Dm->nprocx() * Dm->nprocy() * Dm->nprocz());
|
||||
|
||||
id.resize(Nx,Ny,Nz); id.fill(0);
|
||||
label.resize(Nx,Ny,Nz); label.fill(0);
|
||||
distance.resize(Nx,Ny,Nz); distance.fill(0);
|
||||
id.resize(Nx, Ny, Nz);
|
||||
id.fill(0);
|
||||
label.resize(Nx, Ny, Nz);
|
||||
label.fill(0);
|
||||
distance.resize(Nx, Ny, Nz);
|
||||
distance.fill(0);
|
||||
|
||||
if (Dm->rank() == 0) {
|
||||
LOGFILE = fopen("minkowski.csv", "a+");
|
||||
if (fseek(LOGFILE,0,SEEK_SET) == fseek(LOGFILE,0,SEEK_CUR))
|
||||
{
|
||||
if (fseek(LOGFILE, 0, SEEK_SET) == fseek(LOGFILE, 0, SEEK_CUR)) {
|
||||
// If LOGFILE is empty, write a short header to list the averages
|
||||
//fprintf(LOGFILE,"--------------------------------------------------------------------------------------\n");
|
||||
fprintf(LOGFILE, "Vn An Jn Xn\n"); //miknowski measures,
|
||||
|
@ -39,15 +58,14 @@ Minkowski::Minkowski(std::shared_ptr <Domain> dm):
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Destructor
|
||||
Minkowski::~Minkowski()
|
||||
{
|
||||
if ( LOGFILE!=NULL ) { fclose(LOGFILE); }
|
||||
Minkowski::~Minkowski() {
|
||||
if (LOGFILE != NULL) {
|
||||
fclose(LOGFILE);
|
||||
}
|
||||
}
|
||||
|
||||
void Minkowski::ComputeScalar(const DoubleArray& Field, const double isovalue)
|
||||
{
|
||||
void Minkowski::ComputeScalar(const DoubleArray &Field, const double isovalue) {
|
||||
PROFILE_START("ComputeScalar");
|
||||
Xi = Ji = Ai = 0.0;
|
||||
DCEL object;
|
||||
|
@ -133,7 +151,6 @@ void Minkowski::ComputeScalar(const DoubleArray& Field, const double isovalue)
|
|||
PROFILE_STOP("ComputeScalar");
|
||||
}
|
||||
|
||||
|
||||
void Minkowski::MeasureObject() {
|
||||
/*
|
||||
* compute the distance to an object
|
||||
|
@ -156,7 +173,6 @@ void Minkowski::MeasureObject(){
|
|||
ComputeScalar(distance, 0.0);
|
||||
}
|
||||
|
||||
|
||||
void Minkowski::MeasureObject(double factor, const DoubleArray &Phi) {
|
||||
/*
|
||||
* compute the distance to an object
|
||||
|
@ -180,7 +196,8 @@ void Minkowski::MeasureObject(double factor, const DoubleArray &Phi){
|
|||
double value = Phi(i, j, k);
|
||||
double dist_value = distance(i, j, k);
|
||||
if (dist_value < 2.5 && dist_value > -2.5) {
|
||||
double new_distance = factor*log((1.0+value)/(1.0-value));
|
||||
double new_distance =
|
||||
factor * log((1.0 + value) / (1.0 - value));
|
||||
if (dist_value * new_distance < 0.0)
|
||||
new_distance = (-1.0) * new_distance;
|
||||
distance(i, j, k) = new_distance;
|
||||
|
@ -190,10 +207,8 @@ void Minkowski::MeasureObject(double factor, const DoubleArray &Phi){
|
|||
}
|
||||
|
||||
ComputeScalar(distance, 0.0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
int Minkowski::MeasureConnectedPathway() {
|
||||
/*
|
||||
* compute the connected pathway for object with LABEL in id field
|
||||
|
@ -209,8 +224,7 @@ int Minkowski::MeasureConnectedPathway(){
|
|||
for (int i = 0; i < Nx; i++) {
|
||||
if (id(i, j, k) == LABEL) {
|
||||
distance(i, j, k) = 1.0;
|
||||
}
|
||||
else
|
||||
} else
|
||||
distance(i, j, k) = -1.0;
|
||||
}
|
||||
}
|
||||
|
@ -218,7 +232,9 @@ int Minkowski::MeasureConnectedPathway(){
|
|||
|
||||
// Extract only the connected part of NWP
|
||||
double vF = 0.0;
|
||||
n_connected_components = ComputeGlobalBlobIDs(Nx-2,Ny-2,Nz-2,Dm->rank_info,distance,distance,vF,vF,label,Dm->Comm);
|
||||
n_connected_components =
|
||||
ComputeGlobalBlobIDs(Nx - 2, Ny - 2, Nz - 2, Dm->rank_info, distance,
|
||||
distance, vF, vF, label, Dm->Comm);
|
||||
// int n_connected_components = ComputeGlobalPhaseComponent(Nx-2,Ny-2,Nz-2,Dm->rank_info,const IntArray &PhaseID, int &VALUE, BlobIDArray &GlobalBlobID, Dm->Comm )
|
||||
Dm->Comm.barrier();
|
||||
|
||||
|
@ -227,8 +243,7 @@ int Minkowski::MeasureConnectedPathway(){
|
|||
for (int i = 0; i < Nx; i++) {
|
||||
if (label(i, j, k) == 0) {
|
||||
id(i, j, k) = 0;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
id(i, j, k) = 1;
|
||||
}
|
||||
}
|
||||
|
@ -253,8 +268,7 @@ int Minkowski::MeasureConnectedPathway(double factor, const DoubleArray &Phi){
|
|||
for (int i = 0; i < Nx; i++) {
|
||||
if (id(i, j, k) == LABEL) {
|
||||
distance(i, j, k) = 1.0;
|
||||
}
|
||||
else
|
||||
} else
|
||||
distance(i, j, k) = -1.0;
|
||||
}
|
||||
}
|
||||
|
@ -262,18 +276,18 @@ int Minkowski::MeasureConnectedPathway(double factor, const DoubleArray &Phi){
|
|||
|
||||
// Extract only the connected part of NWP
|
||||
double vF = 0.0;
|
||||
n_connected_components = ComputeGlobalBlobIDs(Nx-2,Ny-2,Nz-2,Dm->rank_info,distance,distance,vF,vF,label,Dm->Comm);
|
||||
n_connected_components =
|
||||
ComputeGlobalBlobIDs(Nx - 2, Ny - 2, Nz - 2, Dm->rank_info, distance,
|
||||
distance, vF, vF, label, Dm->Comm);
|
||||
// int n_connected_components = ComputeGlobalPhaseComponent(Nx-2,Ny-2,Nz-2,Dm->rank_info,const IntArray &PhaseID, int &VALUE, BlobIDArray &GlobalBlobID, Dm->Comm )
|
||||
Dm->Comm.barrier();
|
||||
|
||||
|
||||
for (int k = 0; k < Nz; k++) {
|
||||
for (int j = 0; j < Ny; j++) {
|
||||
for (int i = 0; i < Nx; i++) {
|
||||
if (label(i, j, k) == 0) {
|
||||
id(i, j, k) = 0;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
id(i, j, k) = 1;
|
||||
}
|
||||
}
|
||||
|
@ -283,12 +297,10 @@ int Minkowski::MeasureConnectedPathway(double factor, const DoubleArray &Phi){
|
|||
return n_connected_components;
|
||||
}
|
||||
|
||||
|
||||
void Minkowski::PrintAll()
|
||||
{
|
||||
void Minkowski::PrintAll() {
|
||||
if (Dm->rank() == 0) {
|
||||
fprintf(LOGFILE,"%.5g %.5g %.5g %.5g\n",Vi_global, Ai_global, Ji_global, Xi_global); // minkowski measures
|
||||
fprintf(LOGFILE, "%.5g %.5g %.5g %.5g\n", Vi_global, Ai_global,
|
||||
Ji_global, Xi_global); // minkowski measures
|
||||
fflush(LOGFILE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// Header file for two-phase averaging class
|
||||
#ifndef Minkowski_INC
|
||||
#define Minkowski_INC
|
||||
|
@ -26,7 +42,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
class Minkowski {
|
||||
//...........................................................................
|
||||
int kstart, kfinish;
|
||||
|
@ -54,18 +69,10 @@ public:
|
|||
//...........................................................................
|
||||
int Nx, Ny, Nz;
|
||||
|
||||
double V(){
|
||||
return Vi;
|
||||
}
|
||||
double A(){
|
||||
return Ai;
|
||||
}
|
||||
double H(){
|
||||
return Ji;
|
||||
}
|
||||
double X(){
|
||||
return Xi;
|
||||
}
|
||||
double V() { return Vi; }
|
||||
double A() { return Ai; }
|
||||
double H() { return Ji; }
|
||||
double X() { return Xi; }
|
||||
|
||||
//..........................................................................
|
||||
/**
|
||||
|
@ -119,8 +126,6 @@ public:
|
|||
* \brief print the scalar invariants
|
||||
*/
|
||||
void PrintAll();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef PointList_INC
|
||||
#define PointList_INC
|
||||
|
||||
|
@ -10,20 +26,44 @@ struct LBPM_Point {
|
|||
};
|
||||
typedef LBPM_Point Point;
|
||||
|
||||
inline Point operator+(const Point &A,const Point &B) {return Point(A.x+B.x,A.y+B.y,A.z+B.z);}
|
||||
inline Point operator-(const Point &A,const Point &B) {return Point(A.x-B.x,A.y-B.y,A.z-B.z);}
|
||||
inline Point operator*(const Point &A,double v) {return Point(A.x*v,A.y*v,A.z*v);}
|
||||
inline Point operator*(double v,const Point &A) {return Point(A.x*v,A.y*v,A.z*v);}
|
||||
inline Point operator/(const Point &A,double v) {return Point(A.x/v,A.y/v,A.z/v);}
|
||||
inline Point operator+(const Point &A, const Point &B) {
|
||||
return Point(A.x + B.x, A.y + B.y, A.z + B.z);
|
||||
}
|
||||
inline Point operator-(const Point &A, const Point &B) {
|
||||
return Point(A.x - B.x, A.y - B.y, A.z - B.z);
|
||||
}
|
||||
inline Point operator*(const Point &A, double v) {
|
||||
return Point(A.x * v, A.y * v, A.z * v);
|
||||
}
|
||||
inline Point operator*(double v, const Point &A) {
|
||||
return Point(A.x * v, A.y * v, A.z * v);
|
||||
}
|
||||
inline Point operator/(const Point &A, double v) {
|
||||
return Point(A.x / v, A.y / v, A.z / v);
|
||||
}
|
||||
inline Point operator-(const Point &A) { return Point(-A.x, -A.y, -A.z); }
|
||||
|
||||
inline bool operator==(const Point &A,const Point &B) {return (A.x==B.x && A.y==B.y && A.z==B.z);}
|
||||
inline bool operator!=(const Point &A,const Point &B) {return (A.x!=B.x || A.y!=B.y || A.z!=B.z);}
|
||||
inline bool operator==(const Point &A, const Point &B) {
|
||||
return (A.x == B.x && A.y == B.y && A.z == B.z);
|
||||
}
|
||||
inline bool operator!=(const Point &A, const Point &B) {
|
||||
return (A.x != B.x || A.y != B.y || A.z != B.z);
|
||||
}
|
||||
|
||||
inline double Norm(const Point &A) {return sqrt(A.x*A.x+A.y*A.y+A.z*A.z);}
|
||||
inline Point Cross(const Point &A,const Point &B) {return Point(A.y*B.z-A.z*B.y,B.x*A.z-A.x*B.z,A.x*B.y-A.y*B.x);}
|
||||
inline double Dot(const Point &A,const Point &B) {return (A.x*B.x+A.y*B.y+A.z*B.z);}
|
||||
inline double Distance(const Point &A,const Point &B) {return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y)+(A.z-B.z)*(A.z-B.z));}
|
||||
inline double Norm(const Point &A) {
|
||||
return sqrt(A.x * A.x + A.y * A.y + A.z * A.z);
|
||||
}
|
||||
inline Point Cross(const Point &A, const Point &B) {
|
||||
return Point(A.y * B.z - A.z * B.y, B.x * A.z - A.x * B.z,
|
||||
A.x * B.y - A.y * B.x);
|
||||
}
|
||||
inline double Dot(const Point &A, const Point &B) {
|
||||
return (A.x * B.x + A.y * B.y + A.z * B.z);
|
||||
}
|
||||
inline double Distance(const Point &A, const Point &B) {
|
||||
return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y) +
|
||||
(A.z - B.z) * (A.z - B.z));
|
||||
}
|
||||
|
||||
/*
|
||||
class PointList{
|
||||
|
@ -88,25 +128,38 @@ PointList::~PointList()
|
|||
delete data;
|
||||
}
|
||||
*/
|
||||
template <class T>
|
||||
class DTList {
|
||||
template <class T> class DTList {
|
||||
public:
|
||||
DTList() : Data(0), length(0), refCount(new size_t(1)), outOfRange() {}
|
||||
DTList(const DTList<T> &A) : Data(A.Data), length(A.length), refCount(A.refCount), outOfRange() {++(*refCount);}
|
||||
protected:
|
||||
DTList(size_t len) : Data(len<=0 ? 0 : new T[len]), length(len<=0 ? 0 : len), refCount(new size_t(1)), outOfRange() {}
|
||||
public:
|
||||
DTList(const DTList<T> &A)
|
||||
: Data(A.Data), length(A.length), refCount(A.refCount), outOfRange() {
|
||||
++(*refCount);
|
||||
}
|
||||
|
||||
protected:
|
||||
DTList(size_t len)
|
||||
: Data(len <= 0 ? 0 : new T[len]), length(len <= 0 ? 0 : len),
|
||||
refCount(new size_t(1)), outOfRange() {}
|
||||
|
||||
public:
|
||||
virtual ~DTList() {
|
||||
--(*refCount);
|
||||
if (*refCount==0) {delete [] Data; delete refCount;}
|
||||
Data = 0; refCount = 0; length=0;
|
||||
if (*refCount == 0) {
|
||||
delete[] Data;
|
||||
delete refCount;
|
||||
}
|
||||
Data = 0;
|
||||
refCount = 0;
|
||||
length = 0;
|
||||
}
|
||||
|
||||
DTList<T> &operator=(const DTList<T> &A) {
|
||||
if (A.refCount != refCount) { // Otherwise doing A=A.
|
||||
--(*refCount);
|
||||
if (*refCount==0) {delete [] Data; delete refCount;}
|
||||
if (*refCount == 0) {
|
||||
delete[] Data;
|
||||
delete refCount;
|
||||
}
|
||||
refCount = A.refCount;
|
||||
++(*refCount);
|
||||
length = A.length;
|
||||
|
@ -133,43 +186,50 @@ protected:
|
|||
T outOfRange;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class DTMutableList : public DTList<T> {
|
||||
template <class T> class DTMutableList : public DTList<T> {
|
||||
public:
|
||||
DTMutableList() : DTList<T>() {}
|
||||
DTMutableList(size_t len) : DTList<T>(len) {}
|
||||
DTMutableList(const DTMutableList<T> &A) : DTList<T>(A) {}
|
||||
|
||||
DTMutableList<T> &operator=(const DTMutableList<T> &A) {DTList<T>::operator=(A); return *this;}
|
||||
DTMutableList<T> &operator=(const DTMutableList<T> &A) {
|
||||
DTList<T>::operator=(A);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T *Pointer(void) { return DTList<T>::Data; }
|
||||
const T *Pointer(void) const { return DTList<T>::Data; }
|
||||
T &operator()(size_t i) { return DTList<T>::Data[i]; }
|
||||
T operator()(size_t i) const { return DTList<T>::Data[i]; }
|
||||
|
||||
DTMutableList<T> &operator=(T v) {for (size_t i=0;i<DTList<T>::length;i++) DTList<T>::Data[i] = v; return *this;}
|
||||
DTMutableList<T> &operator=(T v) {
|
||||
for (size_t i = 0; i < DTList<T>::length; i++)
|
||||
DTList<T>::Data[i] = v;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T> DTMutableList<T> TruncateSize(const DTList<T> &A,size_t length)
|
||||
{
|
||||
if (length>A.Length()) length = A.Length();
|
||||
template <class T>
|
||||
DTMutableList<T> TruncateSize(const DTList<T> &A, size_t length) {
|
||||
if (length > A.Length())
|
||||
length = A.Length();
|
||||
DTMutableList<T> toReturn(length);
|
||||
const T *fromP = A.Pointer();
|
||||
T *toP = toReturn.Pointer();
|
||||
for (size_t i=0;i<length;i++) toP[i] = fromP[i];
|
||||
for (size_t i = 0; i < length; i++)
|
||||
toP[i] = fromP[i];
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
template <class T> DTMutableList<T> IncreaseSize(const DTList<T> &A,size_t addLength)
|
||||
{
|
||||
template <class T>
|
||||
DTMutableList<T> IncreaseSize(const DTList<T> &A, size_t addLength) {
|
||||
DTMutableList<T> toReturn(A.Length() + (addLength >= 0 ? addLength : 0));
|
||||
size_t len = A.Length();
|
||||
const T *fromP = A.Pointer();
|
||||
T *toP = toReturn.Pointer();
|
||||
for (size_t i=0;i<len;i++) toP[i] = fromP[i];
|
||||
for (size_t i = 0; i < len; i++)
|
||||
toP[i] = fromP[i];
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -1,30 +1,44 @@
|
|||
#include "analysis/SubPhase.h"
|
||||
|
||||
// Constructor
|
||||
SubPhase::SubPhase(std::shared_ptr <Domain> dm):
|
||||
Dm(dm)
|
||||
{
|
||||
Nx=dm->Nx; Ny=dm->Ny; Nz=dm->Nz;
|
||||
Volume=(Nx-2)*(Ny-2)*(Nz-2)*Dm->nprocx()*Dm->nprocy()*Dm->nprocz()*1.0;
|
||||
SubPhase::SubPhase(std::shared_ptr<Domain> dm) : Dm(dm) {
|
||||
Nx = dm->Nx;
|
||||
Ny = dm->Ny;
|
||||
Nz = dm->Nz;
|
||||
Volume = (Nx - 2) * (Ny - 2) * (Nz - 2) * Dm->nprocx() * Dm->nprocy() *
|
||||
Dm->nprocz() * 1.0;
|
||||
|
||||
morph_w = std::shared_ptr<Minkowski>(new Minkowski(Dm));
|
||||
morph_n = std::shared_ptr<Minkowski>(new Minkowski(Dm));
|
||||
morph_i = std::shared_ptr<Minkowski>(new Minkowski(Dm));
|
||||
|
||||
// Global arrays
|
||||
PhaseID.resize(Nx,Ny,Nz); PhaseID.fill(0);
|
||||
Label_WP.resize(Nx,Ny,Nz); Label_WP.fill(0);
|
||||
Label_NWP.resize(Nx,Ny,Nz); Label_NWP.fill(0);
|
||||
Rho_n.resize(Nx,Ny,Nz); Rho_n.fill(0);
|
||||
Rho_w.resize(Nx,Ny,Nz); Rho_w.fill(0);
|
||||
Pressure.resize(Nx,Ny,Nz); Pressure.fill(0);
|
||||
Phi.resize(Nx,Ny,Nz); Phi.fill(0);
|
||||
DelPhi.resize(Nx,Ny,Nz); DelPhi.fill(0);
|
||||
Vel_x.resize(Nx,Ny,Nz); Vel_x.fill(0); // Gradient of the phase indicator field
|
||||
Vel_y.resize(Nx,Ny,Nz); Vel_y.fill(0);
|
||||
Vel_z.resize(Nx,Ny,Nz); Vel_z.fill(0);
|
||||
Dissipation.resize(Nx,Ny,Nz); Dissipation.fill(0);
|
||||
SDs.resize(Nx,Ny,Nz); SDs.fill(0);
|
||||
PhaseID.resize(Nx, Ny, Nz);
|
||||
PhaseID.fill(0);
|
||||
Label_WP.resize(Nx, Ny, Nz);
|
||||
Label_WP.fill(0);
|
||||
Label_NWP.resize(Nx, Ny, Nz);
|
||||
Label_NWP.fill(0);
|
||||
Rho_n.resize(Nx, Ny, Nz);
|
||||
Rho_n.fill(0);
|
||||
Rho_w.resize(Nx, Ny, Nz);
|
||||
Rho_w.fill(0);
|
||||
Pressure.resize(Nx, Ny, Nz);
|
||||
Pressure.fill(0);
|
||||
Phi.resize(Nx, Ny, Nz);
|
||||
Phi.fill(0);
|
||||
DelPhi.resize(Nx, Ny, Nz);
|
||||
DelPhi.fill(0);
|
||||
Vel_x.resize(Nx, Ny, Nz);
|
||||
Vel_x.fill(0); // Gradient of the phase indicator field
|
||||
Vel_y.resize(Nx, Ny, Nz);
|
||||
Vel_y.fill(0);
|
||||
Vel_z.resize(Nx, Ny, Nz);
|
||||
Vel_z.fill(0);
|
||||
Dissipation.resize(Nx, Ny, Nz);
|
||||
Dissipation.fill(0);
|
||||
SDs.resize(Nx, Ny, Nz);
|
||||
SDs.fill(0);
|
||||
//.........................................
|
||||
|
||||
//.........................................
|
||||
|
@ -37,16 +51,18 @@ SubPhase::SubPhase(std::shared_ptr <Domain> dm):
|
|||
WriteHeader = true;
|
||||
|
||||
SUBPHASE = fopen("subphase.csv", "a+");
|
||||
if (WriteHeader)
|
||||
{
|
||||
if (WriteHeader) {
|
||||
// If timelog is empty, write a short header to list the averages
|
||||
//fprintf(SUBPHASE,"--------------------------------------------------------------------------------------\n");
|
||||
fprintf(SUBPHASE, "time rn rw nun nuw Fx Fy Fz iftwn wet ");
|
||||
fprintf(SUBPHASE, "pwc pwd pnc pnd "); // pressures
|
||||
fprintf(SUBPHASE, "Mwc Mwd Mwi Mnc Mnd Mni Msw Msn "); // mass
|
||||
fprintf(SUBPHASE,"Pwc_x Pwd_x Pwi_x Pnc_x Pnd_x Pni_x Psw_x Psn_x "); // momentum
|
||||
fprintf(SUBPHASE,"Pwc_y Pwd_y Pwi_y Pnc_y Pnd_y Pni_y Psw_y Psn_y ");
|
||||
fprintf(SUBPHASE,"Pwc_z Pwd_z Pwi_z Pnc_z Pnd_z Pni_z Psw_z Psn_z ");
|
||||
fprintf(
|
||||
SUBPHASE,
|
||||
"Pwc_x Pwd_x Pwi_x Pnc_x Pnd_x Pni_x Psw_x Psn_x "); // momentum
|
||||
fprintf(SUBPHASE,
|
||||
"Pwc_y Pwd_y Pwi_y Pnc_y Pnd_y Pni_y Psw_y Psn_y ");
|
||||
fprintf(SUBPHASE,
|
||||
"Pwc_z Pwd_z Pwi_z Pnc_z Pnd_z Pni_z Psw_z Psn_z ");
|
||||
fprintf(SUBPHASE, "Kwc Kwd Kwi Knc Knd Kni "); // kinetic energy
|
||||
fprintf(SUBPHASE, "Dwc Dwd Dnc Dnd "); // viscous dissipation
|
||||
fprintf(SUBPHASE, "Vwc Awc Hwc Xwc "); // wc region
|
||||
|
@ -59,18 +75,18 @@ SubPhase::SubPhase(std::shared_ptr <Domain> dm):
|
|||
// stress tensor?
|
||||
}
|
||||
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
char LocalRankString[8];
|
||||
sprintf(LocalRankString, "%05d", Dm->rank());
|
||||
char LocalRankFilename[40];
|
||||
sprintf(LocalRankFilename, "%s%s", "subphase.csv.", LocalRankString);
|
||||
SUBPHASE = fopen(LocalRankFilename, "a+");
|
||||
//fprintf(SUBPHASE,"--------------------------------------------------------------------------------------\n");
|
||||
|
||||
fprintf(SUBPHASE, "time rn rw nun nuw Fx Fy Fz iftwn wet ");
|
||||
fprintf(SUBPHASE, "pwc pwd pnc pnd "); // pressures
|
||||
fprintf(SUBPHASE, "Mwc Mwd Mwi Mnc Mnd Mni Msw Msn "); // mass
|
||||
fprintf(SUBPHASE,"Pwc_x Pwd_x Pwi_x Pnc_x Pnd_x Pni_x Psw_x Psn_x "); // momentum
|
||||
fprintf(SUBPHASE,
|
||||
"Pwc_x Pwd_x Pwi_x Pnc_x Pnd_x Pni_x Psw_x Psn_x "); // momentum
|
||||
fprintf(SUBPHASE, "Pwc_y Pwd_y Pwi_y Pnc_y Pnd_y Pni_y Psw_y Psn_y ");
|
||||
fprintf(SUBPHASE, "Pwc_z Pwd_z Pwi_z Pnc_z Pnd_z Pni_z Psw_z Psn_z ");
|
||||
fprintf(SUBPHASE, "Kwc Kwd Kwi Knc Knd Kni "); // kinetic energy
|
||||
|
@ -92,63 +108,82 @@ SubPhase::SubPhase(std::shared_ptr <Domain> dm):
|
|||
WriteHeader = true;
|
||||
|
||||
TIMELOG = fopen("timelog.csv", "a+");
|
||||
if (WriteHeader)
|
||||
{
|
||||
if (WriteHeader) {
|
||||
// If timelog is empty, write a short header to list the averages
|
||||
//fprintf(TIMELOG,"--------------------------------------------------------------------------------------\n");
|
||||
fprintf(TIMELOG,"sw krw krn krwf krnf vw vn force pw pn wet\n");
|
||||
fprintf(TIMELOG,
|
||||
"sw krw krn krwf krnf vw vn force pw pn wet peff\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Destructor
|
||||
SubPhase::~SubPhase()
|
||||
{
|
||||
if ( SUBPHASE!=NULL ) { fclose(SUBPHASE); }
|
||||
|
||||
SubPhase::~SubPhase() {
|
||||
if (SUBPHASE != NULL) {
|
||||
fclose(SUBPHASE);
|
||||
}
|
||||
}
|
||||
|
||||
void SubPhase::Write(int timestep)
|
||||
{
|
||||
void SubPhase::Write(int timestep) {
|
||||
if (Dm->rank() == 0) {
|
||||
fprintf(SUBPHASE,"%i %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ",timestep,rho_n,rho_w,nu_n,nu_w,Fx,Fy,Fz,gamma_wn,total_wetting_interaction_global);
|
||||
fprintf(SUBPHASE, "%i %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ",
|
||||
timestep, rho_n, rho_w, nu_n, nu_w, Fx, Fy, Fz, gamma_wn,
|
||||
total_wetting_interaction_global);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g ", gwc.p, gwd.p, gnc.p, gnd.p);
|
||||
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ",gwc.M, gwd.M, giwn.Mw, gnc.M, gnd.M, giwn.Mn, gifs.Mw, gifs.Mn);
|
||||
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ",gwc.Px, gwd.Px, giwn.Pwx, gnc.Px, gnd.Px, giwn.Pnx, gifs.Pwx, gifs.Pnx);
|
||||
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ",gwc.Py, gwd.Py, giwn.Pwy, gnc.Py, gnd.Py, giwn.Pny, gifs.Pwy, gifs.Pny);
|
||||
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ",gwc.Pz, gwd.Pz, giwn.Pwz, gnc.Pz, gnd.Pz, giwn.Pnz, gifs.Pwz, gifs.Pnz);
|
||||
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g %.8g %.8g ",gwc.K, gwd.K, giwn.Kw, gnc.K, gnd.K, giwn.Kn);
|
||||
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g ",gwc.visc, gwd.visc, gnc.visc, gnd.visc);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ", gwc.M,
|
||||
gwd.M, giwn.Mw, gnc.M, gnd.M, giwn.Mn, gifs.Mw, gifs.Mn);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ", gwc.Px,
|
||||
gwd.Px, giwn.Pwx, gnc.Px, gnd.Px, giwn.Pnx, gifs.Pwx, gifs.Pnx);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ", gwc.Py,
|
||||
gwd.Py, giwn.Pwy, gnc.Py, gnd.Py, giwn.Pny, gifs.Pwy, gifs.Pny);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ", gwc.Pz,
|
||||
gwd.Pz, giwn.Pwz, gnc.Pz, gnd.Pz, giwn.Pnz, gifs.Pwz, gifs.Pnz);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g %.8g %.8g ", gwc.K, gwd.K,
|
||||
giwn.Kw, gnc.K, gnd.K, giwn.Kn);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g ", gwc.visc, gwd.visc, gnc.visc,
|
||||
gnd.visc);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g ", gwc.V, gwc.A, gwc.H, gwc.X);
|
||||
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g %i ",gwd.V, gwd.A, gwd.H, gwd.X, gwd.Nc);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g %i ", gwd.V, gwd.A, gwd.H, gwd.X,
|
||||
gwd.Nc);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g ", gnc.V, gnc.A, gnc.H, gnc.X);
|
||||
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g %i ",gnd.V, gnd.A, gnd.H, gnd.X, gnd.Nc);
|
||||
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g ",giwn.V, giwn.A, giwn.H, giwn.X);
|
||||
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g %i\n",giwnc.V, giwnc.A, giwnc.H, giwnc.X, giwnc.Nc);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g %i ", gnd.V, gnd.A, gnd.H, gnd.X,
|
||||
gnd.Nc);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g ", giwn.V, giwn.A, giwn.H,
|
||||
giwn.X);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g %i\n", giwnc.V, giwnc.A, giwnc.H,
|
||||
giwnc.X, giwnc.Nc);
|
||||
fflush(SUBPHASE);
|
||||
}
|
||||
else{
|
||||
fprintf(SUBPHASE,"%i %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ",timestep,rho_n,rho_w,nu_n,nu_w,Fx,Fy,Fz,gamma_wn,total_wetting_interaction);
|
||||
} else {
|
||||
fprintf(SUBPHASE, "%i %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ",
|
||||
timestep, rho_n, rho_w, nu_n, nu_w, Fx, Fy, Fz, gamma_wn,
|
||||
total_wetting_interaction);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g ", wc.p, wd.p, nc.p, nd.p);
|
||||
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ",wc.M, wd.M, iwn.Mw, nc.M, nd.M, iwn.Mn, ifs.Mw, ifs.Mn);
|
||||
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ",wc.Px, wd.Px, iwn.Pwx, nc.Px, nd.Px, iwn.Pnx, ifs.Pwx, ifs.Pnx);
|
||||
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ",wc.Py, wd.Py, iwn.Pwy, nc.Py, nd.Py, iwn.Pny, ifs.Pwy, ifs.Pny);
|
||||
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ",wc.Pz, wd.Pz, iwn.Pwz, nc.Pz, nd.Pz, iwn.Pnz, ifs.Pwz, ifs.Pnz);
|
||||
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g %.8g %.8g ",wc.K, wd.K, iwn.Kw, nc.K, nd.K, iwn.Kn);
|
||||
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g ",wc.visc, wd.visc, nc.visc, nd.visc);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ", wc.M,
|
||||
wd.M, iwn.Mw, nc.M, nd.M, iwn.Mn, ifs.Mw, ifs.Mn);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ", wc.Px,
|
||||
wd.Px, iwn.Pwx, nc.Px, nd.Px, iwn.Pnx, ifs.Pwx, ifs.Pnx);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ", wc.Py,
|
||||
wd.Py, iwn.Pwy, nc.Py, nd.Py, iwn.Pny, ifs.Pwy, ifs.Pny);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ", wc.Pz,
|
||||
wd.Pz, iwn.Pwz, nc.Pz, nd.Pz, iwn.Pnz, ifs.Pwz, ifs.Pnz);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g %.8g %.8g ", wc.K, wd.K, iwn.Kw,
|
||||
nc.K, nd.K, iwn.Kn);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g ", wc.visc, wd.visc, nc.visc,
|
||||
nd.visc);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g ", wc.V, wc.A, wc.H, wc.X);
|
||||
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g %i ",wd.V, wd.A, wd.H, wd.X, wd.Nc);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g %i ", wd.V, wd.A, wd.H, wd.X,
|
||||
wd.Nc);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g ", nc.V, nc.A, nc.H, nc.X);
|
||||
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g %i ",nd.V, nd.A, nd.H, nd.X, nd.Nc);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g %i ", nd.V, nd.A, nd.H, nd.X,
|
||||
nd.Nc);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g ", iwn.V, iwn.A, iwn.H, iwn.X);
|
||||
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g\n",iwnc.V, iwnc.A, iwnc.H, iwnc.X);
|
||||
fprintf(SUBPHASE, "%.8g %.8g %.8g %.8g\n", iwnc.V, iwnc.A, iwnc.H,
|
||||
iwnc.X);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SubPhase::SetParams(double rhoA, double rhoB, double tauA, double tauB, double force_x, double force_y, double force_z, double alpha, double B)
|
||||
{
|
||||
void SubPhase::SetParams(double rhoA, double rhoB, double tauA, double tauB,
|
||||
double force_x, double force_y, double force_z,
|
||||
double alpha, double B) {
|
||||
Fx = force_x;
|
||||
Fy = force_y;
|
||||
Fz = force_z;
|
||||
|
@ -164,15 +199,13 @@ void SubPhase::Basic(){
|
|||
int i, j, k, n, imin, jmin, kmin, kmax;
|
||||
|
||||
// If external boundary conditions are set, do not average over the inlet
|
||||
kmin=1; kmax=Nz-1;
|
||||
kmin = 1;
|
||||
kmax = Nz - 1;
|
||||
imin = jmin = 1;
|
||||
/*// If inlet/outlet layers exist use these as default
|
||||
if (Dm->inlet_layers_x > 0) imin = Dm->inlet_layers_x;
|
||||
if (Dm->inlet_layers_y > 0) jmin = Dm->inlet_layers_y;
|
||||
if (Dm->inlet_layers_z > 0 && Dm->kproc() == 0) kmin += Dm->inlet_layers_z;
|
||||
if (Dm->outlet_layers_z > 0 && Dm->kproc() == Dm->nprocz()-1) kmax -= Dm->outlet_layers_z;
|
||||
*/
|
||||
nb.reset(); wb.reset(); iwn.reset();
|
||||
|
||||
nb.reset();
|
||||
wb.reset();
|
||||
iwn.reset();
|
||||
|
||||
double count_w = 0.0;
|
||||
double count_n = 0.0;
|
||||
|
@ -231,8 +264,7 @@ void SubPhase::Basic(){
|
|||
nb.Px += rho_n * nA * Vel_x(n);
|
||||
nb.Py += rho_n * nA * Vel_y(n);
|
||||
nb.Pz += rho_n * nA * Vel_z(n);
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
nB = 1.0;
|
||||
wb.M += nB * rho_w;
|
||||
wb.V += 1.0;
|
||||
|
@ -245,8 +277,7 @@ void SubPhase::Basic(){
|
|||
if (phi > 0.99) {
|
||||
nb.p += Pressure(n);
|
||||
count_n += 1.0;
|
||||
}
|
||||
else if ( phi < -0.99 ){
|
||||
} else if (phi < -0.99) {
|
||||
wb.p += Pressure(n);
|
||||
count_w += 1.0;
|
||||
}
|
||||
|
@ -260,8 +291,7 @@ void SubPhase::Basic(){
|
|||
iwn.Pnx += rho_n * nA * Vel_x(n);
|
||||
iwn.Pny += rho_n * nA * Vel_y(n);
|
||||
iwn.Pnz += rho_n * nA * Vel_z(n);
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
nB = 1.0;
|
||||
iwn.Mw += nB * rho_w;
|
||||
iwn.V += 1.0;
|
||||
|
@ -290,9 +320,11 @@ void SubPhase::Basic(){
|
|||
}
|
||||
}
|
||||
}
|
||||
//printf("wetting interaction = %f, count = %f\n",total_wetting_interaction,count_wetting_interaction);
|
||||
total_wetting_interaction_global=Dm->Comm.sumReduce( total_wetting_interaction);
|
||||
count_wetting_interaction_global=Dm->Comm.sumReduce( count_wetting_interaction);
|
||||
|
||||
total_wetting_interaction_global =
|
||||
Dm->Comm.sumReduce(total_wetting_interaction);
|
||||
count_wetting_interaction_global =
|
||||
Dm->Comm.sumReduce(count_wetting_interaction);
|
||||
|
||||
gwb.V = Dm->Comm.sumReduce(wb.V);
|
||||
gnb.V = Dm->Comm.sumReduce(nb.V);
|
||||
|
@ -328,16 +360,26 @@ void SubPhase::Basic(){
|
|||
|
||||
// check for NaN
|
||||
bool err = false;
|
||||
if (gwb.V != gwb.V) err=true;
|
||||
if (gnb.V != gnb.V) err=true;
|
||||
if (gwb.p != gwb.p) err=true;
|
||||
if (gnb.p != gnb.p) err=true;
|
||||
if (gwb.Px != gwb.Px) err=true;
|
||||
if (gwb.Py != gwb.Py) err=true;
|
||||
if (gwb.Pz != gwb.Pz) err=true;
|
||||
if (gnb.Px != gnb.Px) err=true;
|
||||
if (gnb.Py != gnb.Py) err=true;
|
||||
if (gnb.Pz != gnb.Pz) err=true;
|
||||
if (gwb.V != gwb.V)
|
||||
err = true;
|
||||
if (gnb.V != gnb.V)
|
||||
err = true;
|
||||
if (gwb.p != gwb.p)
|
||||
err = true;
|
||||
if (gnb.p != gnb.p)
|
||||
err = true;
|
||||
if (gwb.Px != gwb.Px)
|
||||
err = true;
|
||||
if (gwb.Py != gwb.Py)
|
||||
err = true;
|
||||
if (gwb.Pz != gwb.Pz)
|
||||
err = true;
|
||||
if (gnb.Px != gnb.Px)
|
||||
err = true;
|
||||
if (gnb.Py != gnb.Py)
|
||||
err = true;
|
||||
if (gnb.Pz != gnb.Pz)
|
||||
err = true;
|
||||
|
||||
if (Dm->rank() == 0) {
|
||||
/* align flow direction based on total mass flux */
|
||||
|
@ -350,13 +392,13 @@ void SubPhase::Basic(){
|
|||
dir_x = Fx / force_mag;
|
||||
dir_y = Fy / force_mag;
|
||||
dir_z = Fz / force_mag;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
dir_x /= flow_magnitude;
|
||||
dir_y /= flow_magnitude;
|
||||
dir_z /= flow_magnitude;
|
||||
}
|
||||
if (Dm->BoundaryCondition == 1 || Dm->BoundaryCondition == 2 || Dm->BoundaryCondition == 3 || Dm->BoundaryCondition == 4 ){
|
||||
if (Dm->BoundaryCondition == 1 || Dm->BoundaryCondition == 2 ||
|
||||
Dm->BoundaryCondition == 3 || Dm->BoundaryCondition == 4) {
|
||||
// compute the pressure drop
|
||||
double pressure_drop = (Pressure(Nx * Ny + Nx + 1) - 1.0) / 3.0;
|
||||
double length = ((Nz - 2) * Dm->nprocz());
|
||||
|
@ -370,34 +412,49 @@ void SubPhase::Basic(){
|
|||
force_mag = 1.0;
|
||||
}
|
||||
double saturation = gwb.V / (gwb.V + gnb.V);
|
||||
double water_flow_rate=gwb.V*(gwb.Px*dir_x + gwb.Py*dir_y + gwb.Pz*dir_z)/gwb.M / Dm->Volume;
|
||||
double not_water_flow_rate=gnb.V*(gnb.Px*dir_x + gnb.Py*dir_y + gnb.Pz*dir_z)/gnb.M/ Dm->Volume;
|
||||
double water_flow_rate =
|
||||
gwb.V * (gwb.Px * dir_x + gwb.Py * dir_y + gwb.Pz * dir_z) / gwb.M /
|
||||
Dm->Volume;
|
||||
double not_water_flow_rate =
|
||||
gnb.V * (gnb.Px * dir_x + gnb.Py * dir_y + gnb.Pz * dir_z) / gnb.M /
|
||||
Dm->Volume;
|
||||
|
||||
/* contribution from water films */
|
||||
double water_film_flow_rate=gwb.V*(giwn.Pwx*dir_x + giwn.Pwy*dir_y + giwn.Pwz*dir_z)/gwb.M / Dm->Volume;
|
||||
double not_water_film_flow_rate=gnb.V*(giwn.Pnx*dir_x + giwn.Pny*dir_y + giwn.Pnz*dir_z)/gnb.M / Dm->Volume;
|
||||
double water_film_flow_rate =
|
||||
gwb.V * (giwn.Pwx * dir_x + giwn.Pwy * dir_y + giwn.Pwz * dir_z) /
|
||||
gwb.M / Dm->Volume;
|
||||
double not_water_film_flow_rate =
|
||||
gnb.V * (giwn.Pnx * dir_x + giwn.Pny * dir_y + giwn.Pnz * dir_z) /
|
||||
gnb.M / Dm->Volume;
|
||||
//double total_flow_rate = water_flow_rate + not_water_flow_rate;
|
||||
//double fractional_flow = water_flow_rate / total_flow_rate;
|
||||
|
||||
double h = Dm->voxel_length;
|
||||
double krn = h * h * nu_n * not_water_flow_rate / force_mag;
|
||||
double krw = h * h * nu_w * water_flow_rate / force_mag;
|
||||
/* not counting films */
|
||||
double krnf = krn - h * h * nu_n * not_water_film_flow_rate / force_mag;
|
||||
double krwf = krw - h * h * nu_w * water_film_flow_rate / force_mag;
|
||||
//printf(" water saturation = %f, fractional flow =%f \n",saturation,fractional_flow);
|
||||
fprintf(TIMELOG,"%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g\n",saturation,krw,krn,krwf,krnf,h*water_flow_rate,h*not_water_flow_rate, force_mag, gwb.p, gnb.p, total_wetting_interaction_global);
|
||||
double eff_pressure = 1.0 / (krn + krw); // effective pressure drop
|
||||
|
||||
fprintf(TIMELOG,
|
||||
"%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g\n",
|
||||
saturation, krw, krn, krwf, krnf, h * water_flow_rate,
|
||||
h * not_water_flow_rate, force_mag, gwb.p, gnb.p,
|
||||
total_wetting_interaction_global, eff_pressure);
|
||||
fflush(TIMELOG);
|
||||
}
|
||||
if (err == true) {
|
||||
// exception if simulation produceds NaN
|
||||
printf("SubPhase.cpp: NaN encountered, may need to check simulation parameters \n");
|
||||
printf("SubPhase.cpp: NaN encountered, may need to check simulation "
|
||||
"parameters \n");
|
||||
}
|
||||
ASSERT(err == false);
|
||||
}
|
||||
|
||||
inline void InterfaceTransportMeasures( double beta, double rA, double rB, double nA, double nB,
|
||||
double nx, double ny, double nz, double ux, double uy, double uz, interface &I){
|
||||
inline void InterfaceTransportMeasures(double beta, double rA, double rB,
|
||||
double nA, double nB, double nx,
|
||||
double ny, double nz, double ux,
|
||||
double uy, double uz, interface &I) {
|
||||
|
||||
double A1, A2, A3, A4, A5, A6;
|
||||
double B1, B2, B3, B4, B5, B6;
|
||||
|
@ -410,7 +467,8 @@ inline void InterfaceTransportMeasures( double beta, double rA, double rB, doubl
|
|||
// q = 0,2,4
|
||||
// Cq = {1,0,0}, {0,1,0}, {0,0,1}
|
||||
delta = beta * nA * nB * nAB * 0.1111111111111111 * nx;
|
||||
if (!(nA*nB*nAB>0)) delta=0;
|
||||
if (!(nA * nB * nAB > 0))
|
||||
delta = 0;
|
||||
A1 = nA * (0.1111111111111111 * (1 + 4.5 * ux)) + delta;
|
||||
B1 = nB * (0.1111111111111111 * (1 + 4.5 * ux)) - delta;
|
||||
A2 = nA * (0.1111111111111111 * (1 - 4.5 * ux)) - delta;
|
||||
|
@ -419,7 +477,8 @@ inline void InterfaceTransportMeasures( double beta, double rA, double rB, doubl
|
|||
//...............................................
|
||||
// Cq = {0,1,0}
|
||||
delta = beta * nA * nB * nAB * 0.1111111111111111 * ny;
|
||||
if (!(nA*nB*nAB>0)) delta=0;
|
||||
if (!(nA * nB * nAB > 0))
|
||||
delta = 0;
|
||||
A3 = nA * (0.1111111111111111 * (1 + 4.5 * uy)) + delta;
|
||||
B3 = nB * (0.1111111111111111 * (1 + 4.5 * uy)) - delta;
|
||||
A4 = nA * (0.1111111111111111 * (1 - 4.5 * uy)) - delta;
|
||||
|
@ -429,7 +488,8 @@ inline void InterfaceTransportMeasures( double beta, double rA, double rB, doubl
|
|||
// q = 4
|
||||
// Cq = {0,0,1}
|
||||
delta = beta * nA * nB * nAB * 0.1111111111111111 * nz;
|
||||
if (!(nA*nB*nAB>0)) delta=0;
|
||||
if (!(nA * nB * nAB > 0))
|
||||
delta = 0;
|
||||
A5 = nA * (0.1111111111111111 * (1 + 4.5 * uz)) + delta;
|
||||
B5 = nB * (0.1111111111111111 * (1 + 4.5 * uz)) - delta;
|
||||
A6 = nA * (0.1111111111111111 * (1 - 4.5 * uz)) - delta;
|
||||
|
@ -458,8 +518,7 @@ inline void InterfaceTransportMeasures( double beta, double rA, double rB, doubl
|
|||
I.Pnx += rA * ux;
|
||||
I.Pny += rA * uy;
|
||||
I.Pnz += rA * uz;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
I.Mw += rB;
|
||||
I.Pwx += rB * ux;
|
||||
I.Pwy += rB * uy;
|
||||
|
@ -467,26 +526,23 @@ inline void InterfaceTransportMeasures( double beta, double rA, double rB, doubl
|
|||
}
|
||||
I.Kn += rA * nA * (unx * unx + uny * uny + unz * unz);
|
||||
I.Kw += rB * nB * (uwx * uwx + uwy * uwy + uwz * uwz);
|
||||
|
||||
}
|
||||
|
||||
void SubPhase::Full() {
|
||||
int i, j, k, n, imin, jmin, kmin, kmax;
|
||||
|
||||
// If external boundary conditions are set, do not average over the inlet
|
||||
kmin=1; kmax=Nz-1;
|
||||
/*if (Dm->BoundaryCondition > 0 && Dm->BoundaryCondition != 5 && Dm->kproc() == 0) kmin=4;
|
||||
if (Dm->BoundaryCondition > 0 && Dm->BoundaryCondition != 5 && Dm->kproc() == Dm->nprocz()-1) kmax=Nz-4;
|
||||
*/
|
||||
kmin = 1;
|
||||
kmax = Nz - 1;
|
||||
imin = jmin = 1;
|
||||
/*// If inlet layers exist use these as default
|
||||
* NOTE -- excluding inlet / outlet will screw up topological averages!!!
|
||||
if (Dm->inlet_layers_x > 0) imin = Dm->inlet_layers_x;
|
||||
if (Dm->inlet_layers_y > 0) jmin = Dm->inlet_layers_y;
|
||||
if (Dm->inlet_layers_z > 0 && Dm->kproc() == 0) kmin += Dm->inlet_layers_z;
|
||||
if (Dm->outlet_layers_z > 0 && Dm->kproc() == Dm->nprocz()-1) kmax -= Dm->outlet_layers_z;
|
||||
*/
|
||||
nd.reset(); nc.reset(); wd.reset(); wc.reset(); iwn.reset(); iwnc.reset(); ifs.reset();
|
||||
|
||||
nd.reset();
|
||||
nc.reset();
|
||||
wd.reset();
|
||||
wc.reset();
|
||||
iwn.reset();
|
||||
iwnc.reset();
|
||||
ifs.reset();
|
||||
|
||||
Dm->CommunicateMeshHalo(Phi);
|
||||
for (int k = 1; k < Nz - 1; k++) {
|
||||
|
@ -502,7 +558,6 @@ void SubPhase::Full(){
|
|||
}
|
||||
Dm->CommunicateMeshHalo(DelPhi);
|
||||
|
||||
|
||||
Dm->CommunicateMeshHalo(Vel_x);
|
||||
Dm->CommunicateMeshHalo(Vel_y);
|
||||
Dm->CommunicateMeshHalo(Vel_z);
|
||||
|
@ -523,7 +578,11 @@ void SubPhase::Full(){
|
|||
double wy = 0.5 * (Vel_z(i, j + 1, k) - Vel_z(i, j - 1, k));
|
||||
double wz = 0.5 * (Vel_z(i, j, k + 1) - Vel_z(i, j, k - 1));
|
||||
if (SDs(i, j, k) > 2.0) {
|
||||
Dissipation(i,j,k) = 2*rho*nu*( ux*ux + vy*vy + wz*wz + 0.5*(vx + uy)*(vx + uy)+ 0.5*(vz + wy)*(vz + wy)+ 0.5*(uz + wx)*(uz + wx));
|
||||
Dissipation(i, j, k) = 2 * rho * nu *
|
||||
(ux * ux + vy * vy + wz * wz +
|
||||
0.5 * (vx + uy) * (vx + uy) +
|
||||
0.5 * (vz + wy) * (vz + wy) +
|
||||
0.5 * (uz + wx) * (uz + wx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -540,12 +599,10 @@ void SubPhase::Full(){
|
|||
// Solid phase
|
||||
morph_n->id(i, j, k) = 1;
|
||||
|
||||
}
|
||||
else if (Phi(n) > 0.0){
|
||||
} else if (Phi(n) > 0.0) {
|
||||
// non-wetting phase
|
||||
morph_n->id(i, j, k) = 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// wetting phase
|
||||
morph_n->id(i, j, k) = 1;
|
||||
}
|
||||
|
@ -589,12 +646,10 @@ void SubPhase::Full(){
|
|||
// Solid phase
|
||||
morph_w->id(i, j, k) = 1;
|
||||
|
||||
}
|
||||
else if (Phi(n) < 0.0){
|
||||
} else if (Phi(n) < 0.0) {
|
||||
// wetting phase
|
||||
morph_w->id(i, j, k) = 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// non-wetting phase
|
||||
morph_w->id(i, j, k) = 1;
|
||||
}
|
||||
|
@ -636,12 +691,10 @@ void SubPhase::Full(){
|
|||
if (!(Dm->id[n] > 0)) {
|
||||
// Solid phase
|
||||
morph_i->id(i, j, k) = 1;
|
||||
}
|
||||
else if (DelPhi(n) > 1e-4){
|
||||
} else if (DelPhi(n) > 1e-4) {
|
||||
// interface
|
||||
morph_i->id(i, j, k) = 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// not interface
|
||||
morph_i->id(i, j, k) = 1;
|
||||
}
|
||||
|
@ -695,9 +748,10 @@ void SubPhase::Full(){
|
|||
double nz = 0.5 * (Phi(i, j, k + 1) - Phi(i, j, k - 1));
|
||||
if (SDs(n) > 2.5) {
|
||||
// not a film region
|
||||
InterfaceTransportMeasures( beta, rho_w, rho_n, nA, nB, nx, ny, nz, ux, uy, uz, iwn);
|
||||
}
|
||||
else{
|
||||
InterfaceTransportMeasures(beta, rho_w, rho_n, nA,
|
||||
nB, nx, ny, nz, ux, uy,
|
||||
uz, iwn);
|
||||
} else {
|
||||
// films that are close to the wetting fluid
|
||||
if (morph_w->distance(i, j, k) < 2.5 && phi > 0.0) {
|
||||
ifs.Mw += rho_w;
|
||||
|
@ -713,24 +767,20 @@ void SubPhase::Full(){
|
|||
ifs.Pnz += rho_n * uz;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( phi > 0.0){
|
||||
} else if (phi > 0.0) {
|
||||
if (morph_n->label(i, j, k) > 0) {
|
||||
vol_nd_bulk += 1.0;
|
||||
nd.p += Pressure(n);
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
vol_nc_bulk += 1.0;
|
||||
nc.p += Pressure(n);
|
||||
}
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
// water region
|
||||
if (morph_w->label(i, j, k) > 0) {
|
||||
vol_wd_bulk += 1.0;
|
||||
wd.p += Pressure(n);
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
vol_wc_bulk += 1.0;
|
||||
wc.p += Pressure(n);
|
||||
}
|
||||
|
@ -744,8 +794,7 @@ void SubPhase::Full(){
|
|||
nd.Pz += nA * rho_n * uz;
|
||||
nd.K += nA * rho_n * (ux * ux + uy * uy + uz * uz);
|
||||
nd.visc += visc;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
nA = 1.0;
|
||||
nc.M += nA * rho_n;
|
||||
nc.Px += nA * rho_n * ux;
|
||||
|
@ -754,8 +803,7 @@ void SubPhase::Full(){
|
|||
nc.K += nA * rho_n * (ux * ux + uy * uy + uz * uz);
|
||||
nc.visc += visc;
|
||||
}
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
// water region
|
||||
if (morph_w->label(i, j, k) > 0) {
|
||||
nB = 1.0;
|
||||
|
@ -765,8 +813,7 @@ void SubPhase::Full(){
|
|||
wd.Pz += nB * rho_w * uz;
|
||||
wd.K += nB * rho_w * (ux * ux + uy * uy + uz * uz);
|
||||
wd.visc += visc;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
nB = 1.0;
|
||||
wc.M += nB * rho_w;
|
||||
wc.Px += nB * rho_w * ux;
|
||||
|
@ -859,15 +906,12 @@ void SubPhase::Full(){
|
|||
gnd.p = gnd.p / vol_nd_bulk;
|
||||
}
|
||||
|
||||
|
||||
void SubPhase::AggregateLabels( const std::string& filename )
|
||||
{
|
||||
void SubPhase::AggregateLabels(const std::string &filename) {
|
||||
|
||||
int nx = Dm->Nx;
|
||||
int ny = Dm->Ny;
|
||||
int nz = Dm->Nz;
|
||||
|
||||
//printf("aggregate labels: local size=%i, global size = %i",local_size, full_size);
|
||||
// assign the ID from the phase indicator field
|
||||
for (int k = 0; k < nz; k++) {
|
||||
for (int j = 0; j < ny; j++) {
|
||||
|
@ -876,8 +920,10 @@ void SubPhase::AggregateLabels( const std::string& filename )
|
|||
signed char local_id_val = Dm->id[n];
|
||||
if (local_id_val > 0) {
|
||||
double value = Phi(i, j, k);
|
||||
if (value > 0.0) local_id_val = 1;
|
||||
else local_id_val = 2;
|
||||
if (value > 0.0)
|
||||
local_id_val = 1;
|
||||
else
|
||||
local_id_val = 2;
|
||||
}
|
||||
Dm->id[n] = local_id_val;
|
||||
}
|
||||
|
@ -886,8 +932,4 @@ void SubPhase::AggregateLabels( const std::string& filename )
|
|||
Dm->Comm.barrier();
|
||||
|
||||
Dm->AggregateLabels(filename);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "IO/Reader.h"
|
||||
#include "IO/Writer.h"
|
||||
|
||||
|
||||
class phase {
|
||||
public:
|
||||
int Nc;
|
||||
|
@ -86,7 +85,8 @@ public:
|
|||
IntArray PhaseID; // Phase ID array (solid=0, non-wetting=1, wetting=2)
|
||||
BlobIDArray Label_WP; // Wetting phase label
|
||||
BlobIDArray Label_NWP; // Non-wetting phase label index (0:nblobs-1)
|
||||
std::vector<BlobIDType> Label_NWP_map; // Non-wetting phase label for each index
|
||||
std::vector<BlobIDType>
|
||||
Label_NWP_map; // Non-wetting phase label for each index
|
||||
DoubleArray Rho_n; // density field
|
||||
DoubleArray Rho_w; // density field
|
||||
DoubleArray Phi; // phase indicator field
|
||||
|
@ -105,7 +105,9 @@ public:
|
|||
SubPhase(std::shared_ptr<Domain> Dm);
|
||||
~SubPhase();
|
||||
|
||||
void SetParams(double rhoA, double rhoB, double tauA, double tauB, double force_x, double force_y, double force_z, double alpha, double beta);
|
||||
void SetParams(double rhoA, double rhoB, double tauA, double tauB,
|
||||
double force_x, double force_y, double force_z, double alpha,
|
||||
double beta);
|
||||
void Basic();
|
||||
void Full();
|
||||
void Write(int time);
|
||||
|
@ -117,4 +119,3 @@ private:
|
|||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// Header file for two-phase averaging class
|
||||
#ifndef TwoPhase_INC
|
||||
#define TwoPhase_INC
|
||||
|
@ -17,11 +33,11 @@
|
|||
#include "IO/Reader.h"
|
||||
#include "IO/Writer.h"
|
||||
|
||||
|
||||
class TwoPhase {
|
||||
|
||||
//...........................................................................
|
||||
int n_nw_pts,n_ns_pts,n_ws_pts,n_nws_pts,n_local_sol_pts,n_local_nws_pts;
|
||||
int n_nw_pts, n_ns_pts, n_ws_pts, n_nws_pts, n_local_sol_pts,
|
||||
n_local_nws_pts;
|
||||
int n_nw_tris, n_ns_tris, n_ws_tris, n_nws_seg, n_local_sol_tris;
|
||||
//...........................................................................
|
||||
int nc;
|
||||
|
@ -81,7 +97,8 @@ public:
|
|||
double pan, paw; // local phase averaged pressure
|
||||
// Global averages (all processes)
|
||||
double pan_global, paw_global; // local phase averaged pressure
|
||||
double vol_w_global, vol_n_global; // volumes the exclude the interfacial region
|
||||
double vol_w_global,
|
||||
vol_n_global; // volumes the exclude the interfacial region
|
||||
double awn_global, ans_global, aws_global;
|
||||
double lwns_global;
|
||||
double efawns, efawns_global; // averaged contact angle
|
||||
|
@ -127,7 +144,8 @@ public:
|
|||
IntArray PhaseID; // Phase ID array (solid=0, non-wetting=1, wetting=2)
|
||||
BlobIDArray Label_WP; // Wetting phase label
|
||||
BlobIDArray Label_NWP; // Non-wetting phase label index (0:nblobs-1)
|
||||
std::vector<BlobIDType> Label_NWP_map; // Non-wetting phase label for each index
|
||||
std::vector<BlobIDType>
|
||||
Label_NWP_map; // Non-wetting phase label for each index
|
||||
DoubleArray SDn;
|
||||
DoubleArray SDs;
|
||||
DoubleArray Phase;
|
||||
|
@ -163,7 +181,8 @@ public:
|
|||
void UpdateMeshValues();
|
||||
void UpdateSolid();
|
||||
void ComputeDelPhi();
|
||||
void ColorToSignedDistance(double Beta, DoubleArray &ColorData, DoubleArray &DistData);
|
||||
void ColorToSignedDistance(double Beta, DoubleArray &ColorData,
|
||||
DoubleArray &DistData);
|
||||
void ComputeLocal();
|
||||
void AssignComponentLabels();
|
||||
void ComponentAverages();
|
||||
|
@ -173,15 +192,11 @@ public:
|
|||
int GetCubeLabel(int i, int j, int k, IntArray &BlobLabel);
|
||||
void SortBlobs();
|
||||
void PrintComponents(int timestep);
|
||||
void SetParams(double rhoA, double rhoB, double tauA, double tauB, double force_x, double force_y, double force_z, double alpha);
|
||||
double Volume_w(){
|
||||
return wp_volume_global;
|
||||
}
|
||||
double Volume_n(){
|
||||
return nwp_volume_global;
|
||||
}
|
||||
void SetParams(double rhoA, double rhoB, double tauA, double tauB,
|
||||
double force_x, double force_y, double force_z,
|
||||
double alpha);
|
||||
double Volume_w() { return wp_volume_global; }
|
||||
double Volume_n() { return nwp_volume_global; }
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,21 +1,38 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "analysis/analysis.h"
|
||||
#include "ProfilerApp.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
template<class TYPE>
|
||||
inline TYPE* getPtr( std::vector<TYPE>& x ) { return x.empty() ? NULL:&x[0]; }
|
||||
template<class TYPE>
|
||||
inline const TYPE* getPtr( const std::vector<TYPE>& x ) { return x.empty() ? NULL:&x[0]; }
|
||||
|
||||
template <class TYPE> inline TYPE *getPtr(std::vector<TYPE> &x) {
|
||||
return x.empty() ? NULL : &x[0];
|
||||
}
|
||||
template <class TYPE> inline const TYPE *getPtr(const std::vector<TYPE> &x) {
|
||||
return x.empty() ? NULL : &x[0];
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* Compute the blobs *
|
||||
******************************************************************/
|
||||
int ComputeBlob( const Array<bool>& isPhase, BlobIDArray& LocalBlobID, bool periodic, int start_id )
|
||||
{
|
||||
int ComputeBlob(const Array<bool> &isPhase, BlobIDArray &LocalBlobID,
|
||||
bool periodic, int start_id) {
|
||||
PROFILE_START("ComputeBlob", 1);
|
||||
ASSERT(isPhase.size() == LocalBlobID.size());
|
||||
const int Nx = isPhase.size(0); // maxima for the meshes
|
||||
|
@ -26,27 +43,33 @@ int ComputeBlob( const Array<bool>& isPhase, BlobIDArray& LocalBlobID, bool peri
|
|||
// Get the list of neighbors we need to check
|
||||
int N_neighbors = 0;
|
||||
int d[26][3];
|
||||
bool include_corners = false; // Do we need to include cells that only touch at a corder/edge
|
||||
bool include_corners =
|
||||
false; // Do we need to include cells that only touch at a corder/edge
|
||||
if (include_corners) {
|
||||
// Include corners/edges as neighbors, check all cells
|
||||
N_neighbors = 26;
|
||||
const int tmp[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}}; // directions to neighbors
|
||||
const int tmp[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}}; // directions to neighbors
|
||||
memcpy(d, tmp, sizeof(tmp));
|
||||
} else {
|
||||
// Do not include corners/edges as neighbors
|
||||
if (periodic) {
|
||||
// Include all neighbors for periodic problems
|
||||
N_neighbors = 6;
|
||||
const int tmp[6][3] = {{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}}; // directions to neighbors
|
||||
const int tmp[6][3] = {
|
||||
{1, 0, 0}, {-1, 0, 0}, {0, 1, 0},
|
||||
{0, -1, 0}, {0, 0, 1}, {0, 0, -1}}; // directions to neighbors
|
||||
memcpy(d, tmp, sizeof(tmp));
|
||||
} else {
|
||||
// We only need to include the lower neighbors for non-periodic problems
|
||||
N_neighbors = 3;
|
||||
const int tmp[3][3] = {{-1,0,0},{0,-1,0},{0,0,-1}}; // directions to neighbors
|
||||
const int tmp[3][3] = {
|
||||
{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}}; // directions to neighbors
|
||||
memcpy(d, tmp, sizeof(tmp));
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +100,8 @@ int ComputeBlob( const Array<bool>& isPhase, BlobIDArray& LocalBlobID, bool peri
|
|||
z2 = z2 < 0 ? Nz - 1 : z2; // Periodic BC for x
|
||||
z2 = z2 > Nz - 1 ? 0 : z2;
|
||||
} else {
|
||||
if ( x2<0 || x2>=Nx || y2<0 || y2>=Ny || z2<0 || z2>=Nz )
|
||||
if (x2 < 0 || x2 >= Nx || y2 < 0 || y2 >= Ny ||
|
||||
z2 < 0 || z2 >= Nz)
|
||||
continue;
|
||||
}
|
||||
// Check if a neighbor has a known blob id
|
||||
|
@ -103,7 +127,8 @@ int ComputeBlob( const Array<bool>& isPhase, BlobIDArray& LocalBlobID, bool peri
|
|||
id = std::min(id, neighbor_ids[i]);
|
||||
LocalBlobIDPtr[index] = id;
|
||||
for (int i = 0; i < N_list; i++)
|
||||
map[neighbor_ids[i]-start_id] = std::min(map[neighbor_ids[i]-start_id],id);
|
||||
map[neighbor_ids[i] - start_id] =
|
||||
std::min(map[neighbor_ids[i] - start_id], id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -128,13 +153,12 @@ int ComputeBlob( const Array<bool>& isPhase, BlobIDArray& LocalBlobID, bool peri
|
|||
return last - start_id + 1;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* Compute the local blob ids *
|
||||
******************************************************************/
|
||||
int ComputeLocalBlobIDs(const DoubleArray &Phase, const DoubleArray &SignDist,
|
||||
double vF, double vS, BlobIDArray& LocalBlobID, bool periodic )
|
||||
{
|
||||
double vF, double vS, BlobIDArray &LocalBlobID,
|
||||
bool periodic) {
|
||||
PROFILE_START("ComputeLocalBlobIDs");
|
||||
ASSERT(SignDist.size() == Phase.size());
|
||||
size_t Nx = Phase.size(0);
|
||||
|
@ -160,8 +184,8 @@ int ComputeLocalBlobIDs( const DoubleArray& Phase, const DoubleArray& SignDist,
|
|||
PROFILE_STOP("ComputeLocalBlobIDs");
|
||||
return nblobs;
|
||||
}
|
||||
int ComputeLocalPhaseComponent(const IntArray &PhaseID, int &VALUE, BlobIDArray &ComponentLabel, bool periodic )
|
||||
{
|
||||
int ComputeLocalPhaseComponent(const IntArray &PhaseID, int &VALUE,
|
||||
BlobIDArray &ComponentLabel, bool periodic) {
|
||||
PROFILE_START("ComputeLocalPhaseComponent");
|
||||
size_t Nx = PhaseID.size(0);
|
||||
size_t Ny = PhaseID.size(1);
|
||||
|
@ -184,12 +208,11 @@ int ComputeLocalPhaseComponent(const IntArray &PhaseID, int &VALUE, BlobIDArray
|
|||
return ncomponents;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* Reorder the global blob ids *
|
||||
******************************************************************/
|
||||
static int ReorderBlobIDs2( BlobIDArray& ID, int N_blobs, int ngx, int ngy, int ngz, const Utilities::MPI& comm )
|
||||
{
|
||||
static int ReorderBlobIDs2(BlobIDArray &ID, int N_blobs, int ngx, int ngy,
|
||||
int ngz, const Utilities::MPI &comm) {
|
||||
if (N_blobs == 0)
|
||||
return 0;
|
||||
PROFILE_START("ReorderBlobIDs2", 1);
|
||||
|
@ -235,8 +258,7 @@ static int ReorderBlobIDs2( BlobIDArray& ID, int N_blobs, int ngx, int ngy, int
|
|||
PROFILE_STOP("ReorderBlobIDs2", 1);
|
||||
return N_blobs2;
|
||||
}
|
||||
void ReorderBlobIDs( BlobIDArray& ID, const Utilities::MPI& comm )
|
||||
{
|
||||
void ReorderBlobIDs(BlobIDArray &ID, const Utilities::MPI &comm) {
|
||||
PROFILE_START("ReorderBlobIDs");
|
||||
int tmp = ID.max() + 1;
|
||||
int N_blobs = 0;
|
||||
|
@ -245,7 +267,6 @@ void ReorderBlobIDs( BlobIDArray& ID, const Utilities::MPI& comm )
|
|||
PROFILE_STOP("ReorderBlobIDs");
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* Compute the global blob ids *
|
||||
******************************************************************/
|
||||
|
@ -254,14 +275,12 @@ struct global_id_info_struct {
|
|||
std::set<int64_t> remote_ids;
|
||||
};
|
||||
// Send the local ids and their new value to all neighbors
|
||||
static void updateRemoteIds(
|
||||
const std::map<int64_t,global_id_info_struct>& map,
|
||||
const std::vector<int>& neighbors,
|
||||
int N_send, const std::vector<int>& N_recv,
|
||||
int64_t *send_buf, std::vector<int64_t*>& recv_buf,
|
||||
static void updateRemoteIds(const std::map<int64_t, global_id_info_struct> &map,
|
||||
const std::vector<int> &neighbors, int N_send,
|
||||
const std::vector<int> &N_recv, int64_t *send_buf,
|
||||
std::vector<int64_t *> &recv_buf,
|
||||
std::map<int64_t, int64_t> &remote_map,
|
||||
const Utilities::MPI& comm )
|
||||
{
|
||||
const Utilities::MPI &comm) {
|
||||
std::vector<MPI_Request> send_req(neighbors.size());
|
||||
std::vector<MPI_Request> recv_req(neighbors.size());
|
||||
auto it = map.begin();
|
||||
|
@ -286,14 +305,14 @@ static void updateRemoteIds(
|
|||
}
|
||||
// Compute a new local id for each local id
|
||||
static bool updateLocalIds(const std::map<int64_t, int64_t> &remote_map,
|
||||
std::map<int64_t,global_id_info_struct>& map )
|
||||
{
|
||||
std::map<int64_t, global_id_info_struct> &map) {
|
||||
bool changed = false;
|
||||
std::map<int64_t, global_id_info_struct>::iterator it;
|
||||
for (it = map.begin(); it != map.end(); ++it) {
|
||||
int64_t id = it->second.new_id;
|
||||
std::set<int64_t>::const_iterator it2;
|
||||
for (it2=it->second.remote_ids.begin(); it2!=it->second.remote_ids.end(); ++it2) {
|
||||
for (it2 = it->second.remote_ids.begin();
|
||||
it2 != it->second.remote_ids.end(); ++it2) {
|
||||
int64_t id2 = remote_map.find(*it2)->second;
|
||||
id = std::min(id, id2);
|
||||
}
|
||||
|
@ -302,9 +321,9 @@ static bool updateLocalIds( const std::map<int64_t,int64_t>& remote_map,
|
|||
}
|
||||
return changed;
|
||||
}
|
||||
static int LocalToGlobalIDs( int nx, int ny, int nz, const RankInfoStruct& rank_info,
|
||||
int nblobs, BlobIDArray& IDs, const Utilities::MPI& comm )
|
||||
{
|
||||
static int LocalToGlobalIDs(int nx, int ny, int nz,
|
||||
const RankInfoStruct &rank_info, int nblobs,
|
||||
BlobIDArray &IDs, const Utilities::MPI &comm) {
|
||||
PROFILE_START("LocalToGlobalIDs", 1);
|
||||
const int rank = rank_info.rank[1][1][1];
|
||||
int nprocs = comm.getSize();
|
||||
|
@ -330,7 +349,8 @@ static int LocalToGlobalIDs( int nx, int ny, int nz, const RankInfoStruct& rank_
|
|||
}
|
||||
const BlobIDArray LocalIDs = IDs;
|
||||
// Copy the ids and get the neighbors through the halos
|
||||
fillHalo<BlobIDType> fillData(comm,rank_info,{nx,ny,nz},{1,1,1},0,1,{true,true,true});
|
||||
fillHalo<BlobIDType> fillData(comm, rank_info, {nx, ny, nz}, {1, 1, 1}, 0,
|
||||
1, {true, true, true});
|
||||
fillData.fill(IDs);
|
||||
// Create a list of all neighbor ranks (excluding self)
|
||||
std::vector<int> neighbors;
|
||||
|
@ -341,7 +361,8 @@ static int LocalToGlobalIDs( int nx, int ny, int nz, const RankInfoStruct& rank_
|
|||
neighbors.push_back(rank_info.rank[1][1][0]);
|
||||
neighbors.push_back(rank_info.rank[1][1][2]);
|
||||
std::sort(neighbors.begin(), neighbors.end());
|
||||
neighbors.erase( std::unique( neighbors.begin(), neighbors.end() ), neighbors.end() );
|
||||
neighbors.erase(std::unique(neighbors.begin(), neighbors.end()),
|
||||
neighbors.end());
|
||||
// Create a map of all local ids to the neighbor ids
|
||||
std::map<int64_t, global_id_info_struct> map;
|
||||
std::set<int64_t> local;
|
||||
|
@ -378,7 +399,8 @@ static int LocalToGlobalIDs( int nx, int ny, int nz, const RankInfoStruct& rank_
|
|||
for (it = map.begin(); it != map.end(); ++it) {
|
||||
int64_t id = it->first;
|
||||
std::set<int64_t>::const_iterator it2;
|
||||
for (it2=it->second.remote_ids.begin(); it2!=it->second.remote_ids.end(); ++it2) {
|
||||
for (it2 = it->second.remote_ids.begin();
|
||||
it2 != it->second.remote_ids.end(); ++it2) {
|
||||
int64_t id2 = *it2;
|
||||
id = std::min(id, id2);
|
||||
remote_map.insert(std::pair<int64_t, int64_t>(id2, id2));
|
||||
|
@ -391,7 +413,8 @@ static int LocalToGlobalIDs( int nx, int ny, int nz, const RankInfoStruct& rank_
|
|||
while (1) {
|
||||
iteration++;
|
||||
// Send the local ids and their new value to all neighbors
|
||||
updateRemoteIds( map, neighbors, N_send, N_recv,send_buf, recv_buf, remote_map, comm );
|
||||
updateRemoteIds(map, neighbors, N_send, N_recv, send_buf, recv_buf,
|
||||
remote_map, comm);
|
||||
// Compute a new local id for each local id
|
||||
bool changed = updateLocalIds(remote_map, map);
|
||||
// Check if we are finished
|
||||
|
@ -405,7 +428,8 @@ static int LocalToGlobalIDs( int nx, int ny, int nz, const RankInfoStruct& rank_
|
|||
std::vector<int> final_map(nblobs, -1);
|
||||
for (it = map.begin(); it != map.end(); ++it)
|
||||
final_map[it->first - offset] = it->second.new_id;
|
||||
for (std::set<int64_t>::const_iterator it2=local.begin(); it2!=local.end(); ++it2)
|
||||
for (std::set<int64_t>::const_iterator it2 = local.begin();
|
||||
it2 != local.end(); ++it2)
|
||||
final_map[*it2 - offset] = *it2;
|
||||
for (size_t i = 0; i < final_map.size(); i++)
|
||||
ASSERT(final_map[i] >= 0);
|
||||
|
@ -419,7 +443,8 @@ static int LocalToGlobalIDs( int nx, int ny, int nz, const RankInfoStruct& rank_
|
|||
}
|
||||
}
|
||||
// Fill the ghosts
|
||||
fillHalo<BlobIDType> fillData2(comm,rank_info,{nx,ny,nz},{1,1,1},0,1,{true,true,true});
|
||||
fillHalo<BlobIDType> fillData2(comm, rank_info, {nx, ny, nz}, {1, 1, 1}, 0,
|
||||
1, {true, true, true});
|
||||
fillData2.fill(IDs);
|
||||
// Reorder based on size (and compress the id space
|
||||
int N_blobs_global = ReorderBlobIDs2(IDs, N_blobs_tot, ngx, ngy, ngz, comm);
|
||||
|
@ -430,38 +455,43 @@ static int LocalToGlobalIDs( int nx, int ny, int nz, const RankInfoStruct& rank_
|
|||
PROFILE_STOP("LocalToGlobalIDs", 1);
|
||||
return N_blobs_global;
|
||||
}
|
||||
int ComputeGlobalBlobIDs( int nx, int ny, int nz, const RankInfoStruct& rank_info,
|
||||
const DoubleArray& Phase, const DoubleArray& SignDist, double vF, double vS,
|
||||
BlobIDArray& GlobalBlobID, const Utilities::MPI& comm )
|
||||
{
|
||||
int ComputeGlobalBlobIDs(int nx, int ny, int nz,
|
||||
const RankInfoStruct &rank_info,
|
||||
const DoubleArray &Phase, const DoubleArray &SignDist,
|
||||
double vF, double vS, BlobIDArray &GlobalBlobID,
|
||||
const Utilities::MPI &comm) {
|
||||
PROFILE_START("ComputeGlobalBlobIDs");
|
||||
// First compute the local ids
|
||||
int nblobs = ComputeLocalBlobIDs(Phase,SignDist,vF,vS,GlobalBlobID,false);
|
||||
int nblobs =
|
||||
ComputeLocalBlobIDs(Phase, SignDist, vF, vS, GlobalBlobID, false);
|
||||
// Compute the global ids
|
||||
int nglobal = LocalToGlobalIDs( nx, ny, nz, rank_info, nblobs, GlobalBlobID, comm );
|
||||
int nglobal =
|
||||
LocalToGlobalIDs(nx, ny, nz, rank_info, nblobs, GlobalBlobID, comm);
|
||||
PROFILE_STOP("ComputeGlobalBlobIDs");
|
||||
return nglobal;
|
||||
}
|
||||
int ComputeGlobalPhaseComponent( int nx, int ny, int nz, const RankInfoStruct& rank_info,
|
||||
const IntArray &PhaseID, int &VALUE, BlobIDArray &GlobalBlobID, const Utilities::MPI& comm )
|
||||
{
|
||||
int ComputeGlobalPhaseComponent(int nx, int ny, int nz,
|
||||
const RankInfoStruct &rank_info,
|
||||
const IntArray &PhaseID, int &VALUE,
|
||||
BlobIDArray &GlobalBlobID,
|
||||
const Utilities::MPI &comm) {
|
||||
PROFILE_START("ComputeGlobalPhaseComponent");
|
||||
// First compute the local ids
|
||||
int nblobs = ComputeLocalPhaseComponent(PhaseID,VALUE,GlobalBlobID,false);
|
||||
int nblobs =
|
||||
ComputeLocalPhaseComponent(PhaseID, VALUE, GlobalBlobID, false);
|
||||
// Compute the global ids
|
||||
int nglobal = LocalToGlobalIDs( nx, ny, nz, rank_info, nblobs, GlobalBlobID, comm );
|
||||
int nglobal =
|
||||
LocalToGlobalIDs(nx, ny, nz, rank_info, nblobs, GlobalBlobID, comm);
|
||||
PROFILE_STOP("ComputeGlobalPhaseComponent");
|
||||
return nglobal;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* Compute the mapping of blob ids between timesteps *
|
||||
******************************************************************/
|
||||
typedef std::map<BlobIDType, std::map<BlobIDType, int64_t>> map_type;
|
||||
template <class TYPE>
|
||||
void gatherSet( std::set<TYPE>& set, const Utilities::MPI& comm )
|
||||
{
|
||||
void gatherSet(std::set<TYPE> &set, const Utilities::MPI &comm) {
|
||||
int nprocs = comm.getSize();
|
||||
std::vector<TYPE> send_data(set.begin(), set.end());
|
||||
int send_count = send_data.size();
|
||||
|
@ -475,8 +505,7 @@ void gatherSet( std::set<TYPE>& set, const Utilities::MPI& comm )
|
|||
for (size_t i = 0; i < recv_data.size(); i++)
|
||||
set.insert(recv_data[i]);
|
||||
}
|
||||
void gatherSrcIDMap( map_type& src_map, const Utilities::MPI& comm )
|
||||
{
|
||||
void gatherSrcIDMap(map_type &src_map, const Utilities::MPI &comm) {
|
||||
int nprocs = comm.getSize();
|
||||
std::vector<int64_t> send_data;
|
||||
for (auto it = src_map.begin(); it != src_map.end(); ++it) {
|
||||
|
@ -495,9 +524,10 @@ void gatherSrcIDMap( map_type& src_map, const Utilities::MPI& comm )
|
|||
comm.allGather(send_count, getPtr(recv_count));
|
||||
for (int i = 1; i < nprocs; i++)
|
||||
recv_disp[i] = recv_disp[i - 1] + recv_count[i - 1];
|
||||
std::vector<int64_t> recv_data(recv_disp[nprocs-1]+recv_count[nprocs-1]);
|
||||
comm.allGather(getPtr(send_data),send_count,
|
||||
getPtr(recv_data),getPtr(recv_count),getPtr(recv_disp),true);
|
||||
std::vector<int64_t> recv_data(recv_disp[nprocs - 1] +
|
||||
recv_count[nprocs - 1]);
|
||||
comm.allGather(getPtr(send_data), send_count, getPtr(recv_data),
|
||||
getPtr(recv_count), getPtr(recv_disp), true);
|
||||
size_t i = 0;
|
||||
src_map.clear();
|
||||
while (i < recv_data.size()) {
|
||||
|
@ -508,25 +538,25 @@ void gatherSrcIDMap( map_type& src_map, const Utilities::MPI& comm )
|
|||
for (size_t j = 0; j < count; j++, i += 2) {
|
||||
auto it = src_ids.find(recv_data[i]);
|
||||
if (it == src_ids.end())
|
||||
src_ids.insert(std::pair<BlobIDType,int64_t>(recv_data[i],recv_data[i+1]));
|
||||
src_ids.insert(std::pair<BlobIDType, int64_t>(
|
||||
recv_data[i], recv_data[i + 1]));
|
||||
else
|
||||
it->second += recv_data[i + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
void addSrcDstIDs(BlobIDType src_id, map_type &src_map, map_type &dst_map,
|
||||
std::set<BlobIDType>& src, std::set<BlobIDType>& dst )
|
||||
{
|
||||
std::set<BlobIDType> &src, std::set<BlobIDType> &dst) {
|
||||
src.insert(src_id);
|
||||
const std::map<BlobIDType, int64_t> &dst_ids = dst_map[src_id];
|
||||
for (std::map<BlobIDType,int64_t>::const_iterator it=dst_ids.begin(); it!=dst_ids.end(); ++it) {
|
||||
for (std::map<BlobIDType, int64_t>::const_iterator it = dst_ids.begin();
|
||||
it != dst_ids.end(); ++it) {
|
||||
if (dst.find(it->first) == dst.end())
|
||||
addSrcDstIDs(it->first, dst_map, src_map, dst, src);
|
||||
}
|
||||
}
|
||||
ID_map_struct computeIDMap( int nx, int ny, int nz,
|
||||
const BlobIDArray& ID1, const BlobIDArray& ID2, const Utilities::MPI& comm )
|
||||
{
|
||||
ID_map_struct computeIDMap(int nx, int ny, int nz, const BlobIDArray &ID1,
|
||||
const BlobIDArray &ID2, const Utilities::MPI &comm) {
|
||||
ASSERT(ID1.size() == ID2.size());
|
||||
PROFILE_START("computeIDMap");
|
||||
const int ngx = (ID1.size(0) - nx) / 2;
|
||||
|
@ -547,7 +577,8 @@ ID_map_struct computeIDMap( int nx, int ny, int nz,
|
|||
dst_set.insert(id2);
|
||||
if (id1 >= 0 && id2 >= 0) {
|
||||
std::map<BlobIDType, int64_t> &src_ids = src_map[id2];
|
||||
std::map<BlobIDType,int64_t>::iterator it = src_ids.find(id1);
|
||||
std::map<BlobIDType, int64_t>::iterator it =
|
||||
src_ids.find(id1);
|
||||
if (it == src_ids.end()) {
|
||||
src_ids.insert(std::pair<BlobIDType, int64_t>(id1, 0));
|
||||
it = src_ids.find(id1);
|
||||
|
@ -563,10 +594,13 @@ ID_map_struct computeIDMap( int nx, int ny, int nz,
|
|||
gatherSrcIDMap(src_map, comm);
|
||||
// Compute the dst id map
|
||||
map_type dst_map; // Map of the dst ids for each src id
|
||||
for (map_type::const_iterator it=src_map.begin(); it!=src_map.end(); ++it) {
|
||||
for (map_type::const_iterator it = src_map.begin(); it != src_map.end();
|
||||
++it) {
|
||||
BlobIDType id = it->first;
|
||||
const std::map<BlobIDType, int64_t> &src_ids = it->second;
|
||||
for (std::map<BlobIDType,int64_t>::const_iterator it2=src_ids.begin(); it2!=src_ids.end(); ++it2) {
|
||||
for (std::map<BlobIDType, int64_t>::const_iterator it2 =
|
||||
src_ids.begin();
|
||||
it2 != src_ids.end(); ++it2) {
|
||||
std::map<BlobIDType, int64_t> &dst_ids = dst_map[it2->first];
|
||||
dst_ids.insert(std::pair<BlobIDType, int64_t>(id, it2->second));
|
||||
}
|
||||
|
@ -575,19 +609,22 @@ ID_map_struct computeIDMap( int nx, int ny, int nz,
|
|||
// Perform the mapping of ids
|
||||
ID_map_struct id_map;
|
||||
// Find new blobs
|
||||
for (std::set<BlobIDType>::const_iterator it=dst_set.begin(); it!=dst_set.end(); ++it) {
|
||||
for (std::set<BlobIDType>::const_iterator it = dst_set.begin();
|
||||
it != dst_set.end(); ++it) {
|
||||
if (src_map.find(*it) == src_map.end())
|
||||
id_map.created.push_back(*it);
|
||||
}
|
||||
// Fine blobs that disappeared
|
||||
for (std::set<BlobIDType>::const_iterator it=src_set.begin(); it!=src_set.end(); ++it) {
|
||||
for (std::set<BlobIDType>::const_iterator it = src_set.begin();
|
||||
it != src_set.end(); ++it) {
|
||||
if (dst_map.find(*it) == dst_map.end())
|
||||
id_map.destroyed.push_back(*it);
|
||||
}
|
||||
// Find blobs with a 1-to-1 mapping
|
||||
std::vector<BlobIDType> dst_list;
|
||||
dst_list.reserve(src_map.size());
|
||||
for (map_type::const_iterator it=src_map.begin(); it!=src_map.end(); ++it)
|
||||
for (map_type::const_iterator it = src_map.begin(); it != src_map.end();
|
||||
++it)
|
||||
dst_list.push_back(it->first);
|
||||
for (size_t i = 0; i < dst_list.size(); i++) {
|
||||
int dst_id = dst_list[i];
|
||||
|
@ -599,7 +636,8 @@ ID_map_struct computeIDMap( int nx, int ny, int nz,
|
|||
ASSERT(dst_ids.begin()->first == dst_id);
|
||||
src_map.erase(dst_id);
|
||||
dst_map.erase(src_id);
|
||||
id_map.src_dst.push_back(std::pair<BlobIDType,BlobIDType>(src_id,dst_id));
|
||||
id_map.src_dst.push_back(
|
||||
std::pair<BlobIDType, BlobIDType>(src_id, dst_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -610,30 +648,41 @@ ID_map_struct computeIDMap( int nx, int ny, int nz,
|
|||
addSrcDstIDs(dst_map.begin()->first, src_map, dst_map, src, dst);
|
||||
if (src.size() == 1) {
|
||||
// Bubble split
|
||||
id_map.split.push_back( BlobIDSplitStruct(*src.begin(),std::vector<BlobIDType>(dst.begin(),dst.end())) );
|
||||
id_map.split.push_back(BlobIDSplitStruct(
|
||||
*src.begin(), std::vector<BlobIDType>(dst.begin(), dst.end())));
|
||||
} else if (dst.size() == 1) {
|
||||
// Bubble merge
|
||||
id_map.merge.push_back( BlobIDMergeStruct(std::vector<BlobIDType>(src.begin(),src.end()),*dst.begin()) );
|
||||
id_map.merge.push_back(BlobIDMergeStruct(
|
||||
std::vector<BlobIDType>(src.begin(), src.end()), *dst.begin()));
|
||||
} else {
|
||||
// Bubble split/merge
|
||||
id_map.merge_split.push_back(BlobIDMergeSplitStruct(
|
||||
std::vector<BlobIDType>(src.begin(),src.end()), std::vector<BlobIDType>(dst.begin(),dst.end() ) ) );
|
||||
std::vector<BlobIDType>(src.begin(), src.end()),
|
||||
std::vector<BlobIDType>(dst.begin(), dst.end())));
|
||||
}
|
||||
// Add the overlaps
|
||||
for (std::set<BlobIDType>::const_iterator it1=src.begin(); it1!=src.end(); ++it1) {
|
||||
for (std::set<BlobIDType>::const_iterator it1 = src.begin();
|
||||
it1 != src.end(); ++it1) {
|
||||
const std::map<BlobIDType, int64_t> &dst_ids = dst_map[*it1];
|
||||
for (std::set<BlobIDType>::const_iterator it2=dst.begin(); it2!=dst.end(); ++it2) {
|
||||
for (std::set<BlobIDType>::const_iterator it2 = dst.begin();
|
||||
it2 != dst.end(); ++it2) {
|
||||
std::pair<BlobIDType, BlobIDType> id(*it1, *it2);
|
||||
int64_t overlap = 0;
|
||||
const std::map<BlobIDType,int64_t>::const_iterator it = dst_ids.find(*it2);
|
||||
if ( it != dst_ids.end() ) { overlap = it->second; }
|
||||
id_map.overlap.insert(std::pair<OverlapID,int64_t>(id,overlap));
|
||||
const std::map<BlobIDType, int64_t>::const_iterator it =
|
||||
dst_ids.find(*it2);
|
||||
if (it != dst_ids.end()) {
|
||||
overlap = it->second;
|
||||
}
|
||||
id_map.overlap.insert(
|
||||
std::pair<OverlapID, int64_t>(id, overlap));
|
||||
}
|
||||
}
|
||||
// Clear the mapped entries
|
||||
for (std::set<BlobIDType>::const_iterator it=src.begin(); it!=src.end(); ++it)
|
||||
for (std::set<BlobIDType>::const_iterator it = src.begin();
|
||||
it != src.end(); ++it)
|
||||
dst_map.erase(*it);
|
||||
for (std::set<BlobIDType>::const_iterator it=dst.begin(); it!=dst.end(); ++it)
|
||||
for (std::set<BlobIDType>::const_iterator it = dst.begin();
|
||||
it != dst.end(); ++it)
|
||||
src_map.erase(*it);
|
||||
}
|
||||
ASSERT(src_map.empty());
|
||||
|
@ -642,14 +691,14 @@ ID_map_struct computeIDMap( int nx, int ny, int nz,
|
|||
return id_map;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* Renumber the ids *
|
||||
******************************************************************/
|
||||
typedef std::vector<BlobIDType> IDvec;
|
||||
inline void renumber( const std::vector<BlobIDType>& id1, const std::vector<BlobIDType>& id2,
|
||||
const std::map<OverlapID,int64_t>& overlap, std::vector<BlobIDType>& new_ids, BlobIDType& id_max )
|
||||
{
|
||||
inline void renumber(const std::vector<BlobIDType> &id1,
|
||||
const std::vector<BlobIDType> &id2,
|
||||
const std::map<OverlapID, int64_t> &overlap,
|
||||
std::vector<BlobIDType> &new_ids, BlobIDType &id_max) {
|
||||
if (id2.empty()) {
|
||||
// No dst ids to set
|
||||
} else if (id1.empty()) {
|
||||
|
@ -671,7 +720,10 @@ inline void renumber( const std::vector<BlobIDType>& id1, const std::vector<Blob
|
|||
Array<int64_t> cost(id1.size(), id2.size());
|
||||
for (size_t j = 0; j < id2.size(); j++) {
|
||||
for (size_t i = 0; i < id1.size(); i++) {
|
||||
cost(i,j) = overlap.find(std::pair<BlobIDType,BlobIDType>(id1[i],id2[j]))->second;
|
||||
cost(i, j) =
|
||||
overlap
|
||||
.find(std::pair<BlobIDType, BlobIDType>(id1[i], id2[j]))
|
||||
->second;
|
||||
}
|
||||
}
|
||||
// While we have not mapped all dst ids
|
||||
|
@ -708,31 +760,37 @@ inline void renumber( const std::vector<BlobIDType>& id1, const std::vector<Blob
|
|||
}
|
||||
}
|
||||
}
|
||||
inline void renumberIDs( const std::vector<BlobIDType>& new_ids, BlobIDType& id )
|
||||
{
|
||||
inline void renumberIDs(const std::vector<BlobIDType> &new_ids,
|
||||
BlobIDType &id) {
|
||||
id = new_ids[id];
|
||||
}
|
||||
inline void renumberIDs( const std::vector<BlobIDType>& new_ids, std::vector<BlobIDType>& ids )
|
||||
{
|
||||
inline void renumberIDs(const std::vector<BlobIDType> &new_ids,
|
||||
std::vector<BlobIDType> &ids) {
|
||||
for (size_t i = 0; i < ids.size(); i++)
|
||||
ids[i] = new_ids[ids[i]];
|
||||
}
|
||||
void getNewIDs( ID_map_struct& map, BlobIDType& id_max, std::vector<BlobIDType>& new_ids )
|
||||
{
|
||||
void getNewIDs(ID_map_struct &map, BlobIDType &id_max,
|
||||
std::vector<BlobIDType> &new_ids) {
|
||||
new_ids.resize(0);
|
||||
// Get the new id numbers for each map type
|
||||
for (size_t i = 0; i < map.src_dst.size(); i++)
|
||||
renumber(IDvec(1,map.src_dst[i].first),IDvec(1,map.src_dst[i].second),map.overlap,new_ids,id_max);
|
||||
renumber(IDvec(1, map.src_dst[i].first),
|
||||
IDvec(1, map.src_dst[i].second), map.overlap, new_ids, id_max);
|
||||
for (size_t i = 0; i < map.created.size(); i++)
|
||||
renumber(std::vector<BlobIDType>(),IDvec(1,map.created[i]),map.overlap,new_ids,id_max);
|
||||
renumber(std::vector<BlobIDType>(), IDvec(1, map.created[i]),
|
||||
map.overlap, new_ids, id_max);
|
||||
for (size_t i = 0; i < map.destroyed.size(); i++)
|
||||
renumber(IDvec(1,map.destroyed[i]),std::vector<BlobIDType>(),map.overlap,new_ids,id_max);
|
||||
renumber(IDvec(1, map.destroyed[i]), std::vector<BlobIDType>(),
|
||||
map.overlap, new_ids, id_max);
|
||||
for (size_t i = 0; i < map.split.size(); i++)
|
||||
renumber(IDvec(1,map.split[i].first),map.split[i].second,map.overlap,new_ids,id_max);
|
||||
renumber(IDvec(1, map.split[i].first), map.split[i].second, map.overlap,
|
||||
new_ids, id_max);
|
||||
for (size_t i = 0; i < map.merge.size(); i++)
|
||||
renumber(map.merge[i].first,IDvec(1,map.merge[i].second),map.overlap,new_ids,id_max);
|
||||
renumber(map.merge[i].first, IDvec(1, map.merge[i].second), map.overlap,
|
||||
new_ids, id_max);
|
||||
for (size_t i = 0; i < map.merge_split.size(); i++)
|
||||
renumber(map.merge_split[i].first,map.merge_split[i].second,map.overlap,new_ids,id_max);
|
||||
renumber(map.merge_split[i].first, map.merge_split[i].second,
|
||||
map.overlap, new_ids, id_max);
|
||||
// Renumber the ids in the map
|
||||
for (size_t i = 0; i < map.src_dst.size(); i++)
|
||||
renumberIDs(new_ids, map.src_dst[i].second);
|
||||
|
@ -744,14 +802,14 @@ void getNewIDs( ID_map_struct& map, BlobIDType& id_max, std::vector<BlobIDType>&
|
|||
for (size_t i = 0; i < map.merge_split.size(); i++)
|
||||
renumberIDs(new_ids, map.merge_split[i].second);
|
||||
std::map<OverlapID, int64_t> overlap2;
|
||||
for (std::map<OverlapID,int64_t>::const_iterator it=map.overlap.begin(); it!=map.overlap.begin(); ++it) {
|
||||
for (std::map<OverlapID, int64_t>::const_iterator it = map.overlap.begin();
|
||||
it != map.overlap.begin(); ++it) {
|
||||
OverlapID id = it->first;
|
||||
renumberIDs(new_ids, id.second);
|
||||
overlap2.insert(std::pair<OverlapID, int64_t>(id, it->second));
|
||||
}
|
||||
}
|
||||
void renumberIDs( const std::vector<BlobIDType>& new_ids, BlobIDArray& IDs )
|
||||
{
|
||||
void renumberIDs(const std::vector<BlobIDType> &new_ids, BlobIDArray &IDs) {
|
||||
size_t N = IDs.length();
|
||||
BlobIDType *ids = IDs.data();
|
||||
for (size_t i = 0; i < N; i++) {
|
||||
|
@ -761,17 +819,17 @@ void renumberIDs( const std::vector<BlobIDType>& new_ids, BlobIDArray& IDs )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* Write the id map for the given timestep *
|
||||
******************************************************************/
|
||||
void writeIDMap( const ID_map_struct& map, long long int timestep, const std::string& filename )
|
||||
{
|
||||
void writeIDMap(const ID_map_struct &map, long long int timestep,
|
||||
const std::string &filename) {
|
||||
int rank = Utilities::MPI(MPI_COMM_WORLD).getRank();
|
||||
if (rank != 0)
|
||||
return;
|
||||
bool empty = map.created.empty() && map.destroyed.empty() &&
|
||||
map.split.empty() && map.merge.empty() && map.merge_split.empty();
|
||||
map.split.empty() && map.merge.empty() &&
|
||||
map.merge_split.empty();
|
||||
for (size_t i = 0; i < map.src_dst.size(); i++)
|
||||
empty = empty && map.src_dst[i].first == map.src_dst[i].second;
|
||||
if (timestep != 0 && empty)
|
||||
|
@ -793,30 +851,38 @@ void writeIDMap( const ID_map_struct& map, long long int timestep, const std::st
|
|||
fprintf(fid, " %lli-", static_cast<long long int>(map.destroyed[i]));
|
||||
for (size_t i = 0; i < map.src_dst.size(); i++) {
|
||||
if (map.src_dst[i].first != map.src_dst[i].second)
|
||||
fprintf(fid," %lli-%lli",static_cast<long long int>(map.src_dst[i].first),
|
||||
fprintf(fid, " %lli-%lli",
|
||||
static_cast<long long int>(map.src_dst[i].first),
|
||||
static_cast<long long int>(map.src_dst[i].second));
|
||||
}
|
||||
for (size_t i = 0; i < map.split.size(); i++) {
|
||||
fprintf(fid," %lli-%lli",static_cast<long long int>(map.split[i].first),
|
||||
fprintf(fid, " %lli-%lli",
|
||||
static_cast<long long int>(map.split[i].first),
|
||||
static_cast<long long int>(map.split[i].second[0]));
|
||||
for (size_t j = 1; j < map.split[i].second.size(); j++)
|
||||
fprintf(fid,"/%lli",static_cast<long long int>(map.split[i].second[j]));
|
||||
fprintf(fid, "/%lli",
|
||||
static_cast<long long int>(map.split[i].second[j]));
|
||||
}
|
||||
for (size_t i = 0; i < map.merge.size(); i++) {
|
||||
fprintf(fid," %lli",static_cast<long long int>(map.merge[i].first[0]));
|
||||
fprintf(fid, " %lli",
|
||||
static_cast<long long int>(map.merge[i].first[0]));
|
||||
for (size_t j = 1; j < map.merge[i].first.size(); j++)
|
||||
fprintf(fid,"/%lli",static_cast<long long int>(map.merge[i].first[j]));
|
||||
fprintf(fid, "/%lli",
|
||||
static_cast<long long int>(map.merge[i].first[j]));
|
||||
fprintf(fid, "-%lli", static_cast<long long int>(map.merge[i].second));
|
||||
}
|
||||
for (size_t i = 0; i < map.merge_split.size(); i++) {
|
||||
fprintf(fid," %lli",static_cast<long long int>(map.merge_split[i].first[0]));
|
||||
fprintf(fid, " %lli",
|
||||
static_cast<long long int>(map.merge_split[i].first[0]));
|
||||
for (size_t j = 1; j < map.merge_split[i].first.size(); j++)
|
||||
fprintf(fid,"/%lli",static_cast<long long int>(map.merge_split[i].first[j]));
|
||||
fprintf(fid,"-%lli",static_cast<long long int>(map.merge_split[i].second[0]));
|
||||
fprintf(fid, "/%lli",
|
||||
static_cast<long long int>(map.merge_split[i].first[j]));
|
||||
fprintf(fid, "-%lli",
|
||||
static_cast<long long int>(map.merge_split[i].second[0]));
|
||||
for (size_t j = 1; j < map.merge_split[i].second.size(); j++)
|
||||
fprintf(fid,"/%lli",static_cast<long long int>(map.merge_split[i].second[j]));
|
||||
fprintf(fid, "/%lli",
|
||||
static_cast<long long int>(map.merge_split[i].second[j]));
|
||||
}
|
||||
fprintf(fid, "\n");
|
||||
fclose(fid);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef Analysis_H_INC
|
||||
#define Analysis_H_INC
|
||||
|
||||
|
@ -8,12 +24,10 @@
|
|||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
|
||||
// Define types to use for blob ids
|
||||
typedef int32_t BlobIDType;
|
||||
typedef Array<BlobIDType> BlobIDArray;
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Compute the blob
|
||||
* @details Compute the blob (F>vf|S>vs) starting from (i,j,k) - oil blob
|
||||
|
@ -27,7 +41,8 @@ typedef Array<BlobIDType> BlobIDArray;
|
|||
* @return Returns the number of blobs
|
||||
*/
|
||||
int ComputeLocalBlobIDs(const DoubleArray &Phase, const DoubleArray &SignDist,
|
||||
double vF, double vS, BlobIDArray& LocalBlobID, bool periodic=true );
|
||||
double vF, double vS, BlobIDArray &LocalBlobID,
|
||||
bool periodic = true);
|
||||
|
||||
/*!
|
||||
* @brief Compute blob of an arbitrary phase
|
||||
|
@ -38,8 +53,8 @@ int ComputeLocalBlobIDs( const DoubleArray& Phase, const DoubleArray& SignDist,
|
|||
* @param[out] ComponentLabel
|
||||
* @param[in] periodic
|
||||
*/
|
||||
int ComputeLocalPhaseComponent( const IntArray &PhaseID, int &VALUE, IntArray &ComponentLabel, bool periodic );
|
||||
|
||||
int ComputeLocalPhaseComponent(const IntArray &PhaseID, int &VALUE,
|
||||
IntArray &ComponentLabel, bool periodic);
|
||||
|
||||
/*!
|
||||
* @brief Compute the blob
|
||||
|
@ -57,10 +72,11 @@ int ComputeLocalPhaseComponent( const IntArray &PhaseID, int &VALUE, IntArray &C
|
|||
* @param[in] comm MPI communicator
|
||||
* @return Returns the number of blobs
|
||||
*/
|
||||
int ComputeGlobalBlobIDs( int nx, int ny, int nz, const RankInfoStruct& rank_info,
|
||||
const DoubleArray& Phase, const DoubleArray& SignDist, double vF, double vS,
|
||||
BlobIDArray& GlobalBlobID, const Utilities::MPI& comm );
|
||||
|
||||
int ComputeGlobalBlobIDs(int nx, int ny, int nz,
|
||||
const RankInfoStruct &rank_info,
|
||||
const DoubleArray &Phase, const DoubleArray &SignDist,
|
||||
double vF, double vS, BlobIDArray &GlobalBlobID,
|
||||
const Utilities::MPI &comm);
|
||||
|
||||
/*!
|
||||
* @brief Compute component of the specified phase
|
||||
|
@ -76,9 +92,11 @@ int ComputeGlobalBlobIDs( int nx, int ny, int nz, const RankInfoStruct& rank_inf
|
|||
* @param[in] comm The communicator to use
|
||||
* @return Return the number of components in the specified phase
|
||||
*/
|
||||
int ComputeGlobalPhaseComponent( int nx, int ny, int nz, const RankInfoStruct& rank_info,
|
||||
const IntArray &PhaseID, int &VALUE, BlobIDArray &GlobalBlobID, const Utilities::MPI& comm );
|
||||
|
||||
int ComputeGlobalPhaseComponent(int nx, int ny, int nz,
|
||||
const RankInfoStruct &rank_info,
|
||||
const IntArray &PhaseID, int &VALUE,
|
||||
BlobIDArray &GlobalBlobID,
|
||||
const Utilities::MPI &comm);
|
||||
|
||||
/*!
|
||||
* @brief Reorder the blobs
|
||||
|
@ -89,29 +107,33 @@ int ComputeGlobalPhaseComponent( int nx, int ny, int nz, const RankInfoStruct& r
|
|||
*/
|
||||
void ReorderBlobIDs(BlobIDArray &ID, const Utilities::MPI &comm);
|
||||
|
||||
|
||||
typedef std::pair<BlobIDType, std::vector<BlobIDType>> BlobIDSplitStruct;
|
||||
typedef std::pair<std::vector<BlobIDType>, BlobIDType> BlobIDMergeStruct;
|
||||
typedef std::pair<std::vector<BlobIDType>,std::vector<BlobIDType> > BlobIDMergeSplitStruct;
|
||||
typedef std::pair<std::vector<BlobIDType>, std::vector<BlobIDType>>
|
||||
BlobIDMergeSplitStruct;
|
||||
typedef std::pair<BlobIDType, BlobIDType> OverlapID;
|
||||
struct ID_map_struct {
|
||||
std::vector<BlobIDType> created; // list of new blobs that were created
|
||||
std::vector<BlobIDType> destroyed; // list of blobs that disappeared
|
||||
std::vector<std::pair<BlobIDType,BlobIDType> > src_dst; // one-one mapping of blobs (first,second timestep id)
|
||||
std::vector<std::pair<BlobIDType, BlobIDType>>
|
||||
src_dst; // one-one mapping of blobs (first,second timestep id)
|
||||
std::vector<BlobIDSplitStruct> split; // list of blobs that split
|
||||
std::vector<BlobIDMergeStruct> merge; // list of blobs that merged
|
||||
std::vector<BlobIDMergeSplitStruct> merge_split; // list of blobs that both merged and split
|
||||
std::map<OverlapID,int64_t> overlap; // for ids that are not a 1-1 mapping, this is a list of the overlaps <src,dst>
|
||||
std::vector<BlobIDMergeSplitStruct>
|
||||
merge_split; // list of blobs that both merged and split
|
||||
std::map<OverlapID, int64_t>
|
||||
overlap; // for ids that are not a 1-1 mapping, this is a list of the overlaps <src,dst>
|
||||
//! Empty constructor
|
||||
ID_map_struct() {}
|
||||
//! Create initial map from N blobs (ordered 1:N-1)
|
||||
ID_map_struct(int N) {
|
||||
created.resize(N);
|
||||
for (int i=0; i<N; i++) { created[i]=i; }
|
||||
for (int i = 0; i < N; i++) {
|
||||
created[i] = i;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Get the mapping of blob ids between iterations
|
||||
* @details This functions computes the map of blob ids between iterations
|
||||
|
@ -124,8 +146,8 @@ struct ID_map_struct {
|
|||
* @param[in] ID2 The blob ids at the second timestep
|
||||
* @param[in] comm The communicator to use
|
||||
*/
|
||||
ID_map_struct computeIDMap( int nx, int ny, int nz, const BlobIDArray& ID1, const BlobIDArray& ID2, const Utilities::MPI& comm );
|
||||
|
||||
ID_map_struct computeIDMap(int nx, int ny, int nz, const BlobIDArray &ID1,
|
||||
const BlobIDArray &ID2, const Utilities::MPI &comm);
|
||||
|
||||
/*!
|
||||
* @brief Compute the new global ids based on the map
|
||||
|
@ -135,8 +157,8 @@ ID_map_struct computeIDMap( int nx, int ny, int nz, const BlobIDArray& ID1, cons
|
|||
* @param[in] id_max The globally largest id used previously
|
||||
* @param[out] new_ids The newly renumbered blob ids (0:ids.max())
|
||||
*/
|
||||
void getNewIDs( ID_map_struct& map, BlobIDType& id_max, std::vector<BlobIDType>& new_ids );
|
||||
|
||||
void getNewIDs(ID_map_struct &map, BlobIDType &id_max,
|
||||
std::vector<BlobIDType> &new_ids);
|
||||
|
||||
/*!
|
||||
* @brief Update the blob ids based on mapping
|
||||
|
@ -147,7 +169,6 @@ void getNewIDs( ID_map_struct& map, BlobIDType& id_max, std::vector<BlobIDType>&
|
|||
*/
|
||||
void renumberIDs(const std::vector<BlobIDType> &new_ids, BlobIDArray &IDs);
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Write the ID map
|
||||
* @details This functions writes the id map fo an iteration.
|
||||
|
@ -157,8 +178,7 @@ void renumberIDs( const std::vector<BlobIDType>& new_ids, BlobIDArray& IDs );
|
|||
* @param[in] timestep The current timestep (timestep 0 creates the file)
|
||||
* @param[in] filename The filename to write/append
|
||||
*/
|
||||
void writeIDMap( const ID_map_struct& map, long long int timestep, const std::string& filename );
|
||||
|
||||
|
||||
void writeIDMap(const ID_map_struct &map, long long int timestep,
|
||||
const std::string &filename);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
#include "analysis/dcel.h"
|
||||
|
||||
DCEL::DCEL(){
|
||||
}
|
||||
DCEL::DCEL() {}
|
||||
|
||||
DCEL::~DCEL() {
|
||||
TriangleCount = 0;
|
||||
VertexCount = 0;
|
||||
|
||||
}
|
||||
|
||||
int DCEL::Face(int index){
|
||||
return FaceData[index];
|
||||
}
|
||||
int DCEL::Face(int index) { return FaceData[index]; }
|
||||
|
||||
void DCEL::Write() {
|
||||
int e1, e2, e3;
|
||||
|
@ -32,7 +28,8 @@ void DCEL::Write(){
|
|||
fclose(TRIANGLES);
|
||||
}
|
||||
|
||||
void DCEL::LocalIsosurface(const DoubleArray& A, double value, const int i, const int j, const int k){
|
||||
void DCEL::LocalIsosurface(const DoubleArray &A, double value, const int i,
|
||||
const int j, const int k) {
|
||||
Point P, Q;
|
||||
Point PlaceHolder;
|
||||
Point C0, C1, C2, C3, C4, C5, C6, C7;
|
||||
|
@ -48,14 +45,30 @@ void DCEL::LocalIsosurface(const DoubleArray& A, double value, const int i, cons
|
|||
double CubeValues[8];
|
||||
|
||||
// Points corresponding to cube corners
|
||||
C0.x = 0.0; C0.y = 0.0; C0.z = 0.0;
|
||||
C1.x = 1.0; C1.y = 0.0; C1.z = 0.0;
|
||||
C2.x = 1.0; C2.y = 1.0; C2.z = 0.0;
|
||||
C3.x = 0.0; C3.y = 1.0; C3.z = 0.0;
|
||||
C4.x = 0.0; C4.y = 0.0; C4.z = 1.0;
|
||||
C5.x = 1.0; C5.y = 0.0; C5.z = 1.0;
|
||||
C6.x = 1.0; C6.y = 1.0; C6.z = 1.0;
|
||||
C7.x = 0.0; C7.y = 1.0; C7.z = 1.0;
|
||||
C0.x = 0.0;
|
||||
C0.y = 0.0;
|
||||
C0.z = 0.0;
|
||||
C1.x = 1.0;
|
||||
C1.y = 0.0;
|
||||
C1.z = 0.0;
|
||||
C2.x = 1.0;
|
||||
C2.y = 1.0;
|
||||
C2.z = 0.0;
|
||||
C3.x = 0.0;
|
||||
C3.y = 1.0;
|
||||
C3.z = 0.0;
|
||||
C4.x = 0.0;
|
||||
C4.y = 0.0;
|
||||
C4.z = 1.0;
|
||||
C5.x = 1.0;
|
||||
C5.y = 0.0;
|
||||
C5.z = 1.0;
|
||||
C6.x = 1.0;
|
||||
C6.y = 1.0;
|
||||
C6.z = 1.0;
|
||||
C7.x = 0.0;
|
||||
C7.y = 1.0;
|
||||
C7.z = 1.0;
|
||||
|
||||
CubeValues[0] = A(i, j, k) - value;
|
||||
CubeValues[1] = A(i + 1, j, k) - value;
|
||||
|
@ -70,14 +83,22 @@ void DCEL::LocalIsosurface(const DoubleArray& A, double value, const int i, cons
|
|||
//Determine the index into the edge table which
|
||||
//tells us which vertices are inside of the surface
|
||||
int CubeIndex = 0;
|
||||
if (CubeValues[0] < 0.0f) CubeIndex |= 1;
|
||||
if (CubeValues[1] < 0.0f) CubeIndex |= 2;
|
||||
if (CubeValues[2] < 0.0f) CubeIndex |= 4;
|
||||
if (CubeValues[3] < 0.0f) CubeIndex |= 8;
|
||||
if (CubeValues[4] < 0.0f) CubeIndex |= 16;
|
||||
if (CubeValues[5] < 0.0f) CubeIndex |= 32;
|
||||
if (CubeValues[6] < 0.0f) CubeIndex |= 64;
|
||||
if (CubeValues[7] < 0.0f) CubeIndex |= 128;
|
||||
if (CubeValues[0] < 0.0f)
|
||||
CubeIndex |= 1;
|
||||
if (CubeValues[1] < 0.0f)
|
||||
CubeIndex |= 2;
|
||||
if (CubeValues[2] < 0.0f)
|
||||
CubeIndex |= 4;
|
||||
if (CubeValues[3] < 0.0f)
|
||||
CubeIndex |= 8;
|
||||
if (CubeValues[4] < 0.0f)
|
||||
CubeIndex |= 16;
|
||||
if (CubeValues[5] < 0.0f)
|
||||
CubeIndex |= 32;
|
||||
if (CubeValues[6] < 0.0f)
|
||||
CubeIndex |= 64;
|
||||
if (CubeValues[7] < 0.0f)
|
||||
CubeIndex |= 128;
|
||||
|
||||
//Find the vertices where the surface intersects the cube
|
||||
if (edgeTable[CubeIndex] & 1) {
|
||||
|
@ -145,10 +166,8 @@ void DCEL::LocalIsosurface(const DoubleArray& A, double value, const int i, cons
|
|||
for (int idx = 0; idx < 12; idx++)
|
||||
LocalRemap[idx] = -1;
|
||||
|
||||
for (int idx=0;triTable[CubeIndex][idx]!=-1;idx++)
|
||||
{
|
||||
if(LocalRemap[triTable[CubeIndex][idx]] == -1)
|
||||
{
|
||||
for (int idx = 0; triTable[CubeIndex][idx] != -1; idx++) {
|
||||
if (LocalRemap[triTable[CubeIndex][idx]] == -1) {
|
||||
NewVertexList[VertexCount] = VertexList[triTable[CubeIndex][idx]];
|
||||
LocalRemap[triTable[CubeIndex][idx]] = VertexCount;
|
||||
VertexCount++;
|
||||
|
@ -219,24 +238,33 @@ void DCEL::LocalIsosurface(const DoubleArray& A, double value, const int i, cons
|
|||
int V2 = halfedge.data(1, idx);
|
||||
// Find all the twins within the cube
|
||||
for (int jdx = 0; jdx < EdgeCount; jdx++) {
|
||||
if (halfedge.data(1,jdx) == V1 && halfedge.data(0,jdx) == V2){
|
||||
if (halfedge.data(1, jdx) == V1 &&
|
||||
halfedge.data(0, jdx) == V2) {
|
||||
// this is the pair
|
||||
halfedge.data(3, idx) = jdx;
|
||||
halfedge.data(3, jdx) = idx;
|
||||
}
|
||||
if (halfedge.data(1,jdx) == V2 && halfedge.data(0,jdx) == V1 && !(idx==jdx)){
|
||||
std::printf("WARNING: half edges with identical orientation! \n");
|
||||
if (halfedge.data(1, jdx) == V2 &&
|
||||
halfedge.data(0, jdx) == V1 && !(idx == jdx)) {
|
||||
std::printf(
|
||||
"WARNING: half edges with identical orientation! \n");
|
||||
}
|
||||
}
|
||||
// Use "ghost" twins if edge is on a cube face
|
||||
P = cellvertices[V1];
|
||||
Q = cellvertices[V2];
|
||||
if (P.x == 0.0 && Q.x == 0.0) halfedge.data(3,idx) = -1; // ghost twin for x=0 face
|
||||
if (P.x == 1.0 && Q.x == 1.0) halfedge.data(3,idx) = -4; // ghost twin for x=1 face
|
||||
if (P.y == 0.0 && Q.y == 0.0) halfedge.data(3,idx) = -2; // ghost twin for y=0 face
|
||||
if (P.y == 1.0 && Q.y == 1.0) halfedge.data(3,idx) = -5; // ghost twin for y=1 face
|
||||
if (P.z == 0.0 && Q.z == 0.0) halfedge.data(3,idx) = -3; // ghost twin for z=0 face
|
||||
if (P.z == 1.0 && Q.z == 1.0) halfedge.data(3,idx) = -6; // ghost twin for z=1 face
|
||||
if (P.x == 0.0 && Q.x == 0.0)
|
||||
halfedge.data(3, idx) = -1; // ghost twin for x=0 face
|
||||
if (P.x == 1.0 && Q.x == 1.0)
|
||||
halfedge.data(3, idx) = -4; // ghost twin for x=1 face
|
||||
if (P.y == 0.0 && Q.y == 0.0)
|
||||
halfedge.data(3, idx) = -2; // ghost twin for y=0 face
|
||||
if (P.y == 1.0 && Q.y == 1.0)
|
||||
halfedge.data(3, idx) = -5; // ghost twin for y=1 face
|
||||
if (P.z == 0.0 && Q.z == 0.0)
|
||||
halfedge.data(3, idx) = -3; // ghost twin for z=0 face
|
||||
if (P.z == 1.0 && Q.z == 1.0)
|
||||
halfedge.data(3, idx) = -6; // ghost twin for z=1 face
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,31 +278,36 @@ void DCEL::LocalIsosurface(const DoubleArray& A, double value, const int i, cons
|
|||
}
|
||||
}
|
||||
|
||||
Point DCEL::TriNormal(int edge)
|
||||
{
|
||||
Point DCEL::TriNormal(int edge) {
|
||||
Point P, Q, R;
|
||||
Point U, V, W;
|
||||
double nx, ny, nz, len;
|
||||
// at cube faces define outward normal to cube
|
||||
if (edge == -1) {
|
||||
W.x = -1.0; W.y = 0.0; W.z = 0.0; // x cube face
|
||||
}
|
||||
else if (edge == -2){
|
||||
W.x = 0.0; W.y = -1.0; W.z = 0.0; // y cube face
|
||||
}
|
||||
else if (edge == -3){
|
||||
W.x = 0.0; W.y = 0.0; W.z = -1.0; // z cube face
|
||||
}
|
||||
else if (edge == -4){
|
||||
W.x = 1.0; W.y = 0.0; W.z = 0.0; // x cube face
|
||||
}
|
||||
else if (edge == -5){
|
||||
W.x = 0.0; W.y = 1.0; W.z = 0.0; // y cube face
|
||||
}
|
||||
else if (edge == -6){
|
||||
W.x = 0.0; W.y = 0.0; W.z = 1.0; // z cube face
|
||||
}
|
||||
else{
|
||||
W.x = -1.0;
|
||||
W.y = 0.0;
|
||||
W.z = 0.0; // x cube face
|
||||
} else if (edge == -2) {
|
||||
W.x = 0.0;
|
||||
W.y = -1.0;
|
||||
W.z = 0.0; // y cube face
|
||||
} else if (edge == -3) {
|
||||
W.x = 0.0;
|
||||
W.y = 0.0;
|
||||
W.z = -1.0; // z cube face
|
||||
} else if (edge == -4) {
|
||||
W.x = 1.0;
|
||||
W.y = 0.0;
|
||||
W.z = 0.0; // x cube face
|
||||
} else if (edge == -5) {
|
||||
W.x = 0.0;
|
||||
W.y = 1.0;
|
||||
W.z = 0.0; // y cube face
|
||||
} else if (edge == -6) {
|
||||
W.x = 0.0;
|
||||
W.y = 0.0;
|
||||
W.z = 1.0; // z cube face
|
||||
} else {
|
||||
// vertices for triange
|
||||
int e2 = halfedge.next(edge);
|
||||
int e3 = halfedge.next(e2);
|
||||
|
@ -289,13 +322,14 @@ Point DCEL::TriNormal(int edge)
|
|||
ny = U.z * V.x - U.x * V.z;
|
||||
nz = U.x * V.y - U.y * V.x;
|
||||
len = sqrt(nx * nx + ny * ny + nz * nz);
|
||||
W.x = nx/len; W.y = ny/len; W.z = nz/len;
|
||||
W.x = nx / len;
|
||||
W.y = ny / len;
|
||||
W.z = nz / len;
|
||||
}
|
||||
return W;
|
||||
}
|
||||
|
||||
double DCEL::EdgeAngle(int edge)
|
||||
{
|
||||
double DCEL::EdgeAngle(int edge) {
|
||||
double angle;
|
||||
double dotprod;
|
||||
Point P, Q, R; // triangle vertices
|
||||
|
@ -320,16 +354,22 @@ double DCEL::EdgeAngle(int edge)
|
|||
double nz = W.x * V.y - W.y * V.x;
|
||||
length = sqrt(nx * nx + ny * ny + nz * nz);
|
||||
// new value for V is this normal vector
|
||||
V.x = nx/length; V.y = ny/length; V.z = nz/length;
|
||||
V.x = nx / length;
|
||||
V.y = ny / length;
|
||||
V.z = nz / length;
|
||||
dotprod = U.x * V.x + U.y * V.y + U.z * V.z;
|
||||
if (dotprod < 0.f) {
|
||||
//printf("negative dot product on face\n");
|
||||
dotprod = -dotprod;
|
||||
V.x = -V.x; V.y = -V.y; V.z = -V.z;
|
||||
V.x = -V.x;
|
||||
V.y = -V.y;
|
||||
V.z = -V.z;
|
||||
}
|
||||
|
||||
if (dotprod > 1.f) dotprod=1.f;
|
||||
if (dotprod < -1.f) dotprod=-1.f;
|
||||
if (dotprod > 1.f)
|
||||
dotprod = 1.f;
|
||||
if (dotprod < -1.f)
|
||||
dotprod = -1.f;
|
||||
angle = acos(dotprod);
|
||||
/* project onto plane of cube face also works
|
||||
W = U - dotprod*V;
|
||||
|
@ -339,11 +379,12 @@ double DCEL::EdgeAngle(int edge)
|
|||
if (dotprod < -1.f) dotprod=-1.f;
|
||||
angle = acos(dotprod);
|
||||
*/
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
dotprod = U.x * V.x + U.y * V.y + U.z * V.z;
|
||||
if (dotprod > 1.f) dotprod=1.f;
|
||||
if (dotprod < -1.f) dotprod=-1.f;
|
||||
if (dotprod > 1.f)
|
||||
dotprod = 1.f;
|
||||
if (dotprod < -1.f)
|
||||
dotprod = -1.f;
|
||||
angle = 0.5 * acos(dotprod);
|
||||
}
|
||||
// determine if angle is concave or convex based on edge normal
|
||||
|
@ -362,13 +403,13 @@ double DCEL::EdgeAngle(int edge)
|
|||
// concave
|
||||
angle = -angle;
|
||||
}
|
||||
if (angle != angle) angle = 0.0;
|
||||
if (angle != angle)
|
||||
angle = 0.0;
|
||||
//printf("angle=%f,dot=%f (Edge=%i, twin=%i): P={%f, %f, %f}, Q={%f, %f, %f} U={%f, %f, %f}, V={%f, %f, %f}\n",angle,dotprod,edge,halfedge.twin(edge),P.x,P.y,P.z,Q.x,Q.y,Q.z,U.x,U.y,U.z,V.x,V.y,V.z);
|
||||
return angle;
|
||||
}
|
||||
|
||||
void iso_surface(const Array<double>&Field, const double isovalue)
|
||||
{
|
||||
void iso_surface(const Array<double> &Field, const double isovalue) {
|
||||
DCEL object;
|
||||
int e1, e2, e3;
|
||||
FILE *TRIANGLES;
|
||||
|
@ -392,14 +433,17 @@ void iso_surface(const Array<double>&Field, const double isovalue)
|
|||
// P1.x += 1.0*i; P1.y += 1.0*j; P1.z +=1.0*k;
|
||||
//P2.x += 1.0*i; P2.y += 1.0*j; P2.z +=1.0*k;
|
||||
//P3.x += 1.0*i; P3.y += 1.0*j; P3.z +=1.0*k;
|
||||
fprintf(TRIANGLES,"facet normal %f %f %f\n",Normal.x,Normal.y,Normal.z);
|
||||
fprintf(TRIANGLES, "facet normal %f %f %f\n", Normal.x,
|
||||
Normal.y, Normal.z);
|
||||
fprintf(TRIANGLES, " outer loop\n");
|
||||
fprintf(TRIANGLES," vertex %f %f %f\n",P1.x,P1.y,P1.z);
|
||||
fprintf(TRIANGLES," vertex %f %f %f\n",P2.x,P2.y,P2.z);
|
||||
fprintf(TRIANGLES," vertex %f %f %f\n",P3.x,P3.y,P3.z);
|
||||
fprintf(TRIANGLES, " vertex %f %f %f\n", P1.x, P1.y,
|
||||
P1.z);
|
||||
fprintf(TRIANGLES, " vertex %f %f %f\n", P2.x, P2.y,
|
||||
P2.z);
|
||||
fprintf(TRIANGLES, " vertex %f %f %f\n", P3.x, P3.y,
|
||||
P3.z);
|
||||
fprintf(TRIANGLES, " endloop\n");
|
||||
fprintf(TRIANGLES, "endfacet\n");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ private:
|
|||
std::vector<Point> d_data;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \class Halfedge
|
||||
* @brief store half edge for DCEL data structure
|
||||
|
@ -75,7 +74,8 @@ public:
|
|||
int face();
|
||||
Vertex vertex;
|
||||
Halfedge halfedge;
|
||||
void LocalIsosurface(const DoubleArray& A, double value, int i, int j, int k);
|
||||
void LocalIsosurface(const DoubleArray &A, double value, int i, int j,
|
||||
int k);
|
||||
void Write();
|
||||
int Face(int index);
|
||||
|
||||
|
|
|
@ -1,17 +1,32 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "analysis/distance.h"
|
||||
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* A fast distance calculation *
|
||||
******************************************************************/
|
||||
template <class TYPE>
|
||||
void CalcDist(Array<TYPE> &Distance, const Array<char> &ID, const Domain &Dm,
|
||||
const std::array<bool,3>& periodic, const std::array<double,3>& dx )
|
||||
{
|
||||
const std::array<bool, 3> &periodic,
|
||||
const std::array<double, 3> &dx) {
|
||||
ASSERT(Distance.size() == ID.size());
|
||||
std::array<int, 3> n = {Dm.Nx - 2, Dm.Ny - 2, Dm.Nz - 2};
|
||||
fillHalo<int> fillData( Dm.Comm, Dm.rank_info, n, {1,1,1}, 50, 1, {true,false,false}, periodic );
|
||||
fillHalo<int> fillData(Dm.Comm, Dm.rank_info, n, {1, 1, 1}, 50, 1,
|
||||
{true, false, false}, periodic);
|
||||
Array<int> id(ID.size());
|
||||
Array<Vec> vecDist(Distance.size());
|
||||
for (size_t i = 0; i < ID.length(); i++)
|
||||
|
@ -22,13 +37,12 @@ void CalcDist( Array<TYPE> &Distance, const Array<char> &ID, const Domain &Dm,
|
|||
Distance(i) = id(i) * vecDist(i).norm();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* Vector-based distance calculation *
|
||||
* Initialize cells adjacent to boundaries *
|
||||
******************************************************************/
|
||||
static void calcVecInitialize( Array<Vec> &d, const Array<int> &ID, double dx, double dy, double dz )
|
||||
{
|
||||
static void calcVecInitialize(Array<Vec> &d, const Array<int> &ID, double dx,
|
||||
double dy, double dz) {
|
||||
d.fill(Vec(1e50, 1e50, 1e50));
|
||||
const double dx0 = 0.5 * dx;
|
||||
const double dy0 = 0.5 * dy;
|
||||
|
@ -47,12 +61,18 @@ static void calcVecInitialize( Array<Vec> &d, const Array<int> &ID, double dx, d
|
|||
bool x[2] = {id != ID(i - 1, j, k), id != ID(i + 1, j, k)};
|
||||
bool y[2] = {id != ID(i, j - 1, k), id != ID(i, j + 1, k)};
|
||||
bool z[2] = {id != ID(i, j, k - 1), id != ID(i, j, k + 1)};
|
||||
if ( x[0] ) d(i,j,k) = Vec( dx0, 0, 0 );
|
||||
if ( x[1] ) d(i,j,k) = Vec( -dx0, 0, 0 );
|
||||
if ( y[0] ) d(i,j,k) = Vec( 0, dy0, 0 );
|
||||
if ( y[1] ) d(i,j,k) = Vec( 0, -dy0, 0 );
|
||||
if ( z[0] ) d(i,j,k) = Vec( 0, 0, dz0 );
|
||||
if ( z[1] ) d(i,j,k) = Vec( 0, 0, -dz0 );
|
||||
if (x[0])
|
||||
d(i, j, k) = Vec(dx0, 0, 0);
|
||||
if (x[1])
|
||||
d(i, j, k) = Vec(-dx0, 0, 0);
|
||||
if (y[0])
|
||||
d(i, j, k) = Vec(0, dy0, 0);
|
||||
if (y[1])
|
||||
d(i, j, k) = Vec(0, -dy0, 0);
|
||||
if (z[0])
|
||||
d(i, j, k) = Vec(0, 0, dz0);
|
||||
if (z[1])
|
||||
d(i, j, k) = Vec(0, 0, -dz0);
|
||||
/*if ( x[0] && y[0] ) d(i,j,k) = Vec( dxy0, dxy0, 0 );
|
||||
if ( x[0] && y[1] ) d(i,j,k) = Vec( dxy0, -dxy0, 0 );
|
||||
if ( x[1] && y[0] ) d(i,j,k) = Vec( -dxy0, dxy0, 0 );
|
||||
|
@ -68,16 +88,14 @@ static void calcVecInitialize( Array<Vec> &d, const Array<int> &ID, double dx, d
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* Vector-based distance calculation *
|
||||
* Update interior cells *
|
||||
******************************************************************/
|
||||
static double calcVecUpdateInterior( Array<Vec> &d, double dx, double dy, double dz )
|
||||
{
|
||||
static double calcVecUpdateInterior(Array<Vec> &d, double dx, double dy,
|
||||
double dz) {
|
||||
double err = 0;
|
||||
int Nx = d.size(0);
|
||||
int Ny = d.size(1);
|
||||
|
@ -125,18 +143,18 @@ static double calcVecUpdateInterior( Array<Vec> &d, double dx, double dy, double
|
|||
return err;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* Vector-based distance calculation *
|
||||
******************************************************************/
|
||||
void CalcVecDist(Array<Vec> &d, const Array<int> &ID0, const Domain &Dm,
|
||||
const std::array<bool,3>& periodic, const std::array<double,3>& dx )
|
||||
{
|
||||
const std::array<bool, 3> &periodic,
|
||||
const std::array<double, 3> &dx) {
|
||||
std::array<int, 3> N = {Dm.Nx, Dm.Ny, Dm.Nz};
|
||||
std::array<int, 3> n = {Dm.Nx - 2, Dm.Ny - 2, Dm.Nz - 2};
|
||||
// Create ID with ghosts
|
||||
Array<int> ID(N[0], N[1], N[2]);
|
||||
fillHalo<int> fillDataID( Dm.Comm, Dm.rank_info, n, {1,1,1}, 50, 1, {true,true,true}, periodic );
|
||||
fillHalo<int> fillDataID(Dm.Comm, Dm.rank_info, n, {1, 1, 1}, 50, 1,
|
||||
{true, true, true}, periodic);
|
||||
fillDataID.copy(ID0, ID);
|
||||
// Fill ghosts with nearest neighbor
|
||||
for (int k = 1; k < N[2] - 1; k++) {
|
||||
|
@ -160,7 +178,8 @@ void CalcVecDist( Array<Vec> &d, const Array<int> &ID0, const Domain &Dm,
|
|||
// Communicate ghosts
|
||||
fillDataID.fill(ID);
|
||||
// Create communicator for distance
|
||||
fillHalo<Vec> fillData( Dm.Comm, Dm.rank_info, n, {1,1,1}, 50, 1, {true,false,false}, periodic );
|
||||
fillHalo<Vec> fillData(Dm.Comm, Dm.rank_info, n, {1, 1, 1}, 50, 1,
|
||||
{true, false, false}, periodic);
|
||||
// Calculate the local distances
|
||||
calcVecInitialize(d, ID, dx[0], dx[1], dx[2]);
|
||||
double err = 1e100;
|
||||
|
@ -182,9 +201,10 @@ void CalcVecDist( Array<Vec> &d, const Array<int> &ID0, const Domain &Dm,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Explicit instantiations
|
||||
template void CalcDist<float>( Array<float>&, const Array<char>&, const Domain&, const std::array<bool,3>&, const std::array<double,3>& );
|
||||
template void CalcDist<double>( Array<double>&, const Array<char>&, const Domain&, const std::array<bool,3>&, const std::array<double,3>& );
|
||||
|
||||
|
||||
template void CalcDist<float>(Array<float> &, const Array<char> &,
|
||||
const Domain &, const std::array<bool, 3> &,
|
||||
const std::array<double, 3> &);
|
||||
template void CalcDist<double>(Array<double> &, const Array<char> &,
|
||||
const Domain &, const std::array<bool, 3> &,
|
||||
const std::array<double, 3> &);
|
||||
|
|
|
@ -1,10 +1,25 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef Distance_H_INC
|
||||
#define Distance_H_INC
|
||||
|
||||
#include "common/Domain.h"
|
||||
#include "common/Array.hpp"
|
||||
|
||||
|
||||
struct Vec {
|
||||
double x;
|
||||
double y;
|
||||
|
@ -14,8 +29,10 @@ struct Vec {
|
|||
inline double norm() const { return sqrt(x * x + y * y + z * z); }
|
||||
inline double norm2() const { return x * x + y * y + z * z; }
|
||||
};
|
||||
inline bool operator<(const Vec& l, const Vec& r){ return l.x*l.x+l.y*l.y+l.z*l.z < r.x*r.x+r.y*r.y+r.z*r.z; }
|
||||
|
||||
inline bool operator<(const Vec &l, const Vec &r) {
|
||||
return l.x * l.x + l.y * l.y + l.z * l.z <
|
||||
r.x * r.x + r.y * r.y + r.z * r.z;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Calculate the distance using a simple method
|
||||
|
@ -28,7 +45,8 @@ inline bool operator<(const Vec& l, const Vec& r){ return l.x*l.x+l.y*l.y+l.z*l.
|
|||
*/
|
||||
template <class TYPE>
|
||||
void CalcDist(Array<TYPE> &Distance, const Array<char> &ID, const Domain &Dm,
|
||||
const std::array<bool,3>& periodic = {true,true,true}, const std::array<double,3>& dx = {1,1,1} );
|
||||
const std::array<bool, 3> &periodic = {true, true, true},
|
||||
const std::array<double, 3> &dx = {1, 1, 1});
|
||||
|
||||
/*!
|
||||
* @brief Calculate the distance using a simple method
|
||||
|
@ -40,6 +58,7 @@ void CalcDist( Array<TYPE> &Distance, const Array<char> &ID, const Domain &Dm,
|
|||
* @param[in] dx Cell size
|
||||
*/
|
||||
void CalcVecDist(Array<Vec> &Distance, const Array<int> &ID, const Domain &Dm,
|
||||
const std::array<bool,3>& periodic = {true,true,true}, const std::array<double,3>& dx = {1,1,1} );
|
||||
const std::array<bool, 3> &periodic = {true, true, true},
|
||||
const std::array<double, 3> &dx = {1, 1, 1});
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,9 +1,24 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "analysis/filters.h"
|
||||
#include "math.h"
|
||||
#include "ProfilerApp.h"
|
||||
|
||||
void Mean3D( const Array<double> &Input, Array<double> &Output )
|
||||
{
|
||||
void Mean3D(const Array<double> &Input, Array<double> &Output) {
|
||||
PROFILE_START("Mean3D");
|
||||
// Perform a 3D Mean filter on Input array
|
||||
int i, j, k;
|
||||
|
@ -17,12 +32,21 @@ void Mean3D( const Array<double> &Input, Array<double> &Output )
|
|||
for (i = 1; i < Nx - 1; i++) {
|
||||
double MeanValue = Input(i, j, k);
|
||||
// next neighbors
|
||||
MeanValue += Input(i+1,j,k)+Input(i,j+1,k)+Input(i,j,k+1)+Input(i-1,j,k)+Input(i,j-1,k)+Input(i,j,k-1);
|
||||
MeanValue += Input(i+1,j+1,k)+Input(i-1,j+1,k)+Input(i+1,j-1,k)+Input(i-1,j-1,k);
|
||||
MeanValue += Input(i+1,j,k+1)+Input(i-1,j,k+1)+Input(i+1,j,k-1)+Input(i-1,j,k-1);
|
||||
MeanValue += Input(i,j+1,k+1)+Input(i,j-1,k+1)+Input(i,j+1,k-1)+Input(i,j-1,k-1);
|
||||
MeanValue += Input(i+1,j+1,k+1)+Input(i-1,j+1,k+1)+Input(i+1,j-1,k+1)+Input(i-1,j-1,k+1);
|
||||
MeanValue += Input(i+1,j+1,k-1)+Input(i-1,j+1,k-1)+Input(i+1,j-1,k-1)+Input(i-1,j-1,k-1);
|
||||
MeanValue += Input(i + 1, j, k) + Input(i, j + 1, k) +
|
||||
Input(i, j, k + 1) + Input(i - 1, j, k) +
|
||||
Input(i, j - 1, k) + Input(i, j, k - 1);
|
||||
MeanValue += Input(i + 1, j + 1, k) + Input(i - 1, j + 1, k) +
|
||||
Input(i + 1, j - 1, k) + Input(i - 1, j - 1, k);
|
||||
MeanValue += Input(i + 1, j, k + 1) + Input(i - 1, j, k + 1) +
|
||||
Input(i + 1, j, k - 1) + Input(i - 1, j, k - 1);
|
||||
MeanValue += Input(i, j + 1, k + 1) + Input(i, j - 1, k + 1) +
|
||||
Input(i, j + 1, k - 1) + Input(i, j - 1, k - 1);
|
||||
MeanValue +=
|
||||
Input(i + 1, j + 1, k + 1) + Input(i - 1, j + 1, k + 1) +
|
||||
Input(i + 1, j - 1, k + 1) + Input(i - 1, j - 1, k + 1);
|
||||
MeanValue +=
|
||||
Input(i + 1, j + 1, k - 1) + Input(i - 1, j + 1, k - 1) +
|
||||
Input(i + 1, j - 1, k - 1) + Input(i - 1, j - 1, k - 1);
|
||||
Output(i, j, k) = MeanValue / 27.0;
|
||||
}
|
||||
}
|
||||
|
@ -30,8 +54,7 @@ void Mean3D( const Array<double> &Input, Array<double> &Output )
|
|||
PROFILE_STOP("Mean3D");
|
||||
}
|
||||
|
||||
void Med3D( const Array<float> &Input, Array<float> &Output )
|
||||
{
|
||||
void Med3D(const Array<float> &Input, Array<float> &Output) {
|
||||
PROFILE_START("Med3D");
|
||||
// Perform a 3D Median filter on Input array with specified width
|
||||
int i, j, k, ii, jj, kk;
|
||||
|
@ -83,10 +106,9 @@ void Med3D( const Array<float> &Input, Array<float> &Output )
|
|||
PROFILE_STOP("Med3D");
|
||||
}
|
||||
|
||||
|
||||
int NLM3D(const Array<float> &Input, Array<float> &Mean,
|
||||
const Array<float> &Distance, Array<float> &Output, const int d, const float h)
|
||||
{
|
||||
const Array<float> &Distance, Array<float> &Output, const int d,
|
||||
const float h) {
|
||||
PROFILE_START("NLM3D");
|
||||
// Implemenation of 3D non-local means filter
|
||||
// d determines the width of the search volume
|
||||
|
@ -117,7 +139,8 @@ int NLM3D( const Array<float> &Input, Array<float> &Mean,
|
|||
kmax = std::min(Nz - 1, k + d);
|
||||
|
||||
// Populate the list with values in the window
|
||||
sum = 0; weight=0;
|
||||
sum = 0;
|
||||
weight = 0;
|
||||
for (kk = kmin; kk < kmax; kk++) {
|
||||
for (jj = jmin; jj < jmax; jj++) {
|
||||
for (ii = imin; ii < imax; ii++) {
|
||||
|
@ -137,10 +160,10 @@ int NLM3D( const Array<float> &Input, Array<float> &Mean,
|
|||
for (j = 1; j < Ny - 1; j++) {
|
||||
for (i = 1; i < Nx - 1; i++) {
|
||||
|
||||
|
||||
if (fabs(Distance(i, j, k)) < THRESHOLD_DIST) {
|
||||
// compute the expensive non-local means
|
||||
sum = 0; weight=0;
|
||||
sum = 0;
|
||||
weight = 0;
|
||||
|
||||
imin = std::max(0, i - d);
|
||||
jmin = std::max(0, j - d);
|
||||
|
@ -162,8 +185,7 @@ int NLM3D( const Array<float> &Input, Array<float> &Mean,
|
|||
returnCount++;
|
||||
//Output(i,j,k) = Mean(i,j,k);
|
||||
Output(i, j, k) = sum / weight;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
// Just return the mean
|
||||
Output(i, j, k) = Mean(i, j, k);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,22 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef Filters_H_INC
|
||||
#define Filters_H_INC
|
||||
|
||||
|
||||
#include "common/Array.h"
|
||||
|
||||
/*!
|
||||
|
@ -31,7 +46,7 @@ void Med3D( const Array<float> &Input, Array<float> &Output );
|
|||
* @param[in] h
|
||||
*/
|
||||
int NLM3D(const Array<float> &Input, Array<float> &Mean,
|
||||
const Array<float> &Distance, Array<float> &Output, const int d, const float h);
|
||||
|
||||
const Array<float> &Distance, Array<float> &Output, const int d,
|
||||
const float h);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
* Generate a histogram for volumetric, interfacial and common curve properties
|
||||
* copyright 2014, James E. McClure
|
||||
|
@ -12,18 +28,19 @@ struct Histogram{
|
|||
maximum = v2;
|
||||
delta = (maximum - minimum) / HISTOGRAM_RESOLUTION;
|
||||
}
|
||||
~Histogram{
|
||||
delete *data;
|
||||
}
|
||||
~Histogram { delete *data; }
|
||||
double *data;
|
||||
double minimum, maximum, delta;
|
||||
|
||||
// Adds value into the histogram
|
||||
void IncludeValue(double value, double weight) {
|
||||
idx = floor((value - min) / delta);
|
||||
if (idx > HISTOGRAM_RESOLUTION) ;
|
||||
else if (idx < 0) ;
|
||||
else data[idx] += weight;
|
||||
if (idx > HISTOGRAM_RESOLUTION)
|
||||
;
|
||||
else if (idx < 0)
|
||||
;
|
||||
else
|
||||
data[idx] += weight;
|
||||
}
|
||||
|
||||
// Returns the maximum value in the histogram
|
||||
|
@ -38,7 +55,8 @@ struct Histogram{
|
|||
|
||||
// Resets the histogram to zero
|
||||
void Reset() {
|
||||
for (idx=0; idx<HISTOGRAM_RESOLUTION; idx++) data[idx] = 0.0;
|
||||
for (idx = 0; idx < HISTOGRAM_RESOLUTION; idx++)
|
||||
data[idx] = 0.0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// These functions mimic the behavior of imfilter in MATLAB
|
||||
#ifndef included_imfilter
|
||||
#define included_imfilter
|
||||
|
@ -6,14 +22,11 @@
|
|||
#include "common/Array.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace imfilter {
|
||||
|
||||
|
||||
//! enum to store the BC type
|
||||
enum class BC { fixed = 0, symmetric = 1, replicate = 2, circular = 3 };
|
||||
|
||||
|
||||
/*!
|
||||
* @brief N-D filtering of multidimensional images
|
||||
* @details imfilter filters the multidimensional array A with the
|
||||
|
@ -32,8 +45,9 @@ enum class BC { fixed=0, symmetric=1, replicate=2, circular=3 };
|
|||
* @param[in] X The value to use for boundary conditions (only used if boundary==fixed)
|
||||
*/
|
||||
template <class TYPE>
|
||||
Array<TYPE> imfilter( const Array<TYPE>& A, const Array<TYPE>& H, const std::vector<imfilter::BC>& boundary, const TYPE X=0 );
|
||||
|
||||
Array<TYPE> imfilter(const Array<TYPE> &A, const Array<TYPE> &H,
|
||||
const std::vector<imfilter::BC> &boundary,
|
||||
const TYPE X = 0);
|
||||
|
||||
/*!
|
||||
* @brief N-D filtering of multidimensional images
|
||||
|
@ -57,8 +71,8 @@ Array<TYPE> imfilter( const Array<TYPE>& A, const Array<TYPE>& H, const std::vec
|
|||
template <class TYPE>
|
||||
Array<TYPE> imfilter(const Array<TYPE> &A, const std::vector<int> &Nh,
|
||||
std::function<TYPE(const Array<TYPE> &)> H,
|
||||
const std::vector<imfilter::BC>& boundary, const TYPE X=0 );
|
||||
|
||||
const std::vector<imfilter::BC> &boundary,
|
||||
const TYPE X = 0);
|
||||
|
||||
/*!
|
||||
* @brief N-D filtering of multidimensional images
|
||||
|
@ -79,10 +93,10 @@ Array<TYPE> imfilter( const Array<TYPE>& A, const std::vector<int>& Nh,
|
|||
* @param[in] X The value to use for boundary conditions (only used if boundary==fixed)
|
||||
*/
|
||||
template <class TYPE>
|
||||
Array<TYPE> imfilter_separable( const Array<TYPE>& A, const std::vector<Array<TYPE>>& H,
|
||||
Array<TYPE>
|
||||
imfilter_separable(const Array<TYPE> &A, const std::vector<Array<TYPE>> &H,
|
||||
const std::vector<imfilter::BC> &boundary, const TYPE X = 0);
|
||||
|
||||
|
||||
/*!
|
||||
* @brief N-D filtering of multidimensional images
|
||||
* @details imfilter filters the multidimensional array A with the
|
||||
|
@ -102,11 +116,11 @@ Array<TYPE> imfilter_separable( const Array<TYPE>& A, const std::vector<Array<TY
|
|||
* @param[in] X The value to use for boundary conditions (only used if boundary==fixed)
|
||||
*/
|
||||
template <class TYPE>
|
||||
Array<TYPE> imfilter_separable( const Array<TYPE>& A, const std::vector<int>& Nh,
|
||||
Array<TYPE>
|
||||
imfilter_separable(const Array<TYPE> &A, const std::vector<int> &Nh,
|
||||
std::vector<std::function<TYPE(const Array<TYPE> &)>> H,
|
||||
const std::vector<imfilter::BC> &boundary, const TYPE X = 0);
|
||||
|
||||
|
||||
/*!
|
||||
* @brief N-D filtering of multidimensional images
|
||||
* @details imfilter filters the multidimensional array A with the
|
||||
|
@ -127,11 +141,11 @@ Array<TYPE> imfilter_separable( const Array<TYPE>& A, const std::vector<int>& Nh
|
|||
* @param[in] X The value to use for boundary conditions (only used if boundary==fixed)
|
||||
*/
|
||||
template <class TYPE>
|
||||
Array<TYPE> imfilter_separable( const Array<TYPE>& A, const std::vector<int>& Nh,
|
||||
Array<TYPE>
|
||||
imfilter_separable(const Array<TYPE> &A, const std::vector<int> &Nh,
|
||||
std::vector<std::function<TYPE(int, const TYPE *)>> H,
|
||||
const std::vector<imfilter::BC> &boundary, const TYPE X = 0);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Create a filter to use with imfilter
|
||||
* @details This function creates one of several predefined filters
|
||||
|
@ -148,13 +162,11 @@ Array<TYPE> imfilter_separable( const Array<TYPE>& A, const std::vector<int>& Nh
|
|||
* \param[in] args An optional argument that some of the filters use
|
||||
*/
|
||||
template <class TYPE>
|
||||
Array<TYPE> create_filter( const std::vector<int>& N, const std::string &type, const void *args = NULL );
|
||||
|
||||
|
||||
}
|
||||
Array<TYPE> create_filter(const std::vector<int> &N, const std::string &type,
|
||||
const void *args = NULL);
|
||||
|
||||
} // namespace imfilter
|
||||
|
||||
#include "analysis/imfilter.hpp"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,17 +1,47 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "analysis/imfilter.h"
|
||||
#include "ProfilerApp.h"
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#define IMFILTER_INSIST INSIST
|
||||
#define IMFILTER_ASSERT ASSERT
|
||||
#define IMFILTER_ERROR ERROR
|
||||
|
||||
|
||||
// Function to convert an index
|
||||
static inline int imfilter_index( int index, const int N, const imfilter::BC bc )
|
||||
{
|
||||
static inline int imfilter_index(int index, const int N,
|
||||
const imfilter::BC bc) {
|
||||
if (index < 0 || index >= N) {
|
||||
if (bc == imfilter::BC::symmetric) {
|
||||
index = (2 * N - index) % N;
|
||||
|
@ -26,12 +56,11 @@ static inline int imfilter_index( int index, const int N, const imfilter::BC bc
|
|||
return index;
|
||||
}
|
||||
|
||||
|
||||
// Function to copy a 1D array and pad with the appropriate BC
|
||||
template <class TYPE>
|
||||
static inline void copy_array(const int N, const int Ns, const int Nh,
|
||||
const TYPE *A, const imfilter::BC BC, const TYPE X, TYPE *B )
|
||||
{
|
||||
const TYPE *A, const imfilter::BC BC,
|
||||
const TYPE X, TYPE *B) {
|
||||
// Fill the center with a memcpy
|
||||
for (int i = 0; i < N; i++)
|
||||
B[i + Nh] = A[i * Ns];
|
||||
|
@ -44,14 +73,12 @@ static inline void copy_array( const int N, const int Ns, const int Nh,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Perform a 1D filter in a single direction *
|
||||
********************************************************/
|
||||
template <class TYPE>
|
||||
static void filter_direction(int Ns, int N, int Ne, int Nh, const TYPE *H,
|
||||
imfilter::BC boundary, TYPE X, TYPE *A )
|
||||
{
|
||||
imfilter::BC boundary, TYPE X, TYPE *A) {
|
||||
if (Nh < 0)
|
||||
IMFILTER_ERROR("Invalid filter size");
|
||||
if (Nh == 0) {
|
||||
|
@ -75,8 +102,8 @@ static void filter_direction( int Ns, int N, int Ne, int Nh, const TYPE *H,
|
|||
}
|
||||
template <class TYPE>
|
||||
static void filter_direction(int Ns, int N, int Ne, int Nh,
|
||||
std::function<TYPE(const Array<TYPE>&)> H, imfilter::BC boundary, TYPE X, TYPE *A )
|
||||
{
|
||||
std::function<TYPE(const Array<TYPE> &)> H,
|
||||
imfilter::BC boundary, TYPE X, TYPE *A) {
|
||||
if (Nh < 0)
|
||||
IMFILTER_ERROR("Invalid filter size");
|
||||
TYPE *tmp = new TYPE[N + 2 * Nh];
|
||||
|
@ -95,8 +122,8 @@ static void filter_direction( int Ns, int N, int Ne, int Nh,
|
|||
}
|
||||
template <class TYPE>
|
||||
static void filter_direction(int Ns, int N, int Ne, int Nh,
|
||||
std::function<TYPE(int, const TYPE*)> H, imfilter::BC boundary, TYPE X, TYPE *A )
|
||||
{
|
||||
std::function<TYPE(int, const TYPE *)> H,
|
||||
imfilter::BC boundary, TYPE X, TYPE *A) {
|
||||
if (Nh < 0)
|
||||
IMFILTER_ERROR("Invalid filter size");
|
||||
TYPE *tmp = new TYPE[N + 2 * Nh];
|
||||
|
@ -111,14 +138,12 @@ static void filter_direction( int Ns, int N, int Ne, int Nh,
|
|||
delete[] tmp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Create a filter *
|
||||
********************************************************/
|
||||
template <class TYPE>
|
||||
Array<TYPE> imfilter::create_filter( const std::vector<int>& N0, const std::string &type, const void *args )
|
||||
{
|
||||
Array<TYPE> imfilter::create_filter(const std::vector<int> &N0,
|
||||
const std::string &type, const void *args) {
|
||||
std::vector<size_t> N2(N0.size());
|
||||
for (size_t i = 0; i < N2.size(); i++)
|
||||
N2[i] = 2 * N0[i] + 1;
|
||||
|
@ -156,12 +181,10 @@ Array<TYPE> imfilter::create_filter( const std::vector<int>& N0, const std::stri
|
|||
return h;
|
||||
}
|
||||
|
||||
|
||||
// Perform 2-D filtering
|
||||
template <class TYPE>
|
||||
void imfilter_2D(int Nx, int Ny, const TYPE *A, int Nhx, int Nhy, const TYPE *H,
|
||||
imfilter::BC BCx, imfilter::BC BCy, const TYPE X, TYPE *B )
|
||||
{
|
||||
imfilter::BC BCx, imfilter::BC BCy, const TYPE X, TYPE *B) {
|
||||
IMFILTER_ASSERT(A != B);
|
||||
PROFILE_START("imfilter_2D");
|
||||
memset(B, 0, Nx * Ny * sizeof(TYPE));
|
||||
|
@ -193,13 +216,11 @@ void imfilter_2D( int Nx, int Ny, const TYPE *A, int Nhx, int Nhy, const TYPE *H
|
|||
PROFILE_STOP("imfilter_2D");
|
||||
}
|
||||
|
||||
|
||||
// Perform 3-D filtering
|
||||
template <class TYPE>
|
||||
void imfilter_3D( int Nx, int Ny, int Nz, const TYPE *A, int Nhx, int Nhy, int Nhz,
|
||||
const TYPE *H, imfilter::BC BCx, imfilter::BC BCy, imfilter::BC BCz,
|
||||
const TYPE X, TYPE *B )
|
||||
{
|
||||
void imfilter_3D(int Nx, int Ny, int Nz, const TYPE *A, int Nhx, int Nhy,
|
||||
int Nhz, const TYPE *H, imfilter::BC BCx, imfilter::BC BCy,
|
||||
imfilter::BC BCz, const TYPE X, TYPE *B) {
|
||||
IMFILTER_ASSERT(A != B);
|
||||
PROFILE_START("imfilter_3D");
|
||||
memset(B, 0, Nx * Ny * Nz * sizeof(TYPE));
|
||||
|
@ -215,7 +236,8 @@ void imfilter_3D( int Nx, int Ny, int Nz, const TYPE *A, int Nhx, int Nhy, int N
|
|||
for (int ih = -Nhx; ih <= Nhx; ih++) {
|
||||
int i2 = imfilter_index(i1 + ih, Nx, BCx);
|
||||
bool fixed = i2 == -1 || j2 == -1 || k2 == -1;
|
||||
TYPE A2 = fixed ? X : A[i2 + j2 * Nx + k2 * Nx * Ny];
|
||||
TYPE A2 =
|
||||
fixed ? X : A[i2 + j2 * Nx + k2 * Nx * Ny];
|
||||
tmp += H[ijkh] * A2;
|
||||
ijkh++;
|
||||
}
|
||||
|
@ -228,20 +250,20 @@ void imfilter_3D( int Nx, int Ny, int Nz, const TYPE *A, int Nhx, int Nhy, int N
|
|||
PROFILE_STOP("imfilter_3D");
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Perform N-D filtering *
|
||||
********************************************************/
|
||||
template <class TYPE>
|
||||
Array<TYPE> imfilter::imfilter( const Array<TYPE>& A,
|
||||
const Array<TYPE>& H, const std::vector<imfilter::BC>& BC, const TYPE X )
|
||||
{
|
||||
Array<TYPE> imfilter::imfilter(const Array<TYPE> &A, const Array<TYPE> &H,
|
||||
const std::vector<imfilter::BC> &BC,
|
||||
const TYPE X) {
|
||||
IMFILTER_ASSERT(A.ndim() == H.ndim());
|
||||
IMFILTER_ASSERT(A.ndim() == BC.size());
|
||||
std::vector<size_t> Nh = H.size();
|
||||
for (int d = 0; d < A.ndim(); d++) {
|
||||
Nh[d] = (H.size(d) - 1) / 2;
|
||||
IMFILTER_INSIST(2*Nh[d]+1==H.size(d),"Filter must be of size 2*N+1");
|
||||
IMFILTER_INSIST(2 * Nh[d] + 1 == H.size(d),
|
||||
"Filter must be of size 2*N+1");
|
||||
}
|
||||
auto B = A;
|
||||
if (A.ndim() == 1) {
|
||||
|
@ -249,20 +271,21 @@ Array<TYPE> imfilter::imfilter( const Array<TYPE>& A,
|
|||
filter_direction(1, A.size(0), 1, Nh[0], H.data(), BC[0], X, B.data());
|
||||
PROFILE_STOP("imfilter_1D");
|
||||
} else if (A.ndim() == 2) {
|
||||
imfilter_2D( A.size(0), A.size(1), A.data(), Nh[0], Nh[1], H.data(), BC[0], BC[1], X, B.data() );
|
||||
imfilter_2D(A.size(0), A.size(1), A.data(), Nh[0], Nh[1], H.data(),
|
||||
BC[0], BC[1], X, B.data());
|
||||
} else if (A.ndim() == 3) {
|
||||
imfilter_3D( A.size(0), A.size(1), A.size(2), A.data(),
|
||||
Nh[0], Nh[1], Nh[2], H.data(), BC[0], BC[1], BC[2], X, B.data() );
|
||||
imfilter_3D(A.size(0), A.size(1), A.size(2), A.data(), Nh[0], Nh[1],
|
||||
Nh[2], H.data(), BC[0], BC[1], BC[2], X, B.data());
|
||||
} else {
|
||||
IMFILTER_ERROR("Arbitrary dimension not yet supported");
|
||||
}
|
||||
return B;
|
||||
}
|
||||
template <class TYPE>
|
||||
Array<TYPE> imfilter::imfilter( const Array<TYPE>& A, const std::vector<int>& Nh0,
|
||||
Array<TYPE>
|
||||
imfilter::imfilter(const Array<TYPE> &A, const std::vector<int> &Nh0,
|
||||
std::function<TYPE(const Array<TYPE> &)> H,
|
||||
const std::vector<imfilter::BC>& BC0, const TYPE X )
|
||||
{
|
||||
const std::vector<imfilter::BC> &BC0, const TYPE X) {
|
||||
PROFILE_START("imfilter (lambda)");
|
||||
IMFILTER_ASSERT(A.ndim() == Nh0.size());
|
||||
IMFILTER_ASSERT(A.ndim() == BC0.size());
|
||||
|
@ -271,7 +294,8 @@ Array<TYPE> imfilter::imfilter( const Array<TYPE>& A, const std::vector<int>& Nh
|
|||
Nh2[d] = 2 * Nh0[d] + 1;
|
||||
auto B = A;
|
||||
Array<TYPE> data(Nh2);
|
||||
IMFILTER_INSIST(A.ndim()<=3,"Not programmed for more than 3 dimensions yet");
|
||||
IMFILTER_INSIST(A.ndim() <= 3,
|
||||
"Not programmed for more than 3 dimensions yet");
|
||||
auto N = A.size();
|
||||
auto Nh = Nh0;
|
||||
auto BC = BC0;
|
||||
|
@ -288,7 +312,8 @@ Array<TYPE> imfilter::imfilter( const Array<TYPE>& A, const std::vector<int>& Nh
|
|||
for (int ih = -Nh[0]; ih <= Nh[0]; ih++) {
|
||||
int i2 = imfilter_index(i1 + ih, N[0], BC[0]);
|
||||
bool fixed = i2 == -1 || j2 == -1 || k2 == -1;
|
||||
data(ih+Nh[0],jh+Nh[1],kh+Nh[2]) = fixed ? X : A(i2,j2,k2);
|
||||
data(ih + Nh[0], jh + Nh[1], kh + Nh[2]) =
|
||||
fixed ? X : A(i2, j2, k2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -300,15 +325,13 @@ Array<TYPE> imfilter::imfilter( const Array<TYPE>& A, const std::vector<int>& Nh
|
|||
return B;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* imfilter with separable filter functions *
|
||||
********************************************************/
|
||||
template <class TYPE>
|
||||
Array<TYPE> imfilter::imfilter_separable( const Array<TYPE>& A,
|
||||
const std::vector<Array<TYPE>>& H,
|
||||
const std::vector<imfilter::BC>& boundary, const TYPE X )
|
||||
{
|
||||
Array<TYPE> imfilter::imfilter_separable(
|
||||
const Array<TYPE> &A, const std::vector<Array<TYPE>> &H,
|
||||
const std::vector<imfilter::BC> &boundary, const TYPE X) {
|
||||
PROFILE_START("imfilter_separable");
|
||||
IMFILTER_ASSERT(A.ndim() == (int)H.size());
|
||||
IMFILTER_ASSERT(A.ndim() == (int)boundary.size());
|
||||
|
@ -316,7 +339,8 @@ Array<TYPE> imfilter::imfilter_separable( const Array<TYPE>& A,
|
|||
for (int d = 0; d < A.ndim(); d++) {
|
||||
IMFILTER_ASSERT(H[d].ndim() == 1);
|
||||
Nh[d] = (H[d].length() - 1) / 2;
|
||||
IMFILTER_INSIST(2*Nh[d]+1==H[d].length(),"Filter must be of size 2*N+1");
|
||||
IMFILTER_INSIST(2 * Nh[d] + 1 == H[d].length(),
|
||||
"Filter must be of size 2*N+1");
|
||||
}
|
||||
auto B = A;
|
||||
for (int d = 0; d < A.ndim(); d++) {
|
||||
|
@ -327,16 +351,17 @@ Array<TYPE> imfilter::imfilter_separable( const Array<TYPE>& A,
|
|||
Ns *= A.size(d2);
|
||||
for (int d2 = d + 1; d2 < A.ndim(); d2++)
|
||||
Ne *= A.size(d2);
|
||||
filter_direction( Ns, N, Ne, Nh[d], H[d].data(), boundary[d], X, B.data() );
|
||||
filter_direction(Ns, N, Ne, Nh[d], H[d].data(), boundary[d], X,
|
||||
B.data());
|
||||
}
|
||||
PROFILE_STOP("imfilter_separable");
|
||||
return B;
|
||||
}
|
||||
template <class TYPE>
|
||||
Array<TYPE> imfilter::imfilter_separable( const Array<TYPE>& A, const std::vector<int>& Nh,
|
||||
Array<TYPE> imfilter::imfilter_separable(
|
||||
const Array<TYPE> &A, const std::vector<int> &Nh,
|
||||
std::vector<std::function<TYPE(const Array<TYPE> &)>> H,
|
||||
const std::vector<imfilter::BC>& boundary, const TYPE X )
|
||||
{
|
||||
const std::vector<imfilter::BC> &boundary, const TYPE X) {
|
||||
PROFILE_START("imfilter_separable (lambda)");
|
||||
IMFILTER_ASSERT(A.ndim() == (int)boundary.size());
|
||||
auto B = A;
|
||||
|
@ -354,10 +379,10 @@ Array<TYPE> imfilter::imfilter_separable( const Array<TYPE>& A, const std::vecto
|
|||
return B;
|
||||
}
|
||||
template <class TYPE>
|
||||
Array<TYPE> imfilter::imfilter_separable( const Array<TYPE>& A, const std::vector<int>& Nh,
|
||||
Array<TYPE> imfilter::imfilter_separable(
|
||||
const Array<TYPE> &A, const std::vector<int> &Nh,
|
||||
std::vector<std::function<TYPE(int, const TYPE *)>> H,
|
||||
const std::vector<imfilter::BC>& boundary, const TYPE X )
|
||||
{
|
||||
const std::vector<imfilter::BC> &boundary, const TYPE X) {
|
||||
PROFILE_START("imfilter_separable (function)");
|
||||
IMFILTER_ASSERT(A.ndim() == (int)boundary.size());
|
||||
auto B = A;
|
||||
|
@ -374,5 +399,3 @@ Array<TYPE> imfilter::imfilter_separable( const Array<TYPE>& A, const std::vecto
|
|||
PROFILE_STOP("imfilter_separable (function)");
|
||||
return B;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#include <analysis/morphology.h>
|
||||
// Implementation of morphological opening routine
|
||||
|
||||
inline void PackID(const int *list, int count, signed char *sendbuf, signed char *ID){
|
||||
inline void PackID(const int *list, int count, signed char *sendbuf,
|
||||
signed char *ID) {
|
||||
// Fill in the phase ID values from neighboring processors
|
||||
// This packs up the values that need to be sent from one processor to another
|
||||
int idx, n;
|
||||
|
@ -13,7 +14,8 @@ inline void PackID(const int *list, int count, signed char *sendbuf, signed char
|
|||
}
|
||||
//***************************************************************************************
|
||||
|
||||
inline void UnpackID(const int *list, int count, signed char *recvbuf, signed char *ID){
|
||||
inline void UnpackID(const int *list, int count, signed char *recvbuf,
|
||||
signed char *ID) {
|
||||
// Fill in the phase ID values from neighboring processors
|
||||
// This unpacks the values once they have been recieved from neighbors
|
||||
int idx, n;
|
||||
|
@ -30,9 +32,7 @@ Morphology::Morphology(){
|
|||
sendtag = recvtag = 1381;
|
||||
}
|
||||
|
||||
Morphology::~Morphology(){
|
||||
|
||||
}
|
||||
Morphology::~Morphology() {}
|
||||
|
||||
void Morphology::Initialize(std::shared_ptr<Domain> Dm, DoubleArray &Distance) {
|
||||
/* Loop over all faces and determine overlaps */
|
||||
|
@ -89,7 +89,8 @@ void Morphology::Initialize(std::shared_ptr <Domain> Dm, DoubleArray &Distance){
|
|||
morphRadius.resize(recvLoc);
|
||||
//..............................
|
||||
/* send the morphological radius */
|
||||
Dm->Comm.Irecv(&morphRadius[recvOffset_X],recvCount,Dm->rank_X(),recvtag+0);
|
||||
Dm->Comm.Irecv(&morphRadius[recvOffset_X], recvCount, Dm->rank_X(),
|
||||
recvtag + 0);
|
||||
Dm->Comm.send(&tmpDistance[0], sendCount, Dm->rank_x(), sendtag + 0);
|
||||
/* send the shift values */
|
||||
Dm->Comm.Irecv(&xShift[recvOffset_X], recvCount, Dm->rank_X(), recvtag + 1);
|
||||
|
@ -136,7 +137,8 @@ void Morphology::Initialize(std::shared_ptr <Domain> Dm, DoubleArray &Distance){
|
|||
morphRadius.resize(recvLoc);
|
||||
//..............................
|
||||
/* send the morphological radius */
|
||||
Dm->Comm.Irecv(&morphRadius[recvOffset_x],recvCount,Dm->rank_x(),recvtag+0);
|
||||
Dm->Comm.Irecv(&morphRadius[recvOffset_x], recvCount, Dm->rank_x(),
|
||||
recvtag + 0);
|
||||
Dm->Comm.send(&tmpDistance[0], sendCount, Dm->rank_X(), sendtag + 0);
|
||||
/* send the shift values */
|
||||
Dm->Comm.Irecv(&xShift[recvOffset_x], recvCount, Dm->rank_x(), recvtag + 1);
|
||||
|
@ -184,7 +186,8 @@ void Morphology::Initialize(std::shared_ptr <Domain> Dm, DoubleArray &Distance){
|
|||
morphRadius.resize(recvLoc);
|
||||
//..............................
|
||||
/* send the morphological radius */
|
||||
Dm->Comm.Irecv(&morphRadius[recvOffset_Y],recvCount,Dm->rank_Y(),recvtag+0);
|
||||
Dm->Comm.Irecv(&morphRadius[recvOffset_Y], recvCount, Dm->rank_Y(),
|
||||
recvtag + 0);
|
||||
Dm->Comm.send(&tmpDistance[0], sendCount, Dm->rank_y(), sendtag + 0);
|
||||
/* send the shift values */
|
||||
Dm->Comm.Irecv(&xShift[recvOffset_Y], recvCount, Dm->rank_Y(), recvtag + 1);
|
||||
|
@ -231,7 +234,8 @@ void Morphology::Initialize(std::shared_ptr <Domain> Dm, DoubleArray &Distance){
|
|||
morphRadius.resize(recvLoc);
|
||||
//..............................
|
||||
/* send the morphological radius */
|
||||
Dm->Comm.Irecv(&morphRadius[recvOffset_y],recvCount,Dm->rank_y(),recvtag+0);
|
||||
Dm->Comm.Irecv(&morphRadius[recvOffset_y], recvCount, Dm->rank_y(),
|
||||
recvtag + 0);
|
||||
Dm->Comm.send(&tmpDistance[0], sendCount, Dm->rank_Y(), sendtag + 0);
|
||||
/* send the shift values */
|
||||
Dm->Comm.Irecv(&xShift[recvOffset_y], recvCount, Dm->rank_y(), recvtag + 1);
|
||||
|
@ -279,7 +283,8 @@ void Morphology::Initialize(std::shared_ptr <Domain> Dm, DoubleArray &Distance){
|
|||
morphRadius.resize(recvLoc);
|
||||
//..............................
|
||||
/* send the morphological radius */
|
||||
Dm->Comm.Irecv(&morphRadius[recvOffset_Z],recvCount,Dm->rank_Z(),recvtag+0);
|
||||
Dm->Comm.Irecv(&morphRadius[recvOffset_Z], recvCount, Dm->rank_Z(),
|
||||
recvtag + 0);
|
||||
Dm->Comm.send(&tmpDistance[0], sendCount, Dm->rank_z(), sendtag + 0);
|
||||
/* send the shift values */
|
||||
Dm->Comm.Irecv(&xShift[recvOffset_Z], recvCount, Dm->rank_Z(), recvtag + 1);
|
||||
|
@ -325,7 +330,8 @@ void Morphology::Initialize(std::shared_ptr <Domain> Dm, DoubleArray &Distance){
|
|||
morphRadius.resize(recvLoc);
|
||||
//..............................
|
||||
/* send the morphological radius */
|
||||
Dm->Comm.Irecv(&morphRadius[recvOffset_z],recvCount,Dm->rank_z(),recvtag+0);
|
||||
Dm->Comm.Irecv(&morphRadius[recvOffset_z], recvCount, Dm->rank_z(),
|
||||
recvtag + 0);
|
||||
Dm->Comm.send(&tmpDistance[0], sendCount, Dm->rank_Z(), sendtag + 0);
|
||||
/* send the shift values */
|
||||
Dm->Comm.Irecv(&xShift[recvOffset_z], recvCount, Dm->rank_z(), recvtag + 1);
|
||||
|
@ -352,10 +358,11 @@ void Morphology::Initialize(std::shared_ptr <Domain> Dm, DoubleArray &Distance){
|
|||
printf(" offset %i for send (z) %i \n", sendOffset_z, sendCount_z);
|
||||
printf(" offset %i for send (Z) %i \n", sendOffset_Z, sendCount_Z);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
int Morphology::GetOverlaps(std::shared_ptr <Domain> Dm, signed char *id, const signed char ErodeLabel, const signed char NewLabel){
|
||||
int Morphology::GetOverlaps(std::shared_ptr<Domain> Dm, signed char *id,
|
||||
const signed char ErodeLabel,
|
||||
const signed char NewLabel) {
|
||||
|
||||
int Nx = Dm->Nx;
|
||||
int Ny = Dm->Ny;
|
||||
|
@ -369,28 +376,40 @@ int Morphology::GetOverlaps(std::shared_ptr <Domain> Dm, signed char *id, const
|
|||
localID[idx] = id[n];
|
||||
}
|
||||
//printf("send x -- offset: %i, count: %i \n",sendOffset_x,sendCount_x);
|
||||
Dm->Comm.Irecv(&nonlocalID[recvOffset_X],recvCount_X,Dm->rank_x(),recvtag+2);
|
||||
Dm->Comm.send(&localID[sendOffset_x],sendCount_x,Dm->rank_X(),sendtag+2);
|
||||
Dm->Comm.Irecv(&nonlocalID[recvOffset_X], recvCount_X, Dm->rank_x(),
|
||||
recvtag + 2);
|
||||
Dm->Comm.send(&localID[sendOffset_x], sendCount_x, Dm->rank_X(),
|
||||
sendtag + 2);
|
||||
|
||||
//printf("send X \n");
|
||||
Dm->Comm.Irecv(&nonlocalID[recvOffset_x],recvCount_x,Dm->rank_X(),recvtag+3);
|
||||
Dm->Comm.send(&localID[sendOffset_X],sendCount_X,Dm->rank_x(),sendtag+3);
|
||||
Dm->Comm.Irecv(&nonlocalID[recvOffset_x], recvCount_x, Dm->rank_X(),
|
||||
recvtag + 3);
|
||||
Dm->Comm.send(&localID[sendOffset_X], sendCount_X, Dm->rank_x(),
|
||||
sendtag + 3);
|
||||
|
||||
//printf("send y \n");
|
||||
Dm->Comm.Irecv(&nonlocalID[recvOffset_Y],recvCount_Y,Dm->rank_y(),recvtag+4);
|
||||
Dm->Comm.send(&localID[sendOffset_y],sendCount_y,Dm->rank_Y(),sendtag+4);
|
||||
Dm->Comm.Irecv(&nonlocalID[recvOffset_Y], recvCount_Y, Dm->rank_y(),
|
||||
recvtag + 4);
|
||||
Dm->Comm.send(&localID[sendOffset_y], sendCount_y, Dm->rank_Y(),
|
||||
sendtag + 4);
|
||||
|
||||
//printf("send Y \n");
|
||||
Dm->Comm.Irecv(&nonlocalID[recvOffset_y],recvCount_y,Dm->rank_Y(),recvtag+5);
|
||||
Dm->Comm.send(&localID[sendOffset_Y],sendCount_Y,Dm->rank_y(),sendtag+5);
|
||||
Dm->Comm.Irecv(&nonlocalID[recvOffset_y], recvCount_y, Dm->rank_Y(),
|
||||
recvtag + 5);
|
||||
Dm->Comm.send(&localID[sendOffset_Y], sendCount_Y, Dm->rank_y(),
|
||||
sendtag + 5);
|
||||
|
||||
//printf("send z \n");
|
||||
Dm->Comm.Irecv(&nonlocalID[recvOffset_Z],recvCount_Z,Dm->rank_z(),recvtag+6);
|
||||
Dm->Comm.send(&localID[sendOffset_z],sendCount_z,Dm->rank_Z(),sendtag+6);
|
||||
Dm->Comm.Irecv(&nonlocalID[recvOffset_Z], recvCount_Z, Dm->rank_z(),
|
||||
recvtag + 6);
|
||||
Dm->Comm.send(&localID[sendOffset_z], sendCount_z, Dm->rank_Z(),
|
||||
sendtag + 6);
|
||||
|
||||
//printf("send Z \n");
|
||||
Dm->Comm.Irecv(&nonlocalID[recvOffset_z],recvCount_z,Dm->rank_Z(),recvtag+7);
|
||||
Dm->Comm.send(&localID[sendOffset_Z],sendCount_Z,Dm->rank_z(),sendtag+7);
|
||||
Dm->Comm.Irecv(&nonlocalID[recvOffset_z], recvCount_z, Dm->rank_Z(),
|
||||
recvtag + 7);
|
||||
Dm->Comm.send(&localID[sendOffset_Z], sendCount_Z, Dm->rank_z(),
|
||||
sendtag + 7);
|
||||
|
||||
for (int idx = 0; idx < recvCount; idx++) {
|
||||
double radius = morphRadius[idx];
|
||||
|
@ -412,7 +431,9 @@ int Morphology::GetOverlaps(std::shared_ptr <Domain> Dm, signed char *id, const
|
|||
for (jj = jmin; jj < jmax; jj++) {
|
||||
for (ii = imin; ii < imax; ii++) {
|
||||
int nn = kk * Nx * Ny + jj * Nx + ii;
|
||||
double dsq = double((ii-i)*(ii-i)+(jj-j)*(jj-j)+(kk-k)*(kk-k));
|
||||
double dsq =
|
||||
double((ii - i) * (ii - i) + (jj - j) * (jj - j) +
|
||||
(kk - k) * (kk - k));
|
||||
if (id[nn] == ErodeLabel && dsq <= radius * radius) {
|
||||
LocalNumber += 1.0;
|
||||
id[nn] = NewLabel;
|
||||
|
@ -428,7 +449,9 @@ int Morphology::GetOverlaps(std::shared_ptr <Domain> Dm, signed char *id, const
|
|||
}
|
||||
|
||||
//***************************************************************************************
|
||||
double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain> Dm, double VoidFraction, signed char ErodeLabel, signed char NewLabel){
|
||||
double MorphOpen(DoubleArray &SignDist, signed char *id,
|
||||
std::shared_ptr<Domain> Dm, double VoidFraction,
|
||||
signed char ErodeLabel, signed char NewLabel) {
|
||||
// SignDist is the distance to the object that you want to constaing the morphological opening
|
||||
// VoidFraction is the the empty space where the object inst
|
||||
// id is a labeled map
|
||||
|
@ -453,7 +476,8 @@ double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain>
|
|||
for (int i = 1; i < nx - 1; i++) {
|
||||
n = k * nx * ny + j * nx + i;
|
||||
// extract maximum distance for critical radius
|
||||
if ( SignDist(i,j,k) > maxdist) maxdist=SignDist(i,j,k);
|
||||
if (SignDist(i, j, k) > maxdist)
|
||||
maxdist = SignDist(i, j, k);
|
||||
if (id[n] == ErodeLabel) {
|
||||
count += 1.0;
|
||||
//id[n] = 2;
|
||||
|
@ -469,10 +493,14 @@ double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain>
|
|||
// total Global is the number of nodes in the pore-space
|
||||
totalGlobal = Dm->Comm.sumReduce(count);
|
||||
maxdistGlobal = Dm->Comm.sumReduce(maxdist);
|
||||
double volume=double(nprocx*nprocy*nprocz)*double(nx-2)*double(ny-2)*double(nz-2);
|
||||
double volume = double(nprocx * nprocy * nprocz) * double(nx - 2) *
|
||||
double(ny - 2) * double(nz - 2);
|
||||
double volume_fraction = totalGlobal / volume;
|
||||
if (rank==0) printf("Volume fraction for morphological opening: %f \n",volume_fraction);
|
||||
if (rank==0) printf("Maximum pore size: %f \n",maxdistGlobal);
|
||||
if (rank == 0)
|
||||
printf("Volume fraction for morphological opening: %f \n",
|
||||
volume_fraction);
|
||||
if (rank == 0)
|
||||
printf("Maximum pore size: %f \n", maxdistGlobal);
|
||||
final_void_fraction = volume_fraction; //initialize
|
||||
|
||||
int ii, jj, kk;
|
||||
|
@ -496,8 +524,7 @@ double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain>
|
|||
|
||||
int numTry = 0;
|
||||
int maxTry = 100;
|
||||
while (void_fraction_new > VoidFraction && numTry < maxTry)
|
||||
{
|
||||
while (void_fraction_new > VoidFraction && numTry < maxTry) {
|
||||
numTry++;
|
||||
void_fraction_diff_old = void_fraction_diff_new;
|
||||
void_fraction_old = void_fraction_new;
|
||||
|
@ -507,7 +534,9 @@ double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain>
|
|||
numTry = maxTry;
|
||||
}
|
||||
int Window = round(Rcrit_new);
|
||||
if (Window == 0) Window = 1; // If Window = 0 at the begining, after the following process will have sw=1.0
|
||||
if (Window == 0)
|
||||
Window =
|
||||
1; // If Window = 0 at the begining, after the following process will have sw=1.0
|
||||
// and sw<Sw will be immediately broken
|
||||
double LocalNumber = 0.f;
|
||||
for (int k = 0; k < Nz; k++) {
|
||||
|
@ -526,15 +555,17 @@ double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain>
|
|||
for (jj = jmin; jj < jmax; jj++) {
|
||||
for (ii = imin; ii < imax; ii++) {
|
||||
int nn = kk * nx * ny + jj * nx + ii;
|
||||
double dsq = double((ii-i)*(ii-i)+(jj-j)*(jj-j)+(kk-k)*(kk-k));
|
||||
if (id[nn] == ErodeLabel && dsq <= Rcrit_new*Rcrit_new){
|
||||
double dsq = double((ii - i) * (ii - i) +
|
||||
(jj - j) * (jj - j) +
|
||||
(kk - k) * (kk - k));
|
||||
if (id[nn] == ErodeLabel &&
|
||||
dsq <= Rcrit_new * Rcrit_new) {
|
||||
LocalNumber += 1.0;
|
||||
id[nn] = NewLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// move on
|
||||
}
|
||||
|
@ -568,8 +599,7 @@ double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain>
|
|||
printf("Final void fraction =%f\n", void_fraction_new);
|
||||
printf("Final critical radius=%f\n", Rcrit_new);
|
||||
}
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
final_void_fraction = void_fraction_old;
|
||||
if (rank == 0) {
|
||||
printf("Final void fraction=%f\n", void_fraction_old);
|
||||
|
@ -579,9 +609,9 @@ double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain>
|
|||
return final_void_fraction;
|
||||
}
|
||||
|
||||
|
||||
//***************************************************************************************
|
||||
double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain> Dm, double VoidFraction){
|
||||
double MorphDrain(DoubleArray &SignDist, signed char *id,
|
||||
std::shared_ptr<Domain> Dm, double VoidFraction) {
|
||||
// SignDist is the distance to the object that you want to constaing the morphological opening
|
||||
// VoidFraction is the the empty space where the object inst
|
||||
// id is a labeled map
|
||||
|
@ -601,7 +631,8 @@ double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain
|
|||
DoubleArray phase(nx, ny, nz);
|
||||
IntArray phase_label(nx, ny, nz);
|
||||
Array<char> ID(nx, ny, nz);
|
||||
fillHalo<char> fillChar(Dm->Comm,Dm->rank_info,{nx-2,ny-2,nz-2},{1,1,1},0,1);
|
||||
fillHalo<char> fillChar(Dm->Comm, Dm->rank_info, {nx - 2, ny - 2, nz - 2},
|
||||
{1, 1, 1}, 0, 1);
|
||||
|
||||
Morphology Structure;
|
||||
Structure.Initialize(Dm, SignDist);
|
||||
|
@ -617,7 +648,8 @@ double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain
|
|||
for (int i = 1; i < nx - 1; i++) {
|
||||
n = k * nx * ny + j * nx + i;
|
||||
// extract maximum distance for critical radius
|
||||
if ( SignDist(i,j,k) > maxdist) maxdist=SignDist(i,j,k);
|
||||
if (SignDist(i, j, k) > maxdist)
|
||||
maxdist = SignDist(i, j, k);
|
||||
if (SignDist(i, j, k) > 0.0) {
|
||||
count += 1.0;
|
||||
id[n] = ErodeLabel;
|
||||
|
@ -632,10 +664,14 @@ double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain
|
|||
// total Global is the number of nodes in the pore-space
|
||||
totalGlobal = Dm->Comm.sumReduce(count);
|
||||
maxdistGlobal = Dm->Comm.sumReduce(maxdist);
|
||||
double volume=double(nprocx*nprocy*nprocz)*double(nx-2)*double(ny-2)*double(nz-2);
|
||||
double volume = double(nprocx * nprocy * nprocz) * double(nx - 2) *
|
||||
double(ny - 2) * double(nz - 2);
|
||||
double volume_fraction = totalGlobal / volume;
|
||||
if (rank==0) printf("Volume fraction for morphological opening: %f \n",volume_fraction);
|
||||
if (rank==0) printf("Maximum pore size: %f \n",maxdistGlobal);
|
||||
if (rank == 0)
|
||||
printf("Volume fraction for morphological opening: %f \n",
|
||||
volume_fraction);
|
||||
if (rank == 0)
|
||||
printf("Maximum pore size: %f \n", maxdistGlobal);
|
||||
|
||||
int ii, jj, kk;
|
||||
int imin, jmin, kmin, imax, jmax, kmax;
|
||||
|
@ -661,14 +697,15 @@ double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain
|
|||
FILE *DRAIN = fopen("morphdrain.csv", "w");
|
||||
fprintf(DRAIN, "sw radius\n");
|
||||
|
||||
while (void_fraction_new > VoidFraction && Rcrit_new > 0.5)
|
||||
{
|
||||
while (void_fraction_new > VoidFraction && Rcrit_new > 0.5) {
|
||||
void_fraction_diff_old = void_fraction_diff_new;
|
||||
void_fraction_old = void_fraction_new;
|
||||
Rcrit_old = Rcrit_new;
|
||||
Rcrit_new -= deltaR * Rcrit_old;
|
||||
int Window = round(Rcrit_new);
|
||||
if (Window == 0) Window = 1; // If Window = 0 at the begining, after the following process will have sw=1.0
|
||||
if (Window == 0)
|
||||
Window =
|
||||
1; // If Window = 0 at the begining, after the following process will have sw=1.0
|
||||
// and sw<Sw will be immediately broken
|
||||
double LocalNumber = 0.f;
|
||||
for (int k = 1; k < Nz - 1; k++) {
|
||||
|
@ -686,12 +723,17 @@ double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain
|
|||
for (kk = kmin; kk < kmax; kk++) {
|
||||
for (jj = jmin; jj < jmax; jj++) {
|
||||
for (ii = imin; ii < imax; ii++) {
|
||||
double dsq = double((ii-i)*(ii-i)+(jj-j)*(jj-j)+(kk-k)*(kk-k));
|
||||
if (ID(ii,jj,kk) == ErodeLabel && dsq <= (Rcrit_new+1)*(Rcrit_new+1)){
|
||||
double dsq = double((ii - i) * (ii - i) +
|
||||
(jj - j) * (jj - j) +
|
||||
(kk - k) * (kk - k));
|
||||
if (ID(ii, jj, kk) == ErodeLabel &&
|
||||
dsq <=
|
||||
(Rcrit_new + 1) * (Rcrit_new + 1)) {
|
||||
LocalNumber += 1.0;
|
||||
//id[nn]=1;
|
||||
ID(ii, jj, kk) = NewLabel;
|
||||
id[kk*Nx*Ny+jj*Nx+ii] = NewLabel;
|
||||
id[kk * Nx * Ny + jj * Nx + ii] =
|
||||
NewLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -718,16 +760,17 @@ double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain
|
|||
for (int i = 0; i < nx; i++) {
|
||||
if (ID(i, j, k) == NewLabel) {
|
||||
phase(i, j, k) = 1.0;
|
||||
}
|
||||
else
|
||||
} else
|
||||
phase(i, j, k) = -1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Extract only the connected part of NWP
|
||||
double vF=0.0; double vS=0.0;
|
||||
ComputeGlobalBlobIDs(nx-2,ny-2,nz-2,Dm->rank_info,phase,SignDist,vF,vS,phase_label,Dm->Comm);
|
||||
double vF = 0.0;
|
||||
double vS = 0.0;
|
||||
ComputeGlobalBlobIDs(nx - 2, ny - 2, nz - 2, Dm->rank_info, phase,
|
||||
SignDist, vF, vS, phase_label, Dm->Comm);
|
||||
Dm->Comm.barrier();
|
||||
|
||||
for (int k = 0; k < nz; k++) {
|
||||
|
@ -770,8 +813,7 @@ double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain
|
|||
printf("Final void fraction =%f\n", void_fraction_new);
|
||||
printf("Final critical radius=%f\n", Rcrit_new);
|
||||
}
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
final_void_fraction = void_fraction_old;
|
||||
if (rank == 0) {
|
||||
printf("Final void fraction=%f\n", void_fraction_old);
|
||||
|
@ -794,8 +836,9 @@ double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain
|
|||
}
|
||||
|
||||
//double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id, std::shared_ptr<Domain> Dm, double TargetGrowth)
|
||||
double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id, std::shared_ptr<Domain> Dm, double TargetGrowth, double WallFactor)
|
||||
{
|
||||
double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
|
||||
std::shared_ptr<Domain> Dm, double TargetGrowth,
|
||||
double WallFactor) {
|
||||
int Nx = Dm->Nx;
|
||||
int Ny = Dm->Ny;
|
||||
int Nz = Dm->Nz;
|
||||
|
@ -815,14 +858,17 @@ double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
|
|||
|
||||
// Estimate morph_delta
|
||||
double morph_delta = 0.0;
|
||||
if (TargetGrowth > 0.0) morph_delta = 0.1;
|
||||
else morph_delta = -0.1;
|
||||
if (TargetGrowth > 0.0)
|
||||
morph_delta = 0.1;
|
||||
else
|
||||
morph_delta = -0.1;
|
||||
double morph_delta_previous = 0.0;
|
||||
double GrowthEstimate = 0.0;
|
||||
double GrowthPrevious = 0.0;
|
||||
int COUNT_FOR_LOOP = 0;
|
||||
double ERROR = 100.0;
|
||||
if (rank == 0) printf("Estimate delta for growth=%f \n",TargetGrowth);
|
||||
if (rank == 0)
|
||||
printf("Estimate delta for growth=%f \n", TargetGrowth);
|
||||
while (ERROR > 0.01 && COUNT_FOR_LOOP < 10) {
|
||||
COUNT_FOR_LOOP++;
|
||||
count = 0.0;
|
||||
|
@ -832,9 +878,11 @@ double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
|
|||
for (int i = 1; i < Nx - 1; i++) {
|
||||
double walldist = BoundaryDist(i, j, k);
|
||||
//double wallweight = 1.0 / (1+exp(-5.f*(walldist-1.f)));
|
||||
double wallweight = WallFactor/ (1+exp(-5.f*(walldist-1.f)));
|
||||
double wallweight =
|
||||
WallFactor / (1 + exp(-5.f * (walldist - 1.f)));
|
||||
//wallweight = 1.0;
|
||||
if (fabs(wallweight*morph_delta) > MAX_DISPLACEMENT) MAX_DISPLACEMENT= fabs(wallweight*morph_delta);
|
||||
if (fabs(wallweight * morph_delta) > MAX_DISPLACEMENT)
|
||||
MAX_DISPLACEMENT = fabs(wallweight * morph_delta);
|
||||
|
||||
if (Dist(i, j, k) - wallweight * morph_delta < 0.0) {
|
||||
count += 1.0;
|
||||
|
@ -847,15 +895,20 @@ double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
|
|||
GrowthEstimate = count - count_original;
|
||||
ERROR = fabs((GrowthEstimate - TargetGrowth) / TargetGrowth);
|
||||
|
||||
if (rank == 0) printf(" delta=%f, growth=%f, max. displacement = %f \n",morph_delta, GrowthEstimate, MAX_DISPLACEMENT);
|
||||
if (rank == 0)
|
||||
printf(" delta=%f, growth=%f, max. displacement = %f \n",
|
||||
morph_delta, GrowthEstimate, MAX_DISPLACEMENT);
|
||||
// Now adjust morph_delta
|
||||
if (fabs(GrowthEstimate - GrowthPrevious) > 0.0) {
|
||||
double step_size = (TargetGrowth - GrowthEstimate)*(morph_delta - morph_delta_previous) / (GrowthEstimate - GrowthPrevious);
|
||||
double step_size = (TargetGrowth - GrowthEstimate) *
|
||||
(morph_delta - morph_delta_previous) /
|
||||
(GrowthEstimate - GrowthPrevious);
|
||||
GrowthPrevious = GrowthEstimate;
|
||||
morph_delta_previous = morph_delta;
|
||||
morph_delta += step_size;
|
||||
}
|
||||
if (morph_delta / morph_delta_previous > 2.0 ) morph_delta = morph_delta_previous*2.0;
|
||||
if (morph_delta / morph_delta_previous > 2.0)
|
||||
morph_delta = morph_delta_previous * 2.0;
|
||||
|
||||
//MAX_DISPLACEMENT *= max(TargetGrowth/GrowthEstimate,1.25);
|
||||
|
||||
|
@ -865,8 +918,7 @@ double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
|
|||
morph_delta = 3.0;
|
||||
COUNT_FOR_LOOP = 100; // exit loop if displacement is too large
|
||||
}
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
// object is shrinking
|
||||
if (MAX_DISPLACEMENT > 1.0) {
|
||||
morph_delta = -1.0;
|
||||
|
@ -874,7 +926,8 @@ double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
|
|||
}
|
||||
}
|
||||
}
|
||||
if (rank == 0) printf("Final delta=%f \n",morph_delta);
|
||||
if (rank == 0)
|
||||
printf("Final delta=%f \n", morph_delta);
|
||||
|
||||
count = 0.0;
|
||||
for (int k = 1; k < Nz - 1; k++) {
|
||||
|
@ -883,10 +936,12 @@ double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
|
|||
double walldist = BoundaryDist(i, j, k);
|
||||
//double wallweight = 1.0 / (1+exp(-5.f*(walldist-1.f)));
|
||||
//wallweight = 1.0;
|
||||
double wallweight = WallFactor / (1+exp(-5.f*(walldist-1.f)));
|
||||
double wallweight =
|
||||
WallFactor / (1 + exp(-5.f * (walldist - 1.f)));
|
||||
Dist(i, j, k) -= wallweight * morph_delta;
|
||||
|
||||
if (Dist(i,j,k) < 0.0) count+=1.0;
|
||||
if (Dist(i, j, k) < 0.0)
|
||||
count += 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -894,4 +949,3 @@ double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
|
|||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,9 +3,14 @@
|
|||
#include "common/Domain.h"
|
||||
#include "analysis/runAnalysis.h"
|
||||
|
||||
double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain> Dm, double VoidFraction, signed char ErodeLabel, signed char ReplaceLabel);
|
||||
double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain> Dm, double VoidFraction);
|
||||
double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id, std::shared_ptr<Domain> Dm, double TargetVol, double WallFactor);
|
||||
double MorphOpen(DoubleArray &SignDist, signed char *id,
|
||||
std::shared_ptr<Domain> Dm, double VoidFraction,
|
||||
signed char ErodeLabel, signed char ReplaceLabel);
|
||||
double MorphDrain(DoubleArray &SignDist, signed char *id,
|
||||
std::shared_ptr<Domain> Dm, double VoidFraction);
|
||||
double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
|
||||
std::shared_ptr<Domain> Dm, double TargetVol,
|
||||
double WallFactor);
|
||||
|
||||
#ifndef MORPHOLOGY_INC
|
||||
#define MORPHOLOGY_INC
|
||||
|
@ -41,7 +46,8 @@ public:
|
|||
* @param ErodeLabel label to erode based on morphological operation
|
||||
* @param NewLabel label to assign based on morphological operation
|
||||
*/
|
||||
int GetOverlaps(std::shared_ptr <Domain> Dm, signed char *id, const signed char ErodeLabel, const signed char NewLabel);
|
||||
int GetOverlaps(std::shared_ptr<Domain> Dm, signed char *id,
|
||||
const signed char ErodeLabel, const signed char NewLabel);
|
||||
|
||||
/*
|
||||
* data structures to store non-local morphological information
|
||||
|
@ -58,27 +64,39 @@ private:
|
|||
//......................................................................................
|
||||
int sendCount, recvCount;
|
||||
//......................................................................................
|
||||
int sendOffset_x, sendOffset_y, sendOffset_z, sendOffset_X, sendOffset_Y, sendOffset_Z;
|
||||
int sendOffset_xy, sendOffset_yz, sendOffset_xz, sendOffset_Xy, sendOffset_Yz, sendOffset_xZ;
|
||||
int sendOffset_xY, sendOffset_yZ, sendOffset_Xz, sendOffset_XY, sendOffset_YZ, sendOffset_XZ;
|
||||
int sendOffset_x, sendOffset_y, sendOffset_z, sendOffset_X, sendOffset_Y,
|
||||
sendOffset_Z;
|
||||
int sendOffset_xy, sendOffset_yz, sendOffset_xz, sendOffset_Xy,
|
||||
sendOffset_Yz, sendOffset_xZ;
|
||||
int sendOffset_xY, sendOffset_yZ, sendOffset_Xz, sendOffset_XY,
|
||||
sendOffset_YZ, sendOffset_XZ;
|
||||
int sendOffset_xyz, sendOffset_XYZ, sendOffset_xYz, sendOffset_XyZ;
|
||||
int sendOffset_Xyz, sendOffset_xYZ, sendOffset_xyZ, sendOffset_XYz;
|
||||
//......................................................................................
|
||||
int recvOffset_x, recvOffset_y, recvOffset_z, recvOffset_X, recvOffset_Y, recvOffset_Z;
|
||||
int recvOffset_xy, recvOffset_yz, recvOffset_xz, recvOffset_Xy, recvOffset_Yz, recvOffset_xZ;
|
||||
int recvOffset_xY, recvOffset_yZ, recvOffset_Xz, recvOffset_XY, recvOffset_YZ, recvOffset_XZ;
|
||||
int recvOffset_x, recvOffset_y, recvOffset_z, recvOffset_X, recvOffset_Y,
|
||||
recvOffset_Z;
|
||||
int recvOffset_xy, recvOffset_yz, recvOffset_xz, recvOffset_Xy,
|
||||
recvOffset_Yz, recvOffset_xZ;
|
||||
int recvOffset_xY, recvOffset_yZ, recvOffset_Xz, recvOffset_XY,
|
||||
recvOffset_YZ, recvOffset_XZ;
|
||||
int recvOffset_xyz, recvOffset_XYZ, recvOffset_xYz, recvOffset_XyZ;
|
||||
int recvOffset_Xyz, recvOffset_xYZ, recvOffset_xyZ, recvOffset_XYz;
|
||||
//......................................................................................
|
||||
int sendCount_x, sendCount_y, sendCount_z, sendCount_X, sendCount_Y, sendCount_Z;
|
||||
int sendCount_xy, sendCount_yz, sendCount_xz, sendCount_Xy, sendCount_Yz, sendCount_xZ;
|
||||
int sendCount_xY, sendCount_yZ, sendCount_Xz, sendCount_XY, sendCount_YZ, sendCount_XZ;
|
||||
int sendCount_x, sendCount_y, sendCount_z, sendCount_X, sendCount_Y,
|
||||
sendCount_Z;
|
||||
int sendCount_xy, sendCount_yz, sendCount_xz, sendCount_Xy, sendCount_Yz,
|
||||
sendCount_xZ;
|
||||
int sendCount_xY, sendCount_yZ, sendCount_Xz, sendCount_XY, sendCount_YZ,
|
||||
sendCount_XZ;
|
||||
int sendCount_xyz, sendCount_XYZ, sendCount_xYz, sendCount_XyZ;
|
||||
int sendCount_Xyz, sendCount_xYZ, sendCount_xyZ, sendCount_XYz;
|
||||
//......................................................................................
|
||||
int recvCount_x, recvCount_y, recvCount_z, recvCount_X, recvCount_Y, recvCount_Z;
|
||||
int recvCount_xy, recvCount_yz, recvCount_xz, recvCount_Xy, recvCount_Yz, recvCount_xZ;
|
||||
int recvCount_xY, recvCount_yZ, recvCount_Xz, recvCount_XY, recvCount_YZ, recvCount_XZ;
|
||||
int recvCount_x, recvCount_y, recvCount_z, recvCount_X, recvCount_Y,
|
||||
recvCount_Z;
|
||||
int recvCount_xy, recvCount_yz, recvCount_xz, recvCount_Xy, recvCount_Yz,
|
||||
recvCount_xZ;
|
||||
int recvCount_xY, recvCount_yZ, recvCount_Xz, recvCount_XY, recvCount_YZ,
|
||||
recvCount_XZ;
|
||||
int recvCount_xyz, recvCount_XYZ, recvCount_xYz, recvCount_XyZ;
|
||||
int recvCount_Xyz, recvCount_xYZ, recvCount_xyZ, recvCount_XYz;
|
||||
//......................................................................................
|
||||
|
@ -87,12 +105,18 @@ private:
|
|||
//......................................................................................
|
||||
|
||||
// Communication buffers
|
||||
signed char *sendID_x, *sendID_y, *sendID_z, *sendID_X, *sendID_Y, *sendID_Z;
|
||||
signed char *sendID_xy, *sendID_yz, *sendID_xz, *sendID_Xy, *sendID_Yz, *sendID_xZ;
|
||||
signed char *sendID_xY, *sendID_yZ, *sendID_Xz, *sendID_XY, *sendID_YZ, *sendID_XZ;
|
||||
signed char *recvID_x, *recvID_y, *recvID_z, *recvID_X, *recvID_Y, *recvID_Z;
|
||||
signed char *recvID_xy, *recvID_yz, *recvID_xz, *recvID_Xy, *recvID_Yz, *recvID_xZ;
|
||||
signed char *recvID_xY, *recvID_yZ, *recvID_Xz, *recvID_XY, *recvID_YZ, *recvID_XZ;
|
||||
signed char *sendID_x, *sendID_y, *sendID_z, *sendID_X, *sendID_Y,
|
||||
*sendID_Z;
|
||||
signed char *sendID_xy, *sendID_yz, *sendID_xz, *sendID_Xy, *sendID_Yz,
|
||||
*sendID_xZ;
|
||||
signed char *sendID_xY, *sendID_yZ, *sendID_Xz, *sendID_XY, *sendID_YZ,
|
||||
*sendID_XZ;
|
||||
signed char *recvID_x, *recvID_y, *recvID_z, *recvID_X, *recvID_Y,
|
||||
*recvID_Z;
|
||||
signed char *recvID_xy, *recvID_yz, *recvID_xz, *recvID_Xy, *recvID_Yz,
|
||||
*recvID_xZ;
|
||||
signed char *recvID_xY, *recvID_yZ, *recvID_Xz, *recvID_XY, *recvID_YZ,
|
||||
*recvID_XZ;
|
||||
};
|
||||
|
||||
#endif
|
1601
analysis/pmmc.h
1601
analysis/pmmc.h
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// Run the analysis, blob identification, and write restart files
|
||||
#include "analysis/runAnalysis.h"
|
||||
#include "analysis/analysis.h"
|
||||
|
@ -12,39 +28,32 @@
|
|||
|
||||
#include "ProfilerApp.h"
|
||||
|
||||
|
||||
AnalysisType &operator|=( AnalysisType &lhs, AnalysisType rhs )
|
||||
{
|
||||
lhs = static_cast<AnalysisType>( static_cast<std::underlying_type<AnalysisType>::type>( lhs ) |
|
||||
AnalysisType &operator|=(AnalysisType &lhs, AnalysisType rhs) {
|
||||
lhs = static_cast<AnalysisType>(
|
||||
static_cast<std::underlying_type<AnalysisType>::type>(lhs) |
|
||||
static_cast<std::underlying_type<AnalysisType>::type>(rhs));
|
||||
return lhs;
|
||||
}
|
||||
bool matches( AnalysisType x, AnalysisType y )
|
||||
{
|
||||
bool matches(AnalysisType x, AnalysisType y) {
|
||||
return (static_cast<std::underlying_type<AnalysisType>::type>(x) &
|
||||
static_cast<std::underlying_type<AnalysisType>::type>(y)) != 0;
|
||||
}
|
||||
|
||||
|
||||
// Create a shared_ptr to an array of values
|
||||
template <class TYPE>
|
||||
static inline std::shared_ptr<TYPE> make_shared_array( size_t N )
|
||||
{
|
||||
return std::shared_ptr<TYPE>( new TYPE[N], []( const TYPE *p ) { delete[] p; } );
|
||||
static inline std::shared_ptr<TYPE> make_shared_array(size_t N) {
|
||||
return std::shared_ptr<TYPE>(new TYPE[N],
|
||||
[](const TYPE *p) { delete[] p; });
|
||||
}
|
||||
|
||||
|
||||
// Helper class to write the restart file from a seperate thread
|
||||
class WriteRestartWorkItem : public ThreadPool::WorkItemRet<void>
|
||||
{
|
||||
class WriteRestartWorkItem : public ThreadPool::WorkItemRet<void> {
|
||||
public:
|
||||
WriteRestartWorkItem( const std::string &filename_, std::shared_ptr<double> cDen_,
|
||||
WriteRestartWorkItem(const std::string &filename_,
|
||||
std::shared_ptr<double> cDen_,
|
||||
std::shared_ptr<double> cfq_, int N_)
|
||||
: filename( filename_ ), cfq( cfq_ ), cDen( cDen_ ), N( N_ )
|
||||
{
|
||||
}
|
||||
virtual void run()
|
||||
{
|
||||
: filename(filename_), cfq(cfq_), cDen(cDen_), N(N_) {}
|
||||
virtual void run() {
|
||||
PROFILE_START("Save Checkpoint", 1);
|
||||
double value;
|
||||
ofstream File(filename, ios::binary);
|
||||
|
@ -73,42 +82,32 @@ private:
|
|||
const int N;
|
||||
};
|
||||
|
||||
|
||||
// Helper class to compute the blob ids
|
||||
typedef std::shared_ptr<std::pair<int, IntArray>> BlobIDstruct;
|
||||
typedef std::shared_ptr<std::vector<BlobIDType>> BlobIDList;
|
||||
static const std::string id_map_filename = "lbpm_id_map.txt";
|
||||
class BlobIdentificationWorkItem1 : public ThreadPool::WorkItemRet<void>
|
||||
{
|
||||
class BlobIdentificationWorkItem1 : public ThreadPool::WorkItemRet<void> {
|
||||
public:
|
||||
BlobIdentificationWorkItem1(int timestep_, int Nx_, int Ny_, int Nz_,
|
||||
const RankInfoStruct &rank_info_, std::shared_ptr<const DoubleArray> phase_,
|
||||
const DoubleArray &dist_, BlobIDstruct last_id_, BlobIDstruct new_index_,
|
||||
BlobIDstruct new_id_, BlobIDList new_list_, runAnalysis::commWrapper &&comm_ )
|
||||
: timestep( timestep_ ),
|
||||
Nx( Nx_ ),
|
||||
Ny( Ny_ ),
|
||||
Nz( Nz_ ),
|
||||
rank_info( rank_info_ ),
|
||||
phase( phase_ ),
|
||||
dist( dist_ ),
|
||||
last_id( last_id_ ),
|
||||
new_index( new_index_ ),
|
||||
new_id( new_id_ ),
|
||||
new_list( new_list_ ),
|
||||
comm( std::move( comm_ ) )
|
||||
{
|
||||
}
|
||||
const RankInfoStruct &rank_info_,
|
||||
std::shared_ptr<const DoubleArray> phase_,
|
||||
const DoubleArray &dist_, BlobIDstruct last_id_,
|
||||
BlobIDstruct new_index_, BlobIDstruct new_id_,
|
||||
BlobIDList new_list_,
|
||||
runAnalysis::commWrapper &&comm_)
|
||||
: timestep(timestep_), Nx(Nx_), Ny(Ny_), Nz(Nz_), rank_info(rank_info_),
|
||||
phase(phase_), dist(dist_), last_id(last_id_), new_index(new_index_),
|
||||
new_id(new_id_), new_list(new_list_), comm(std::move(comm_)) {}
|
||||
~BlobIdentificationWorkItem1() {}
|
||||
virtual void run()
|
||||
{
|
||||
virtual void run() {
|
||||
// Compute the global blob id and compare to the previous version
|
||||
PROFILE_START("Identify blobs", 1);
|
||||
double vF = 0.0;
|
||||
double vS = -1.0; // one voxel buffer region around solid
|
||||
IntArray &ids = new_index->second;
|
||||
new_index->first = ComputeGlobalBlobIDs(
|
||||
Nx - 2, Ny - 2, Nz - 2, rank_info, *phase, dist, vF, vS, ids, comm.comm );
|
||||
new_index->first =
|
||||
ComputeGlobalBlobIDs(Nx - 2, Ny - 2, Nz - 2, rank_info, *phase,
|
||||
dist, vF, vS, ids, comm.comm);
|
||||
PROFILE_STOP("Identify blobs", 1);
|
||||
}
|
||||
|
||||
|
@ -123,30 +122,20 @@ private:
|
|||
BlobIDList new_list;
|
||||
runAnalysis::commWrapper comm;
|
||||
};
|
||||
class BlobIdentificationWorkItem2 : public ThreadPool::WorkItemRet<void>
|
||||
{
|
||||
class BlobIdentificationWorkItem2 : public ThreadPool::WorkItemRet<void> {
|
||||
public:
|
||||
BlobIdentificationWorkItem2(int timestep_, int Nx_, int Ny_, int Nz_,
|
||||
const RankInfoStruct &rank_info_, std::shared_ptr<const DoubleArray> phase_,
|
||||
const DoubleArray &dist_, BlobIDstruct last_id_, BlobIDstruct new_index_,
|
||||
BlobIDstruct new_id_, BlobIDList new_list_, runAnalysis::commWrapper &&comm_ )
|
||||
: timestep( timestep_ ),
|
||||
Nx( Nx_ ),
|
||||
Ny( Ny_ ),
|
||||
Nz( Nz_ ),
|
||||
rank_info( rank_info_ ),
|
||||
phase( phase_ ),
|
||||
dist( dist_ ),
|
||||
last_id( last_id_ ),
|
||||
new_index( new_index_ ),
|
||||
new_id( new_id_ ),
|
||||
new_list( new_list_ ),
|
||||
comm( std::move( comm_ ) )
|
||||
{
|
||||
}
|
||||
const RankInfoStruct &rank_info_,
|
||||
std::shared_ptr<const DoubleArray> phase_,
|
||||
const DoubleArray &dist_, BlobIDstruct last_id_,
|
||||
BlobIDstruct new_index_, BlobIDstruct new_id_,
|
||||
BlobIDList new_list_,
|
||||
runAnalysis::commWrapper &&comm_)
|
||||
: timestep(timestep_), Nx(Nx_), Ny(Ny_), Nz(Nz_), rank_info(rank_info_),
|
||||
phase(phase_), dist(dist_), last_id(last_id_), new_index(new_index_),
|
||||
new_id(new_id_), new_list(new_list_), comm(std::move(comm_)) {}
|
||||
~BlobIdentificationWorkItem2() {}
|
||||
virtual void run()
|
||||
{
|
||||
virtual void run() {
|
||||
// Compute the global blob id and compare to the previous version
|
||||
PROFILE_START("Identify blobs maps", 1);
|
||||
const IntArray &ids = new_index->second;
|
||||
|
@ -156,7 +145,8 @@ public:
|
|||
if (last_id.get() != NULL) {
|
||||
// Compute the timestep-timestep map
|
||||
const IntArray &old_ids = last_id->second;
|
||||
ID_map_struct map = computeIDMap( Nx, Ny, Nz, old_ids, ids, comm.comm );
|
||||
ID_map_struct map =
|
||||
computeIDMap(Nx, Ny, Nz, old_ids, ids, comm.comm);
|
||||
// Renumber the current timestep's ids
|
||||
getNewIDs(map, max_id, *new_list);
|
||||
renumberIDs(*new_list, new_id->second);
|
||||
|
@ -182,25 +172,18 @@ private:
|
|||
runAnalysis::commWrapper comm;
|
||||
};
|
||||
|
||||
|
||||
// Helper class to write the vis file from a thread
|
||||
class WriteVisWorkItem : public ThreadPool::WorkItemRet<void>
|
||||
{
|
||||
class WriteVisWorkItem : public ThreadPool::WorkItemRet<void> {
|
||||
public:
|
||||
WriteVisWorkItem(int timestep_, std::vector<IO::MeshDataStruct> &visData_,
|
||||
TwoPhase &Avgerages_, std::array<int, 3> n_, RankInfoStruct rank_info_,
|
||||
TwoPhase &Avgerages_, std::array<int, 3> n_,
|
||||
RankInfoStruct rank_info_,
|
||||
runAnalysis::commWrapper &&comm_)
|
||||
: timestep( timestep_ ),
|
||||
visData( visData_ ),
|
||||
Averages( Avgerages_ ),
|
||||
n( std::move( n_ ) ),
|
||||
rank_info( std::move( rank_info_ ) ),
|
||||
comm( std::move( comm_ ) )
|
||||
{
|
||||
}
|
||||
: timestep(timestep_), visData(visData_), Averages(Avgerages_),
|
||||
n(std::move(n_)), rank_info(std::move(rank_info_)),
|
||||
comm(std::move(comm_)) {}
|
||||
~WriteVisWorkItem() {}
|
||||
virtual void run()
|
||||
{
|
||||
virtual void run() {
|
||||
PROFILE_START("Save Vis", 1);
|
||||
|
||||
fillHalo<double> fillData(comm.comm, rank_info, n, {1, 1, 1}, 0, 1);
|
||||
|
@ -246,24 +229,17 @@ private:
|
|||
};
|
||||
|
||||
// Helper class to write the vis file from a thread
|
||||
class IOWorkItem : public ThreadPool::WorkItemRet<void>
|
||||
{
|
||||
class IOWorkItem : public ThreadPool::WorkItemRet<void> {
|
||||
public:
|
||||
IOWorkItem(int timestep_, std::shared_ptr<Database> input_db_,
|
||||
std::vector<IO::MeshDataStruct> &visData_, SubPhase &Averages_, std::array<int, 3> n_,
|
||||
RankInfoStruct rank_info_, runAnalysis::commWrapper &&comm_ )
|
||||
: timestep( timestep_ ),
|
||||
input_db( input_db_ ),
|
||||
visData( visData_ ),
|
||||
Averages( Averages_ ),
|
||||
n( std::move( n_ ) ),
|
||||
rank_info( std::move( rank_info_ ) ),
|
||||
comm( std::move( comm_ ) )
|
||||
{
|
||||
}
|
||||
std::vector<IO::MeshDataStruct> &visData_, SubPhase &Averages_,
|
||||
std::array<int, 3> n_, RankInfoStruct rank_info_,
|
||||
runAnalysis::commWrapper &&comm_)
|
||||
: timestep(timestep_), input_db(input_db_), visData(visData_),
|
||||
Averages(Averages_), n(std::move(n_)),
|
||||
rank_info(std::move(rank_info_)), comm(std::move(comm_)) {}
|
||||
~IOWorkItem() {}
|
||||
virtual void run()
|
||||
{
|
||||
virtual void run() {
|
||||
PROFILE_START("Save Vis", 1);
|
||||
|
||||
auto color_db = input_db->getDatabase("Color");
|
||||
|
@ -337,25 +313,16 @@ private:
|
|||
runAnalysis::commWrapper comm;
|
||||
};
|
||||
|
||||
|
||||
// Helper class to run the analysis from within a thread
|
||||
// Note: Averages will be modified after the constructor is called
|
||||
class AnalysisWorkItem : public ThreadPool::WorkItemRet<void>
|
||||
{
|
||||
class AnalysisWorkItem : public ThreadPool::WorkItemRet<void> {
|
||||
public:
|
||||
AnalysisWorkItem( AnalysisType type_, int timestep_, TwoPhase &Averages_, BlobIDstruct ids,
|
||||
BlobIDList id_list_, double beta_ )
|
||||
: type( type_ ),
|
||||
timestep( timestep_ ),
|
||||
Averages( Averages_ ),
|
||||
blob_ids( ids ),
|
||||
id_list( id_list_ ),
|
||||
beta( beta_ )
|
||||
{
|
||||
}
|
||||
AnalysisWorkItem(AnalysisType type_, int timestep_, TwoPhase &Averages_,
|
||||
BlobIDstruct ids, BlobIDList id_list_, double beta_)
|
||||
: type(type_), timestep(timestep_), Averages(Averages_), blob_ids(ids),
|
||||
id_list(id_list_), beta(beta_) {}
|
||||
~AnalysisWorkItem() {}
|
||||
virtual void run()
|
||||
{
|
||||
virtual void run() {
|
||||
Averages.NumberComponents_NWP = blob_ids->first;
|
||||
Averages.Label_NWP = blob_ids->second;
|
||||
Averages.Label_NWP_map = *id_list;
|
||||
|
@ -369,8 +336,10 @@ public:
|
|||
Averages.Initialize();
|
||||
Averages.ComputeDelPhi();
|
||||
Averages.ColorToSignedDistance(beta, Averages.Phase, Averages.SDn);
|
||||
Averages.ColorToSignedDistance( beta, Averages.Phase_tminus, Averages.Phase_tminus );
|
||||
Averages.ColorToSignedDistance( beta, Averages.Phase_tplus, Averages.Phase_tplus );
|
||||
Averages.ColorToSignedDistance(beta, Averages.Phase_tminus,
|
||||
Averages.Phase_tminus);
|
||||
Averages.ColorToSignedDistance(beta, Averages.Phase_tplus,
|
||||
Averages.Phase_tplus);
|
||||
Averages.UpdateMeshValues();
|
||||
Averages.ComputeLocal();
|
||||
Averages.Reduce();
|
||||
|
@ -393,23 +362,14 @@ private:
|
|||
double beta;
|
||||
};
|
||||
|
||||
|
||||
class TCATWorkItem : public ThreadPool::WorkItemRet<void>
|
||||
{
|
||||
class TCATWorkItem : public ThreadPool::WorkItemRet<void> {
|
||||
public:
|
||||
TCATWorkItem( AnalysisType type_, int timestep_, TwoPhase &Averages_, BlobIDstruct ids,
|
||||
BlobIDList id_list_, double beta_ )
|
||||
: type( type_ ),
|
||||
timestep( timestep_ ),
|
||||
Averages( Averages_ ),
|
||||
blob_ids( ids ),
|
||||
id_list( id_list_ ),
|
||||
beta( beta_ )
|
||||
{
|
||||
}
|
||||
TCATWorkItem(AnalysisType type_, int timestep_, TwoPhase &Averages_,
|
||||
BlobIDstruct ids, BlobIDList id_list_, double beta_)
|
||||
: type(type_), timestep(timestep_), Averages(Averages_), blob_ids(ids),
|
||||
id_list(id_list_), beta(beta_) {}
|
||||
~TCATWorkItem() {}
|
||||
virtual void run()
|
||||
{
|
||||
virtual void run() {
|
||||
Averages.NumberComponents_NWP = blob_ids->first;
|
||||
Averages.Label_NWP = blob_ids->second;
|
||||
Averages.Label_NWP_map = *id_list;
|
||||
|
@ -423,8 +383,10 @@ public:
|
|||
Averages.Initialize();
|
||||
Averages.ComputeDelPhi();
|
||||
Averages.ColorToSignedDistance(beta, Averages.Phase, Averages.SDn);
|
||||
Averages.ColorToSignedDistance( beta, Averages.Phase_tminus, Averages.Phase_tminus );
|
||||
Averages.ColorToSignedDistance( beta, Averages.Phase_tplus, Averages.Phase_tplus );
|
||||
Averages.ColorToSignedDistance(beta, Averages.Phase_tminus,
|
||||
Averages.Phase_tminus);
|
||||
Averages.ColorToSignedDistance(beta, Averages.Phase_tplus,
|
||||
Averages.Phase_tplus);
|
||||
Averages.UpdateMeshValues();
|
||||
Averages.ComputeLocal();
|
||||
Averages.Reduce();
|
||||
|
@ -443,23 +405,15 @@ private:
|
|||
double beta;
|
||||
};
|
||||
|
||||
|
||||
class GanglionTrackingWorkItem : public ThreadPool::WorkItemRet<void>
|
||||
{
|
||||
class GanglionTrackingWorkItem : public ThreadPool::WorkItemRet<void> {
|
||||
public:
|
||||
GanglionTrackingWorkItem( AnalysisType type_, int timestep_, TwoPhase &Averages_,
|
||||
BlobIDstruct ids, BlobIDList id_list_, double beta_ )
|
||||
: type( type_ ),
|
||||
timestep( timestep_ ),
|
||||
Averages( Averages_ ),
|
||||
blob_ids( ids ),
|
||||
id_list( id_list_ ),
|
||||
beta( beta_ )
|
||||
{
|
||||
}
|
||||
GanglionTrackingWorkItem(AnalysisType type_, int timestep_,
|
||||
TwoPhase &Averages_, BlobIDstruct ids,
|
||||
BlobIDList id_list_, double beta_)
|
||||
: type(type_), timestep(timestep_), Averages(Averages_), blob_ids(ids),
|
||||
id_list(id_list_), beta(beta_) {}
|
||||
~GanglionTrackingWorkItem() {}
|
||||
virtual void run()
|
||||
{
|
||||
virtual void run() {
|
||||
Averages.NumberComponents_NWP = blob_ids->first;
|
||||
Averages.Label_NWP = blob_ids->second;
|
||||
Averages.Label_NWP_map = *id_list;
|
||||
|
@ -473,8 +427,10 @@ public:
|
|||
Averages.Initialize();
|
||||
Averages.ComputeDelPhi();
|
||||
Averages.ColorToSignedDistance(beta, Averages.Phase, Averages.SDn);
|
||||
Averages.ColorToSignedDistance( beta, Averages.Phase_tminus, Averages.Phase_tminus );
|
||||
Averages.ColorToSignedDistance( beta, Averages.Phase_tplus, Averages.Phase_tplus );
|
||||
Averages.ColorToSignedDistance(beta, Averages.Phase_tminus,
|
||||
Averages.Phase_tminus);
|
||||
Averages.ColorToSignedDistance(beta, Averages.Phase_tplus,
|
||||
Averages.Phase_tplus);
|
||||
Averages.UpdateMeshValues();
|
||||
Averages.ComponentAverages();
|
||||
Averages.SortBlobs();
|
||||
|
@ -493,17 +449,12 @@ private:
|
|||
double beta;
|
||||
};
|
||||
|
||||
|
||||
class BasicWorkItem : public ThreadPool::WorkItemRet<void>
|
||||
{
|
||||
class BasicWorkItem : public ThreadPool::WorkItemRet<void> {
|
||||
public:
|
||||
BasicWorkItem(AnalysisType type_, int timestep_, SubPhase &Averages_)
|
||||
: type( type_ ), timestep( timestep_ ), Averages( Averages_ )
|
||||
{
|
||||
}
|
||||
: type(type_), timestep(timestep_), Averages(Averages_) {}
|
||||
~BasicWorkItem() {}
|
||||
virtual void run()
|
||||
{
|
||||
virtual void run() {
|
||||
|
||||
if (matches(type, AnalysisType::CopyPhaseIndicator)) {
|
||||
// Averages.ColorToSignedDistance(beta,Averages.Phase,Averages.Phase_tplus);
|
||||
|
@ -523,16 +474,12 @@ private:
|
|||
double beta;
|
||||
};
|
||||
|
||||
class SubphaseWorkItem : public ThreadPool::WorkItemRet<void>
|
||||
{
|
||||
class SubphaseWorkItem : public ThreadPool::WorkItemRet<void> {
|
||||
public:
|
||||
SubphaseWorkItem(AnalysisType type_, int timestep_, SubPhase &Averages_)
|
||||
: type( type_ ), timestep( timestep_ ), Averages( Averages_ )
|
||||
{
|
||||
}
|
||||
: type(type_), timestep(timestep_), Averages(Averages_) {}
|
||||
~SubphaseWorkItem() {}
|
||||
virtual void run()
|
||||
{
|
||||
virtual void run() {
|
||||
|
||||
PROFILE_START("Compute subphase", 1);
|
||||
Averages.Full();
|
||||
|
@ -548,29 +495,23 @@ private:
|
|||
double beta;
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* MPI comm wrapper for use with analysis *
|
||||
******************************************************************/
|
||||
runAnalysis::commWrapper::commWrapper(
|
||||
int tag_, const Utilities::MPI &comm_, runAnalysis *analysis_ )
|
||||
: comm( comm_ ), tag( tag_ ), analysis( analysis_ )
|
||||
{
|
||||
}
|
||||
runAnalysis::commWrapper::commWrapper(int tag_, const Utilities::MPI &comm_,
|
||||
runAnalysis *analysis_)
|
||||
: comm(comm_), tag(tag_), analysis(analysis_) {}
|
||||
runAnalysis::commWrapper::commWrapper(commWrapper &&rhs)
|
||||
: comm( rhs.comm ), tag( rhs.tag ), analysis( rhs.analysis )
|
||||
{
|
||||
: comm(rhs.comm), tag(rhs.tag), analysis(rhs.analysis) {
|
||||
rhs.tag = -1;
|
||||
}
|
||||
runAnalysis::commWrapper::~commWrapper()
|
||||
{
|
||||
runAnalysis::commWrapper::~commWrapper() {
|
||||
if (tag == -1)
|
||||
return;
|
||||
comm.barrier();
|
||||
analysis->d_comm_used[tag] = false;
|
||||
}
|
||||
runAnalysis::commWrapper runAnalysis::getComm()
|
||||
{
|
||||
runAnalysis::commWrapper runAnalysis::getComm() {
|
||||
// Get a tag from root
|
||||
int tag = -1;
|
||||
if (d_rank == 0) {
|
||||
|
@ -590,24 +531,23 @@ runAnalysis::commWrapper runAnalysis::getComm()
|
|||
return commWrapper(tag, d_comms[tag], this);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* Constructor/Destructors *
|
||||
******************************************************************/
|
||||
runAnalysis::runAnalysis( std::shared_ptr<Database> input_db, const RankInfoStruct &rank_info,
|
||||
std::shared_ptr<ScaLBL_Communicator> ScaLBL_Comm, std::shared_ptr<Domain> Dm, int Np,
|
||||
bool Regular, IntArray Map )
|
||||
: d_Np( Np ),
|
||||
d_regular( Regular ),
|
||||
d_rank_info( rank_info ),
|
||||
d_Map( Map ),
|
||||
d_comm( Dm->Comm.dup() ),
|
||||
d_ScaLBL_Comm( ScaLBL_Comm )
|
||||
{
|
||||
runAnalysis::runAnalysis(std::shared_ptr<Database> input_db,
|
||||
const RankInfoStruct &rank_info,
|
||||
std::shared_ptr<ScaLBL_Communicator> ScaLBL_Comm,
|
||||
std::shared_ptr<Domain> Dm, int Np, bool Regular,
|
||||
IntArray Map)
|
||||
: d_Np(Np), d_regular(Regular), d_rank_info(rank_info), d_Map(Map),
|
||||
d_comm(Dm->Comm.dup()), d_ScaLBL_Comm(ScaLBL_Comm) {
|
||||
|
||||
auto db = input_db->getDatabase("Analysis");
|
||||
auto vis_db = input_db->getDatabase("Visualization");
|
||||
|
||||
/* set the I/O format */
|
||||
format = vis_db->getWithDefault<string>("format", "silo");
|
||||
|
||||
// Ids of work items to use for dependencies
|
||||
ThreadPool::thread_id_t d_wait_blobID;
|
||||
ThreadPool::thread_id_t d_wait_analysis;
|
||||
|
@ -636,17 +576,22 @@ runAnalysis::runAnalysis( std::shared_ptr<Database> input_db, const RankInfoStru
|
|||
d_visualization_interval = db->getScalar<int>("visualization_interval");
|
||||
}
|
||||
if (db->keyExists("subphase_analysis_interval")) {
|
||||
d_subphase_analysis_interval = db->getScalar<int>( "subphase_analysis_interval" );
|
||||
d_subphase_analysis_interval =
|
||||
db->getScalar<int>("subphase_analysis_interval");
|
||||
}
|
||||
|
||||
auto restart_file = db->getWithDefault<std::string>( "restart_file", "Restart");
|
||||
auto restart_file =
|
||||
db->getWithDefault<std::string>("restart_file", "Restart");
|
||||
d_restartFile = restart_file + "." + rankString;
|
||||
|
||||
|
||||
d_rank = d_comm.getRank();
|
||||
writeIDMap(ID_map_struct(), 0, id_map_filename);
|
||||
|
||||
// Initialize IO for silo
|
||||
IO::initialize( "", "silo", "false" );
|
||||
//std::string format = "silo";
|
||||
format = vis_db->getWithDefault<string>("format", "silo");
|
||||
|
||||
IO::initialize("", format, "false");
|
||||
// Create the MeshDataStruct
|
||||
d_meshData.resize(1);
|
||||
|
||||
|
@ -720,7 +665,6 @@ runAnalysis::runAnalysis( std::shared_ptr<Database> input_db, const RankInfoStru
|
|||
d_meshData[0].vars.push_back(BlobIDVar);
|
||||
}
|
||||
|
||||
|
||||
// Initialize the comms
|
||||
for (int i = 0; i < 1024; i++)
|
||||
d_comm_used[i] = false;
|
||||
|
@ -777,22 +721,29 @@ runAnalysis::runAnalysis( ScaLBL_ColorModel &ColorModel)
|
|||
d_visualization_interval = db->getScalar<int>("visualization_interval");
|
||||
}
|
||||
if (db->keyExists("subphase_analysis_interval")) {
|
||||
d_subphase_analysis_interval = db->getScalar<int>( "subphase_analysis_interval" );
|
||||
d_subphase_analysis_interval =
|
||||
db->getScalar<int>("subphase_analysis_interval");
|
||||
}
|
||||
|
||||
auto restart_file = db->getWithDefault<std::string>( "restart_file", "Restart");
|
||||
auto restart_file =
|
||||
db->getWithDefault<std::string>("restart_file", "Restart");
|
||||
d_restartFile = restart_file + "." + rankString;
|
||||
|
||||
d_rank = d_comm.getRank();
|
||||
writeIDMap(ID_map_struct(), 0, id_map_filename);
|
||||
// Initialize IO for silo
|
||||
IO::initialize( "", "silo", "false" );
|
||||
//std::string format = "silo";
|
||||
|
||||
format = vis_db->getWithDefault<string>("format", "silo");
|
||||
|
||||
IO::initialize("", format, "false");
|
||||
// Create the MeshDataStruct
|
||||
d_meshData.resize(1);
|
||||
|
||||
d_meshData[0].meshName = "domain";
|
||||
d_meshData[0].mesh = std::make_shared<IO::DomainMesh>(
|
||||
d_rank_info, d_n[0], d_n[1], d_n[2], ColorModel.Dm->Lx, ColorModel.Dm->Ly, ColorModel.Dm->Lz );
|
||||
d_rank_info, d_n[0], d_n[1], d_n[2], ColorModel.Dm->Lx,
|
||||
ColorModel.Dm->Ly, ColorModel.Dm->Lz);
|
||||
auto PhaseVar = std::make_shared<IO::Variable>();
|
||||
auto PressVar = std::make_shared<IO::Variable>();
|
||||
auto VxVar = std::make_shared<IO::Variable>();
|
||||
|
@ -851,7 +802,6 @@ runAnalysis::runAnalysis( ScaLBL_ColorModel &ColorModel)
|
|||
d_meshData[0].vars.push_back(BlobIDVar);
|
||||
}
|
||||
|
||||
|
||||
// Initialize the comms
|
||||
for (int i = 0; i < 1024; i++)
|
||||
d_comm_used[i] = false;
|
||||
|
@ -860,13 +810,11 @@ runAnalysis::runAnalysis( ScaLBL_ColorModel &ColorModel)
|
|||
auto method = db->getWithDefault<std::string>("load_balance", "default");
|
||||
createThreads(method, N_threads);
|
||||
}
|
||||
runAnalysis::~runAnalysis()
|
||||
{
|
||||
runAnalysis::~runAnalysis() {
|
||||
// Finish processing analysis
|
||||
finish();
|
||||
}
|
||||
void runAnalysis::finish()
|
||||
{
|
||||
void runAnalysis::finish() {
|
||||
PROFILE_START("finish");
|
||||
// Wait for the work items to finish
|
||||
d_tpool.wait_pool_finished();
|
||||
|
@ -881,12 +829,10 @@ void runAnalysis::finish()
|
|||
PROFILE_STOP("finish");
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* Set the thread affinities *
|
||||
******************************************************************/
|
||||
void print( const std::vector<int> &ids )
|
||||
{
|
||||
void print(const std::vector<int> &ids) {
|
||||
if (ids.empty())
|
||||
return;
|
||||
printf("%i", ids[0]);
|
||||
|
@ -894,16 +840,16 @@ void print( const std::vector<int> &ids )
|
|||
printf(", %i", ids[i]);
|
||||
printf("\n");
|
||||
}
|
||||
void runAnalysis::createThreads( const std::string &method, int N_threads )
|
||||
{
|
||||
void runAnalysis::createThreads(const std::string &method, int N_threads) {
|
||||
// Check if we are not using analysis threads
|
||||
if (method == "none")
|
||||
return;
|
||||
// Check if we have thread support
|
||||
auto thread_support = Utilities::MPI::queryThreadSupport();
|
||||
if ( thread_support != Utilities::MPI::ThreadSupport::MULTIPLE && N_threads > 0 )
|
||||
std::cerr
|
||||
<< "Warning: Failed to start MPI with necessary thread support, errors may occur\n";
|
||||
if (thread_support != Utilities::MPI::ThreadSupport::MULTIPLE &&
|
||||
N_threads > 0)
|
||||
std::cerr << "Warning: Failed to start MPI with necessary thread "
|
||||
"support, errors may occur\n";
|
||||
// Create the threads
|
||||
const auto cores = d_tpool.getProcessAffinity();
|
||||
if (N_threads == 0) {
|
||||
|
@ -934,12 +880,10 @@ void runAnalysis::createThreads( const std::string &method, int N_threads )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* Check which analysis we want to perform *
|
||||
******************************************************************/
|
||||
AnalysisType runAnalysis::computeAnalysisType( int timestep )
|
||||
{
|
||||
AnalysisType runAnalysis::computeAnalysisType(int timestep) {
|
||||
AnalysisType type = AnalysisType::AnalyzeNone;
|
||||
if (timestep % d_analysis_interval + 8 == d_analysis_interval) {
|
||||
// Copy the phase indicator field for the earlier timestep
|
||||
|
@ -982,13 +926,12 @@ AnalysisType runAnalysis::computeAnalysisType( int timestep )
|
|||
return type;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* Run the analysis *
|
||||
******************************************************************/
|
||||
void runAnalysis::run( int timestep, std::shared_ptr<Database> input_db, TwoPhase &Averages,
|
||||
const double *Phi, double *Pressure, double *Velocity, double *fq, double *Den )
|
||||
{
|
||||
void runAnalysis::run(int timestep, std::shared_ptr<Database> input_db,
|
||||
TwoPhase &Averages, const double *Phi, double *Pressure,
|
||||
double *Velocity, double *fq, double *Den) {
|
||||
int N = d_N[0] * d_N[1] * d_N[2];
|
||||
NULL_USE(N);
|
||||
NULL_USE(Phi);
|
||||
|
@ -1049,14 +992,16 @@ void runAnalysis::run( int timestep, std::shared_ptr<Database> input_db, TwoPhas
|
|||
if (d_regular)
|
||||
d_ScaLBL_Comm->RegularLayout(d_Map, Phi, Averages.Phase_tplus);
|
||||
else
|
||||
ScaLBL_CopyToHost( Averages.Phase_tplus.data(), Phi, N * sizeof( double ) );
|
||||
ScaLBL_CopyToHost(Averages.Phase_tplus.data(), Phi,
|
||||
N * sizeof(double));
|
||||
// memcpy(Averages.Phase_tplus.data(),phase->data(),N*sizeof(double));
|
||||
}
|
||||
if (timestep % d_analysis_interval == 0) {
|
||||
if (d_regular)
|
||||
d_ScaLBL_Comm->RegularLayout(d_Map, Phi, Averages.Phase_tminus);
|
||||
else
|
||||
ScaLBL_CopyToHost( Averages.Phase_tminus.data(), Phi, N * sizeof( double ) );
|
||||
ScaLBL_CopyToHost(Averages.Phase_tminus.data(), Phi,
|
||||
N * sizeof(double));
|
||||
// memcpy(Averages.Phase_tminus.data(),phase->data(),N*sizeof(double));
|
||||
}
|
||||
// if ( matches(type,AnalysisType::CopySimState) ) {
|
||||
|
@ -1079,7 +1024,8 @@ void runAnalysis::run( int timestep, std::shared_ptr<Database> input_db, TwoPhas
|
|||
d_ScaLBL_Comm->RegularLayout(d_Map, Pressure, Averages.Press);
|
||||
d_ScaLBL_Comm->RegularLayout(d_Map, &Velocity[0], Averages.Vel_x);
|
||||
d_ScaLBL_Comm->RegularLayout(d_Map, &Velocity[d_Np], Averages.Vel_y);
|
||||
d_ScaLBL_Comm->RegularLayout( d_Map, &Velocity[2 * d_Np], Averages.Vel_z );
|
||||
d_ScaLBL_Comm->RegularLayout(d_Map, &Velocity[2 * d_Np],
|
||||
Averages.Vel_z);
|
||||
PROFILE_STOP("Copy-State", 1);
|
||||
}
|
||||
std::shared_ptr<double> cfq, cDen;
|
||||
|
@ -1101,13 +1047,17 @@ void runAnalysis::run( int timestep, std::shared_ptr<Database> input_db, TwoPhas
|
|||
else
|
||||
ScaLBL_CopyToHost(phase->data(), Phi, N * sizeof(double));
|
||||
|
||||
auto new_index = std::make_shared<std::pair<int, IntArray>>( 0, IntArray() );
|
||||
auto new_ids = std::make_shared<std::pair<int, IntArray>>( 0, IntArray() );
|
||||
auto new_index =
|
||||
std::make_shared<std::pair<int, IntArray>>(0, IntArray());
|
||||
auto new_ids =
|
||||
std::make_shared<std::pair<int, IntArray>>(0, IntArray());
|
||||
auto new_list = std::make_shared<std::vector<BlobIDType>>();
|
||||
auto work1 = new BlobIdentificationWorkItem1( timestep, d_N[0], d_N[1], d_N[2], d_rank_info,
|
||||
phase, Averages.SDs, d_last_ids, new_index, new_ids, new_list, getComm() );
|
||||
auto work2 = new BlobIdentificationWorkItem2( timestep, d_N[0], d_N[1], d_N[2], d_rank_info,
|
||||
phase, Averages.SDs, d_last_ids, new_index, new_ids, new_list, getComm() );
|
||||
auto work1 = new BlobIdentificationWorkItem1(
|
||||
timestep, d_N[0], d_N[1], d_N[2], d_rank_info, phase, Averages.SDs,
|
||||
d_last_ids, new_index, new_ids, new_list, getComm());
|
||||
auto work2 = new BlobIdentificationWorkItem2(
|
||||
timestep, d_N[0], d_N[1], d_N[2], d_rank_info, phase, Averages.SDs,
|
||||
d_last_ids, new_index, new_ids, new_list, getComm());
|
||||
work1->add_dependency(d_wait_blobID);
|
||||
work2->add_dependency(d_tpool.add_work(work1));
|
||||
d_wait_blobID = d_tpool.add_work(work2);
|
||||
|
@ -1120,11 +1070,12 @@ void runAnalysis::run( int timestep, std::shared_ptr<Database> input_db, TwoPhas
|
|||
// if (timestep%d_restart_interval==0){
|
||||
// if ( matches(type,AnalysisType::ComputeAverages) ) {
|
||||
if (timestep % d_analysis_interval == 0) {
|
||||
auto work =
|
||||
new AnalysisWorkItem( type, timestep, Averages, d_last_index, d_last_id_map, d_beta );
|
||||
auto work = new AnalysisWorkItem(type, timestep, Averages, d_last_index,
|
||||
d_last_id_map, d_beta);
|
||||
work->add_dependency(d_wait_blobID);
|
||||
work->add_dependency(d_wait_analysis);
|
||||
work->add_dependency( d_wait_vis ); // Make sure we are done using analysis before modifying
|
||||
work->add_dependency(
|
||||
d_wait_vis); // Make sure we are done using analysis before modifying
|
||||
d_wait_analysis = d_tpool.add_work(work);
|
||||
}
|
||||
|
||||
|
@ -1139,7 +1090,8 @@ void runAnalysis::run( int timestep, std::shared_ptr<Database> input_db, TwoPhas
|
|||
OutStream.close();
|
||||
}
|
||||
// Write the restart file (using a seperate thread)
|
||||
auto work = new WriteRestartWorkItem( d_restartFile.c_str(), cDen, cfq, d_Np );
|
||||
auto work =
|
||||
new WriteRestartWorkItem(d_restartFile.c_str(), cDen, cfq, d_Np);
|
||||
work->add_dependency(d_wait_restart);
|
||||
d_wait_restart = d_tpool.add_work(work);
|
||||
}
|
||||
|
@ -1148,8 +1100,8 @@ void runAnalysis::run( int timestep, std::shared_ptr<Database> input_db, TwoPhas
|
|||
// if ( matches(type,AnalysisType::CreateRestart) ) {
|
||||
if (timestep % d_restart_interval == 0) {
|
||||
// Write the vis files
|
||||
auto work =
|
||||
new WriteVisWorkItem( timestep, d_meshData, Averages, d_n, d_rank_info, getComm() );
|
||||
auto work = new WriteVisWorkItem(timestep, d_meshData, Averages, d_n,
|
||||
d_rank_info, getComm());
|
||||
work->add_dependency(d_wait_blobID);
|
||||
work->add_dependency(d_wait_analysis);
|
||||
work->add_dependency(d_wait_vis);
|
||||
|
@ -1158,13 +1110,12 @@ void runAnalysis::run( int timestep, std::shared_ptr<Database> input_db, TwoPhas
|
|||
PROFILE_STOP("run");
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* Run the analysis *
|
||||
******************************************************************/
|
||||
void runAnalysis::basic( int timestep, std::shared_ptr<Database> input_db, SubPhase &Averages,
|
||||
const double *Phi, double *Pressure, double *Velocity, double *fq, double *Den )
|
||||
{
|
||||
void runAnalysis::basic(int timestep, std::shared_ptr<Database> input_db,
|
||||
SubPhase &Averages, const double *Phi, double *Pressure,
|
||||
double *Velocity, double *fq, double *Den) {
|
||||
int Nx = d_N[0];
|
||||
int Ny = d_N[1];
|
||||
int Nz = d_N[2];
|
||||
|
@ -1213,7 +1164,8 @@ void runAnalysis::basic( int timestep, std::shared_ptr<Database> input_db, SubPh
|
|||
d_ScaLBL_Comm->RegularLayout(d_Map, &Den[d_Np], Averages.Rho_w);
|
||||
d_ScaLBL_Comm->RegularLayout(d_Map, &Velocity[0], Averages.Vel_x);
|
||||
d_ScaLBL_Comm->RegularLayout(d_Map, &Velocity[d_Np], Averages.Vel_y);
|
||||
d_ScaLBL_Comm->RegularLayout( d_Map, &Velocity[2 * d_Np], Averages.Vel_z );
|
||||
d_ScaLBL_Comm->RegularLayout(d_Map, &Velocity[2 * d_Np],
|
||||
Averages.Vel_z);
|
||||
PROFILE_STOP("Copy-State", 1);
|
||||
}
|
||||
PROFILE_STOP("Copy data to host");
|
||||
|
@ -1256,15 +1208,16 @@ void runAnalysis::basic( int timestep, std::shared_ptr<Database> input_db, SubPh
|
|||
OutStream.close();
|
||||
}
|
||||
// Write the restart file (using a seperate thread)
|
||||
auto work1 = new WriteRestartWorkItem( d_restartFile.c_str(), cDen, cfq, d_Np );
|
||||
auto work1 =
|
||||
new WriteRestartWorkItem(d_restartFile.c_str(), cDen, cfq, d_Np);
|
||||
work1->add_dependency(d_wait_restart);
|
||||
d_wait_restart = d_tpool.add_work(work1);
|
||||
}
|
||||
|
||||
if (timestep % d_visualization_interval == 0) {
|
||||
// Write the vis files
|
||||
auto work =
|
||||
new IOWorkItem( timestep, input_db, d_meshData, Averages, d_n, d_rank_info, getComm() );
|
||||
auto work = new IOWorkItem(timestep, input_db, d_meshData, Averages,
|
||||
d_n, d_rank_info, getComm());
|
||||
work->add_dependency(d_wait_analysis);
|
||||
work->add_dependency(d_wait_subphase);
|
||||
work->add_dependency(d_wait_vis);
|
||||
|
@ -1275,9 +1228,9 @@ void runAnalysis::basic( int timestep, std::shared_ptr<Database> input_db, SubPh
|
|||
}
|
||||
|
||||
void runAnalysis::WriteVisData(int timestep, std::shared_ptr<Database> input_db,
|
||||
SubPhase &Averages, const double *Phi, double *Pressure, double *Velocity, double *fq,
|
||||
double *Den )
|
||||
{
|
||||
SubPhase &Averages, const double *Phi,
|
||||
double *Pressure, double *Velocity, double *fq,
|
||||
double *Den) {
|
||||
auto color_db = input_db->getDatabase("Color");
|
||||
auto vis_db = input_db->getDatabase("Visualization");
|
||||
// int timestep = color_db->getWithDefault<int>( "timestep", 0 );
|
||||
|
@ -1299,8 +1252,8 @@ void runAnalysis::WriteVisData( int timestep, std::shared_ptr<Database> input_db
|
|||
PROFILE_START("write vis", 1);
|
||||
|
||||
// if (Averages.WriteVis == true){
|
||||
auto work2 =
|
||||
new IOWorkItem( timestep, input_db, d_meshData, Averages, d_n, d_rank_info, getComm() );
|
||||
auto work2 = new IOWorkItem(timestep, input_db, d_meshData, Averages, d_n,
|
||||
d_rank_info, getComm());
|
||||
work2->add_dependency(d_wait_vis);
|
||||
d_wait_vis = d_tpool.add_work(work2);
|
||||
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef RunAnalysis_H_INC
|
||||
#define RunAnalysis_H_INC
|
||||
|
||||
|
@ -10,7 +26,6 @@
|
|||
#include "models/ColorModel.h"
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
// Types of analysis
|
||||
enum class AnalysisType : uint64_t {
|
||||
AnalyzeNone = 0,
|
||||
|
@ -23,15 +38,13 @@ enum class AnalysisType : uint64_t {
|
|||
ComputeSubphase = 0x40
|
||||
};
|
||||
|
||||
|
||||
//! Class to run the analysis in multiple threads
|
||||
class runAnalysis
|
||||
{
|
||||
class runAnalysis {
|
||||
public:
|
||||
//! Constructor
|
||||
runAnalysis(std::shared_ptr<Database> db, const RankInfoStruct &rank_info,
|
||||
std::shared_ptr<ScaLBL_Communicator> ScaLBL_Comm, std::shared_ptr<Domain> dm, int Np,
|
||||
bool Regular, IntArray Map );
|
||||
std::shared_ptr<ScaLBL_Communicator> ScaLBL_Comm,
|
||||
std::shared_ptr<Domain> dm, int Np, bool Regular, IntArray Map);
|
||||
|
||||
runAnalysis(ScaLBL_ColorModel &ColorModel);
|
||||
|
||||
|
@ -39,13 +52,16 @@ public:
|
|||
~runAnalysis();
|
||||
|
||||
//! Run the next analysis
|
||||
void run( int timestep, std::shared_ptr<Database> db, TwoPhase &Averages, const double *Phi,
|
||||
double *Pressure, double *Velocity, double *fq, double *Den );
|
||||
void run(int timestep, std::shared_ptr<Database> db, TwoPhase &Averages,
|
||||
const double *Phi, double *Pressure, double *Velocity, double *fq,
|
||||
double *Den);
|
||||
|
||||
void basic( int timestep, std::shared_ptr<Database> db, SubPhase &Averages, const double *Phi,
|
||||
double *Pressure, double *Velocity, double *fq, double *Den );
|
||||
void WriteVisData( int timestep, std::shared_ptr<Database> vis_db, SubPhase &Averages,
|
||||
const double *Phi, double *Pressure, double *Velocity, double *fq, double *Den );
|
||||
void basic(int timestep, std::shared_ptr<Database> db, SubPhase &Averages,
|
||||
const double *Phi, double *Pressure, double *Velocity,
|
||||
double *fq, double *Den);
|
||||
void WriteVisData(int timestep, std::shared_ptr<Database> vis_db,
|
||||
SubPhase &Averages, const double *Phi, double *Pressure,
|
||||
double *Velocity, double *fq, double *Den);
|
||||
|
||||
//! Finish all active analysis
|
||||
void finish();
|
||||
|
@ -64,8 +80,8 @@ public:
|
|||
* that all threads run on independent cores
|
||||
* @param[in] N_threads Number of threads, only used by some of the methods
|
||||
*/
|
||||
void createThreads( const std::string &method = "default", int N_threads = 4 );
|
||||
|
||||
void createThreads(const std::string &method = "default",
|
||||
int N_threads = 4);
|
||||
|
||||
private:
|
||||
runAnalysis();
|
||||
|
@ -74,8 +90,7 @@ private:
|
|||
AnalysisType computeAnalysisType(int timestep);
|
||||
|
||||
public:
|
||||
class commWrapper
|
||||
{
|
||||
class commWrapper {
|
||||
public:
|
||||
Utilities::MPI comm;
|
||||
int tag;
|
||||
|
@ -96,10 +111,13 @@ private:
|
|||
std::array<int, 3> d_N; // Number of local cells with ghosts
|
||||
int d_Np;
|
||||
int d_rank;
|
||||
int d_restart_interval, d_analysis_interval, d_blobid_interval, d_visualization_interval;
|
||||
int d_restart_interval, d_analysis_interval, d_blobid_interval,
|
||||
d_visualization_interval;
|
||||
int d_subphase_analysis_interval;
|
||||
double d_beta;
|
||||
bool d_regular;
|
||||
std::string format; // IO format string "silo" or "hdf5"
|
||||
|
||||
ThreadPool d_tpool;
|
||||
RankInfoStruct d_rank_info;
|
||||
IntArray d_Map;
|
||||
|
|
129
analysis/uCT.cpp
129
analysis/uCT.cpp
|
@ -1,22 +1,34 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "analysis/uCT.h"
|
||||
#include "analysis/analysis.h"
|
||||
#include "analysis/distance.h"
|
||||
#include "analysis/filters.h"
|
||||
#include "analysis/imfilter.h"
|
||||
|
||||
|
||||
template<class T>
|
||||
inline int sign( T x )
|
||||
{
|
||||
template <class T> inline int sign(T x) {
|
||||
if (x == 0)
|
||||
return 0;
|
||||
return x > 0 ? 1 : -1;
|
||||
}
|
||||
|
||||
|
||||
inline float trilinear(float dx, float dy, float dz, float f1, float f2,
|
||||
float f3, float f4, float f5, float f6, float f7, float f8 )
|
||||
{
|
||||
float f3, float f4, float f5, float f6, float f7,
|
||||
float f8) {
|
||||
double f, dx2, dy2, dz2, h0, h1;
|
||||
dx2 = 1.0 - dx;
|
||||
dy2 = 1.0 - dy;
|
||||
|
@ -27,9 +39,7 @@ inline float trilinear( float dx, float dy, float dz, float f1, float f2,
|
|||
return (f);
|
||||
}
|
||||
|
||||
|
||||
void InterpolateMesh( const Array<float> &Coarse, Array<float> &Fine )
|
||||
{
|
||||
void InterpolateMesh(const Array<float> &Coarse, Array<float> &Fine) {
|
||||
PROFILE_START("InterpolateMesh");
|
||||
|
||||
// Interpolate values from a Coarse mesh to a fine one
|
||||
|
@ -79,9 +89,10 @@ void InterpolateMesh( const Array<float> &Coarse, Array<float> &Fine )
|
|||
int i2 = i0 + 2;
|
||||
float dx = ((i + 0.5) - (i0 + 0.5) * hx) / hx;
|
||||
ASSERT(i0 >= -1 && i0 < nx + 1 && dx >= 0 && dx <= 1);
|
||||
float val = trilinear( dx, dy, dz,
|
||||
Coarse(i1,j1,k1), Coarse(i2,j1,k1), Coarse(i1,j2,k1), Coarse(i2,j2,k1),
|
||||
Coarse(i1,j1,k2), Coarse(i2,j1,k2), Coarse(i1,j2,k2), Coarse(i2,j2,k2) );
|
||||
float val = trilinear(
|
||||
dx, dy, dz, Coarse(i1, j1, k1), Coarse(i2, j1, k1),
|
||||
Coarse(i1, j2, k1), Coarse(i2, j2, k1), Coarse(i1, j1, k2),
|
||||
Coarse(i2, j1, k2), Coarse(i1, j2, k2), Coarse(i2, j2, k2));
|
||||
Fine(i + 1, j + 1, k + 1) = mapvalue * val;
|
||||
}
|
||||
}
|
||||
|
@ -89,10 +100,9 @@ void InterpolateMesh( const Array<float> &Coarse, Array<float> &Fine )
|
|||
PROFILE_STOP("InterpolateMesh");
|
||||
}
|
||||
|
||||
|
||||
// Smooth the data using the distance
|
||||
void smooth( const Array<float>& VOL, const Array<float>& Dist, float sigma, Array<float>& MultiScaleSmooth, fillHalo<float>& fillFloat )
|
||||
{
|
||||
void smooth(const Array<float> &VOL, const Array<float> &Dist, float sigma,
|
||||
Array<float> &MultiScaleSmooth, fillHalo<float> &fillFloat) {
|
||||
for (size_t i = 0; i < VOL.length(); i++) {
|
||||
// use exponential weight based on the distance
|
||||
float dst = Dist(i);
|
||||
|
@ -103,10 +113,8 @@ void smooth( const Array<float>& VOL, const Array<float>& Dist, float sigma, Arr
|
|||
fillFloat.fill(MultiScaleSmooth);
|
||||
}
|
||||
|
||||
|
||||
// Segment the data
|
||||
void segment( const Array<float>& data, Array<char>& ID, float tol )
|
||||
{
|
||||
void segment(const Array<float> &data, Array<char> &ID, float tol) {
|
||||
ASSERT(data.size() == ID.size());
|
||||
for (size_t i = 0; i < data.length(); i++) {
|
||||
if (data(i) > tol)
|
||||
|
@ -116,10 +124,8 @@ void segment( const Array<float>& data, Array<char>& ID, float tol )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Remove disconnected phases
|
||||
void removeDisconnected( Array<char>& ID, const Domain& Dm )
|
||||
{
|
||||
void removeDisconnected(Array<char> &ID, const Domain &Dm) {
|
||||
// Run blob identification to remove disconnected volumes
|
||||
BlobIDArray GlobalBlobID;
|
||||
DoubleArray SignDist(ID.size());
|
||||
|
@ -129,7 +135,8 @@ void removeDisconnected( Array<char>& ID, const Domain& Dm )
|
|||
Phase(i) = 1;
|
||||
}
|
||||
ComputeGlobalBlobIDs(ID.size(0) - 2, ID.size(1) - 2, ID.size(2) - 2,
|
||||
Dm.rank_info, Phase, SignDist, 0, 0, GlobalBlobID, Dm.Comm );
|
||||
Dm.rank_info, Phase, SignDist, 0, 0, GlobalBlobID,
|
||||
Dm.Comm);
|
||||
for (size_t i = 0; i < ID.length(); i++) {
|
||||
if (GlobalBlobID(i) > 0)
|
||||
ID(i) = 0;
|
||||
|
@ -137,13 +144,12 @@ void removeDisconnected( Array<char>& ID, const Domain& Dm )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Solve a level (without any coarse level information)
|
||||
void solve(const Array<float> &VOL, Array<float> &Mean, Array<char> &ID,
|
||||
Array<float>& Dist, Array<float>& MultiScaleSmooth, Array<float>& NonLocalMean,
|
||||
fillHalo<float>& fillFloat, const Domain& Dm, int nprocx,
|
||||
float threshold, float lamda, float sigsq, int depth)
|
||||
{
|
||||
Array<float> &Dist, Array<float> &MultiScaleSmooth,
|
||||
Array<float> &NonLocalMean, fillHalo<float> &fillFloat,
|
||||
const Domain &Dm, int nprocx, float threshold, float lamda,
|
||||
float sigsq, int depth) {
|
||||
PROFILE_SCOPED(timer, "solve");
|
||||
// Compute the median filter on the sparse array
|
||||
Med3D(VOL, Mean);
|
||||
|
@ -156,19 +162,18 @@ void solve( const Array<float>& VOL, Array<float>& Mean, Array<char>& ID,
|
|||
// Compute non-local mean
|
||||
// int depth = 5;
|
||||
// float sigsq=0.1;
|
||||
int nlm_count = NLM3D( MultiScaleSmooth, Mean, Dist, NonLocalMean, depth, sigsq);
|
||||
int nlm_count =
|
||||
NLM3D(MultiScaleSmooth, Mean, Dist, NonLocalMean, depth, sigsq);
|
||||
NULL_USE(nlm_count);
|
||||
fillFloat.fill(NonLocalMean);
|
||||
}
|
||||
|
||||
|
||||
// Refine a solution from a coarse grid to a fine grid
|
||||
void refine( const Array<float>& Dist_coarse,
|
||||
const Array<float>& VOL, Array<float>& Mean, Array<char>& ID,
|
||||
Array<float>& Dist, Array<float>& MultiScaleSmooth, Array<float>& NonLocalMean,
|
||||
void refine(const Array<float> &Dist_coarse, const Array<float> &VOL,
|
||||
Array<float> &Mean, Array<char> &ID, Array<float> &Dist,
|
||||
Array<float> &MultiScaleSmooth, Array<float> &NonLocalMean,
|
||||
fillHalo<float> &fillFloat, const Domain &Dm, int nprocx, int level,
|
||||
float threshold, float lamda, float sigsq, int depth)
|
||||
{
|
||||
float threshold, float lamda, float sigsq, int depth) {
|
||||
PROFILE_SCOPED(timer, "refine");
|
||||
int ratio[3] = {int(Dist.size(0) / Dist_coarse.size(0)),
|
||||
int(Dist.size(1) / Dist_coarse.size(1)),
|
||||
|
@ -186,22 +191,26 @@ void refine( const Array<float>& Dist_coarse,
|
|||
Dist(i) = 0;
|
||||
}
|
||||
fillFloat.fill(Dist);
|
||||
std::function<float(int,const float*)> filter_1D = []( int N, const float* data )
|
||||
{
|
||||
std::function<float(int, const float *)> filter_1D = [](int N,
|
||||
const float *data) {
|
||||
bool zero = data[0] == 0 || data[2] == 0;
|
||||
return zero ? data[1] * 1e-12 : data[1];
|
||||
};
|
||||
std::vector<imfilter::BC> BC(3, imfilter::BC::replicate);
|
||||
std::vector<std::function<float(int,const float*)>> filter_set(3,filter_1D);
|
||||
std::vector<std::function<float(int, const float *)>> filter_set(3,
|
||||
filter_1D);
|
||||
Dist = imfilter::imfilter_separable<float>(Dist, {1, 1, 1}, filter_set, BC);
|
||||
fillFloat.fill(Dist);
|
||||
// Smooth the volume data
|
||||
float h = 2*lamda*sqrt(double(ratio[0]*ratio[0]+ratio[1]*ratio[1]+ratio[2]*ratio[2]));
|
||||
float h = 2 * lamda *
|
||||
sqrt(double(ratio[0] * ratio[0] + ratio[1] * ratio[1] +
|
||||
ratio[2] * ratio[2]));
|
||||
smooth(VOL, Dist, h, MultiScaleSmooth, fillFloat);
|
||||
// Compute non-local mean
|
||||
// int depth = 3;
|
||||
// float sigsq = 0.1;
|
||||
int nlm_count = NLM3D( MultiScaleSmooth, Mean, Dist, NonLocalMean, depth, sigsq);
|
||||
int nlm_count =
|
||||
NLM3D(MultiScaleSmooth, Mean, Dist, NonLocalMean, depth, sigsq);
|
||||
NULL_USE(nlm_count);
|
||||
fillFloat.fill(NonLocalMean);
|
||||
segment(NonLocalMean, ID, 0.001);
|
||||
|
@ -219,14 +228,13 @@ void refine( const Array<float>& Dist_coarse,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Remove regions that are likely noise by shrinking the volumes by dx,
|
||||
// removing all values that are more than dx+delta from the surface, and then
|
||||
// growing by dx+delta and intersecting with the original data
|
||||
void filter_final(Array<char> &ID, Array<float> &Dist,
|
||||
fillHalo<float> &fillFloat, const Domain &Dm,
|
||||
Array<float>& Mean, Array<float>& Dist1, Array<float>& Dist2 )
|
||||
{
|
||||
Array<float> &Mean, Array<float> &Dist1,
|
||||
Array<float> &Dist2) {
|
||||
PROFILE_SCOPED(timer, "filter_final");
|
||||
int rank = Dm.Comm.getRank();
|
||||
int Nx = Dm.Nx - 2;
|
||||
|
@ -241,7 +249,8 @@ void filter_final( Array<char>& ID, Array<float>& Dist,
|
|||
float tmp = 0;
|
||||
for (size_t i = 0; i < Dist0.length(); i++)
|
||||
tmp += Dist0(i) * Dist0(i);
|
||||
tmp = sqrt( Dm.Comm.sumReduce(tmp) / Dm.Comm.sumReduce<float>(Dist0.length()) );
|
||||
tmp =
|
||||
sqrt(Dm.Comm.sumReduce(tmp) / Dm.Comm.sumReduce<float>(Dist0.length()));
|
||||
const float dx1 = 0.3 * tmp;
|
||||
const float dx2 = 1.05 * dx1;
|
||||
if (rank == 0)
|
||||
|
@ -273,8 +282,10 @@ void filter_final( Array<char>& ID, Array<float>& Dist,
|
|||
}
|
||||
}
|
||||
// Find regions of uncertainty that are entirely contained within another region
|
||||
fillHalo<double> fillDouble(Dm.Comm,Dm.rank_info,{Nx,Ny,Nz},{1,1,1},0,1);
|
||||
fillHalo<BlobIDType> fillInt(Dm.Comm,Dm.rank_info,{Nx,Ny,Nz},{1,1,1},0,1);
|
||||
fillHalo<double> fillDouble(Dm.Comm, Dm.rank_info, {Nx, Ny, Nz}, {1, 1, 1},
|
||||
0, 1);
|
||||
fillHalo<BlobIDType> fillInt(Dm.Comm, Dm.rank_info, {Nx, Ny, Nz}, {1, 1, 1},
|
||||
0, 1);
|
||||
BlobIDArray GlobalBlobID;
|
||||
DoubleArray SignDist(ID.size());
|
||||
for (size_t i = 0; i < ID.length(); i++)
|
||||
|
@ -282,7 +293,8 @@ void filter_final( Array<char>& ID, Array<float>& Dist,
|
|||
fillDouble.fill(SignDist);
|
||||
DoubleArray Phase(ID.size());
|
||||
Phase.fill(1);
|
||||
ComputeGlobalBlobIDs( Nx, Ny, Nz, Dm.rank_info, Phase, SignDist, 0, 0, GlobalBlobID, Dm.Comm );
|
||||
ComputeGlobalBlobIDs(Nx, Ny, Nz, Dm.rank_info, Phase, SignDist, 0, 0,
|
||||
GlobalBlobID, Dm.Comm);
|
||||
fillInt.fill(GlobalBlobID);
|
||||
int N_blobs = Dm.Comm.maxReduce(GlobalBlobID.max() + 1);
|
||||
std::vector<float> mean(N_blobs, 0);
|
||||
|
@ -348,20 +360,20 @@ void filter_final( Array<char>& ID, Array<float>& Dist,
|
|||
fillFloat.fill(Dist);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Filter the original data
|
||||
void filter_src( const Domain& Dm, Array<float>& src )
|
||||
{
|
||||
void filter_src(const Domain &Dm, Array<float> &src) {
|
||||
PROFILE_START("Filter source data");
|
||||
int Nx = Dm.Nx - 2;
|
||||
int Ny = Dm.Ny - 2;
|
||||
int Nz = Dm.Nz - 2;
|
||||
fillHalo<float> fillFloat(Dm.Comm,Dm.rank_info,{Nx,Ny,Nz},{1,1,1},0,1);
|
||||
fillHalo<float> fillFloat(Dm.Comm, Dm.rank_info, {Nx, Ny, Nz}, {1, 1, 1}, 0,
|
||||
1);
|
||||
// Perform a hot-spot filter on the data
|
||||
std::vector<imfilter::BC> BC = { imfilter::BC::replicate, imfilter::BC::replicate, imfilter::BC::replicate };
|
||||
std::function<float(const Array<float>&)> filter_3D = []( const Array<float>& data )
|
||||
{
|
||||
std::vector<imfilter::BC> BC = {imfilter::BC::replicate,
|
||||
imfilter::BC::replicate,
|
||||
imfilter::BC::replicate};
|
||||
std::function<float(const Array<float> &)> filter_3D =
|
||||
[](const Array<float> &data) {
|
||||
float min1 = std::min(data(0, 1, 1), data(2, 1, 1));
|
||||
float min2 = std::min(data(1, 0, 1), data(1, 2, 1));
|
||||
float min3 = std::min(data(1, 1, 0), data(1, 1, 2));
|
||||
|
@ -372,14 +384,15 @@ void filter_src( const Domain& Dm, Array<float>& src )
|
|||
float max = std::max(max1, std::max(max2, max3));
|
||||
return std::max(std::min(data(1, 1, 1), max), min);
|
||||
};
|
||||
std::function<float(const Array<float>&)> filter_1D = []( const Array<float>& data )
|
||||
{
|
||||
std::function<float(const Array<float> &)> filter_1D =
|
||||
[](const Array<float> &data) {
|
||||
float min = std::min(data(0), data(2));
|
||||
float max = std::max(data(0), data(2));
|
||||
return std::max(std::min(data(1), max), min);
|
||||
};
|
||||
//LOCVOL[0] = imfilter::imfilter<float>( LOCVOL[0], {1,1,1}, filter_3D, BC );
|
||||
std::vector<std::function<float(const Array<float>&)>> filter_set(3,filter_1D);
|
||||
std::vector<std::function<float(const Array<float> &)>> filter_set(
|
||||
3, filter_1D);
|
||||
src = imfilter::imfilter_separable<float>(src, {1, 1, 1}, filter_set, BC);
|
||||
fillFloat.fill(src);
|
||||
// Perform a gaussian filter on the data
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef uCT_H_INC
|
||||
#define uCT_H_INC
|
||||
|
||||
|
@ -5,8 +21,6 @@
|
|||
#include "common/Domain.h"
|
||||
#include "common/Communication.h"
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Interpolate between meshes
|
||||
* @details This routine interpolates from a coarse to a fine mesh
|
||||
|
@ -15,34 +29,30 @@
|
|||
*/
|
||||
void InterpolateMesh(const Array<float> &Coarse, Array<float> &Fine);
|
||||
|
||||
|
||||
// Smooth the data using the distance
|
||||
void smooth( const Array<float>& VOL, const Array<float>& Dist, float sigma, Array<float>& MultiScaleSmooth, fillHalo<float>& fillFloat );
|
||||
|
||||
void smooth(const Array<float> &VOL, const Array<float> &Dist, float sigma,
|
||||
Array<float> &MultiScaleSmooth, fillHalo<float> &fillFloat);
|
||||
|
||||
// Segment the data
|
||||
void segment(const Array<float> &data, Array<char> &ID, float tol);
|
||||
|
||||
|
||||
// Remove disconnected phases
|
||||
void removeDisconnected(Array<char> &ID, const Domain &Dm);
|
||||
|
||||
|
||||
// Solve a level (without any coarse level information)
|
||||
void solve(const Array<float> &VOL, Array<float> &Mean, Array<char> &ID,
|
||||
Array<float>& Dist, Array<float>& MultiScaleSmooth, Array<float>& NonLocalMean,
|
||||
fillHalo<float>& fillFloat, const Domain& Dm, int nprocx,
|
||||
float threshold, float lamda, float sigsq, int depth);
|
||||
|
||||
Array<float> &Dist, Array<float> &MultiScaleSmooth,
|
||||
Array<float> &NonLocalMean, fillHalo<float> &fillFloat,
|
||||
const Domain &Dm, int nprocx, float threshold, float lamda,
|
||||
float sigsq, int depth);
|
||||
|
||||
// Refine a solution from a coarse grid to a fine grid
|
||||
void refine( const Array<float>& Dist_coarse,
|
||||
const Array<float>& VOL, Array<float>& Mean, Array<char>& ID,
|
||||
Array<float>& Dist, Array<float>& MultiScaleSmooth, Array<float>& NonLocalMean,
|
||||
void refine(const Array<float> &Dist_coarse, const Array<float> &VOL,
|
||||
Array<float> &Mean, Array<char> &ID, Array<float> &Dist,
|
||||
Array<float> &MultiScaleSmooth, Array<float> &NonLocalMean,
|
||||
fillHalo<float> &fillFloat, const Domain &Dm, int nprocx, int level,
|
||||
float threshold, float lamda, float sigsq, int depth);
|
||||
|
||||
|
||||
// Remove regions that are likely noise by shrinking the volumes by dx,
|
||||
// removing all values that are more than dx+delta from the surface, and then
|
||||
// growing by dx+delta and intersecting with the original data
|
||||
|
@ -50,9 +60,7 @@ void filter_final( Array<char>& ID, Array<float>& Dist,
|
|||
fillHalo<float> &fillFloat, const Domain &Dm,
|
||||
Array<float> &Mean, Array<float> &Dist1, Array<float> &Dist2);
|
||||
|
||||
|
||||
// Filter the original data
|
||||
void filter_src(const Domain &Dm, Array<float> &src);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
84
clang-format-all
Executable file
84
clang-format-all
Executable file
|
@ -0,0 +1,84 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# clang-format-all: a tool to run clang-format on an entire project
|
||||
# Copyright (C) 2016 Evan Klitzke <evan@eklitzke.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
function usage {
|
||||
echo "Usage: $0 DIR..."
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
# Variable that will hold the name of the clang-format command
|
||||
FMT=""
|
||||
|
||||
# Some distros just call it clang-format. Others (e.g. Ubuntu) are insistent
|
||||
# that the version number be part of the command. We prefer clang-format if
|
||||
# that's present, otherwise we work backwards from highest version to lowest
|
||||
# version.
|
||||
for clangfmt in clang-format{,-{4,3}.{9,8,7,6,5,4,3,2,1,0}}; do
|
||||
if which "$clangfmt" &>/dev/null; then
|
||||
FMT="$clangfmt"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Check if we found a working clang-format
|
||||
if [ -z "$FMT" ]; then
|
||||
echo "failed to find clang-format"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check all of the arguments first to make sure they're all directories
|
||||
for dir in "$@"; do
|
||||
if [ ! -d "${dir}" ]; then
|
||||
echo "${dir} is not a directory"
|
||||
usage
|
||||
fi
|
||||
done
|
||||
|
||||
# Find a dominating file, starting from a given directory and going up.
|
||||
find-dominating-file() {
|
||||
if [ -r "$1"/"$2" ]; then
|
||||
return 0
|
||||
fi
|
||||
if [ "$1" = "/" ]; then
|
||||
return 1
|
||||
fi
|
||||
find-dominating-file "$(realpath "$1"/..)" "$2"
|
||||
return $?
|
||||
}
|
||||
|
||||
# Run clang-format -i on all of the things
|
||||
for dir in "$@"; do
|
||||
pushd "${dir}" &>/dev/null
|
||||
if ! find-dominating-file . .clang-format; then
|
||||
echo "Failed to find dominating .clang-format starting at $PWD"
|
||||
continue
|
||||
fi
|
||||
find . \
|
||||
\( -name '*.c' \
|
||||
-o -name '*.cc' \
|
||||
-o -name '*.cpp' \
|
||||
-o -name '*.h' \
|
||||
-o -name '*.hh' \
|
||||
-o -name '*.hpp' \) \
|
||||
-exec "${FMT}" -i '{}' \;
|
||||
popd &>/dev/null
|
||||
done
|
|
@ -263,7 +263,7 @@ ENDMACRO ()
|
|||
# Macro to configure LBPM specific options
|
||||
MACRO ( CONFIGURE_LBPM )
|
||||
# Set the maximum number of processors for the tests
|
||||
IF ( NOT TEST_MAX_PROCS )
|
||||
IF ( NOT DEFINED TEST_MAX_PROCS )
|
||||
SET( TEST_MAX_PROCS 32 )
|
||||
ENDIF()
|
||||
# Add the correct paths to rpath in case we build shared libraries
|
||||
|
|
221
common/Array.h
221
common/Array.h
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef included_ArrayClass
|
||||
#define included_ArrayClass
|
||||
|
||||
|
@ -13,13 +29,10 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
/*!
|
||||
* Class Array is a multi-dimensional array class written by Mark Berrill
|
||||
*/
|
||||
template<class TYPE, class FUN, class Allocator>
|
||||
class Array final
|
||||
{
|
||||
template <class TYPE, class FUN, class Allocator> class Array final {
|
||||
public: // Constructors / assignment operators
|
||||
/*!
|
||||
* Create a new empty Array
|
||||
|
@ -97,7 +110,6 @@ public: // Constructors / assignment operators
|
|||
*/
|
||||
Array(std::initializer_list<std::initializer_list<TYPE>> data);
|
||||
|
||||
|
||||
/*!
|
||||
* Copy constructor
|
||||
* @param rhs Array to copy
|
||||
|
@ -140,24 +152,22 @@ public: // Constructors / assignment operators
|
|||
//! Set is copyable
|
||||
inline void setFixedSize(bool flag) { d_isFixedSize = flag; }
|
||||
|
||||
|
||||
public: // Views/copies/subset
|
||||
/*!
|
||||
* Create a multi-dimensional Array view to a raw block of data
|
||||
* @param N Number of elements in each dimension
|
||||
* @param data Pointer to the data
|
||||
*/
|
||||
static std::unique_ptr<Array> view( const ArraySize &N, std::shared_ptr<TYPE> data );
|
||||
|
||||
static std::unique_ptr<Array> view(const ArraySize &N,
|
||||
std::shared_ptr<TYPE> data);
|
||||
|
||||
/*!
|
||||
* Create a multi-dimensional Array view to a raw block of data
|
||||
* @param N Number of elements in each dimension
|
||||
* @param data Pointer to the data
|
||||
*/
|
||||
static std::unique_ptr<const Array> constView( const ArraySize &N,
|
||||
std::shared_ptr<const TYPE> const &data );
|
||||
|
||||
static std::unique_ptr<const Array>
|
||||
constView(const ArraySize &N, std::shared_ptr<const TYPE> const &data);
|
||||
|
||||
/*!
|
||||
* Make this object a view of the src
|
||||
|
@ -185,9 +195,8 @@ public: // Views/copies/subset
|
|||
* @param isCopyable Once the view is created, can the array be copied
|
||||
* @param isFixedSize Once the view is created, is the array size fixed
|
||||
*/
|
||||
inline void viewRaw(
|
||||
int ndim, const size_t *dims, TYPE *data, bool isCopyable = true, bool isFixedSize = true )
|
||||
{
|
||||
inline void viewRaw(int ndim, const size_t *dims, TYPE *data,
|
||||
bool isCopyable = true, bool isFixedSize = true) {
|
||||
viewRaw(ArraySize(ndim, dims), data, isCopyable, isFixedSize);
|
||||
}
|
||||
|
||||
|
@ -203,7 +212,8 @@ public: // Views/copies/subset
|
|||
* @param isCopyable Once the view is created, can the array be copied
|
||||
* @param isFixedSize Once the view is created, is the array size fixed
|
||||
*/
|
||||
void viewRaw( const ArraySize &N, TYPE *data, bool isCopyable = true, bool isFixedSize = true );
|
||||
void viewRaw(const ArraySize &N, TYPE *data, bool isCopyable = true,
|
||||
bool isFixedSize = true);
|
||||
|
||||
/*!
|
||||
* Create an array view of the given data (expert use only).
|
||||
|
@ -215,8 +225,7 @@ public: // Views/copies/subset
|
|||
* @param N Number of elements in each dimension
|
||||
* @param data Pointer to the data
|
||||
*/
|
||||
static inline Array staticView( const ArraySize &N, TYPE *data )
|
||||
{
|
||||
static inline Array staticView(const ArraySize &N, TYPE *data) {
|
||||
Array x;
|
||||
x.viewRaw(N, data, true, true);
|
||||
return x;
|
||||
|
@ -228,35 +237,30 @@ public: // Views/copies/subset
|
|||
*/
|
||||
template <class TYPE2>
|
||||
static inline std::unique_ptr<Array<TYPE2, FUN, Allocator>>
|
||||
convert( std::shared_ptr<Array<TYPE, FUN, Allocator>> array )
|
||||
{
|
||||
convert(std::shared_ptr<Array<TYPE, FUN, Allocator>> array) {
|
||||
auto array2 = std::make_unique<Array<TYPE2>>(array->size());
|
||||
array2.copy(*array);
|
||||
return array2;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* Convert an array of one type to another. This may or may not allocate new memory.
|
||||
* @param array Input array
|
||||
*/
|
||||
template <class TYPE2>
|
||||
static inline std::unique_ptr<const Array<TYPE2, FUN, Allocator>>
|
||||
convert( std::shared_ptr<const Array<TYPE, FUN, Allocator>> array )
|
||||
{
|
||||
convert(std::shared_ptr<const Array<TYPE, FUN, Allocator>> array) {
|
||||
auto array2 = std::make_unique<Array<TYPE2>>(array->size());
|
||||
array2.copy(*array);
|
||||
return array2;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* Copy and convert data from another array to this array
|
||||
* @param array Source array
|
||||
*/
|
||||
template <class TYPE2, class FUN2, class Allocator2>
|
||||
void inline copy( const Array<TYPE2, FUN2, Allocator2> &array )
|
||||
{
|
||||
void inline copy(const Array<TYPE2, FUN2, Allocator2> &array) {
|
||||
resize(array.size());
|
||||
copy(array.data());
|
||||
}
|
||||
|
@ -266,38 +270,32 @@ public: // Views/copies/subset
|
|||
* Note: The current array must be allocated to the proper size first.
|
||||
* @param data Source data
|
||||
*/
|
||||
template<class TYPE2>
|
||||
inline void copy( const TYPE2 *data );
|
||||
template <class TYPE2> inline void copy(const TYPE2 *data);
|
||||
|
||||
/*!
|
||||
* Copy and convert data from this array to a raw vector.
|
||||
* @param data Source data
|
||||
*/
|
||||
template<class TYPE2>
|
||||
inline void copyTo( TYPE2 *data ) const;
|
||||
template <class TYPE2> inline void copyTo(TYPE2 *data) const;
|
||||
|
||||
/*!
|
||||
* Copy and convert data from this array to a new array
|
||||
*/
|
||||
template <class TYPE2>
|
||||
Array<TYPE2, FUN, std::allocator<TYPE2>> inline cloneTo() const
|
||||
{
|
||||
Array<TYPE2, FUN, std::allocator<TYPE2>> inline cloneTo() const {
|
||||
Array<TYPE2, FUN, std::allocator<TYPE2>> dst(this->size());
|
||||
copyTo(dst.data());
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
/*! swap the raw data pointers for the Arrays after checking for compatibility */
|
||||
void swap(Array &other);
|
||||
|
||||
|
||||
/*!
|
||||
* Fill the array with the given value
|
||||
* @param y Value to fill
|
||||
*/
|
||||
inline void fill( const TYPE &y )
|
||||
{
|
||||
inline void fill(const TYPE &y) {
|
||||
for (auto &x : *this)
|
||||
x = y;
|
||||
}
|
||||
|
@ -306,14 +304,11 @@ public: // Views/copies/subset
|
|||
* Scale the array by the given value
|
||||
* @param y Value to scale by
|
||||
*/
|
||||
template<class TYPE2>
|
||||
inline void scale( const TYPE2 &y )
|
||||
{
|
||||
template <class TYPE2> inline void scale(const TYPE2 &y) {
|
||||
for (auto &x : *this)
|
||||
x *= y;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* Set the values of this array to pow(base, exp)
|
||||
* @param base Base array
|
||||
|
@ -321,52 +316,44 @@ public: // Views/copies/subset
|
|||
*/
|
||||
void pow(const Array &base, const TYPE &exp);
|
||||
|
||||
|
||||
//! Destructor
|
||||
~Array();
|
||||
|
||||
|
||||
//! Clear the data in the array
|
||||
void clear();
|
||||
|
||||
|
||||
//! Return the size of the Array
|
||||
inline int ndim() const { return d_size.ndim(); }
|
||||
|
||||
|
||||
//! Return the size of the Array
|
||||
inline const ArraySize &size() const { return d_size; }
|
||||
|
||||
|
||||
//! Return the size of the Array
|
||||
inline size_t size(int d) const { return d_size[d]; }
|
||||
|
||||
|
||||
//! Return the size of the Array
|
||||
inline size_t length() const { return d_size.length(); }
|
||||
|
||||
|
||||
//! Return true if the Array is empty
|
||||
inline bool empty() const { return d_size.length() == 0; }
|
||||
|
||||
|
||||
//! Return true if the Array is not empty
|
||||
inline operator bool() const { return d_size.length() != 0; }
|
||||
|
||||
|
||||
/*!
|
||||
* Resize the Array
|
||||
* @param N NUmber of elements
|
||||
*/
|
||||
inline void resize(size_t N) { resize(ArraySize(N)); }
|
||||
|
||||
|
||||
/*!
|
||||
* Resize the Array
|
||||
* @param N_row Number of rows
|
||||
* @param N_col Number of columns
|
||||
*/
|
||||
inline void resize( size_t N_row, size_t N_col ) { resize( ArraySize( N_row, N_col ) ); }
|
||||
inline void resize(size_t N_row, size_t N_col) {
|
||||
resize(ArraySize(N_row, N_col));
|
||||
}
|
||||
|
||||
/*!
|
||||
* Resize the Array
|
||||
|
@ -374,7 +361,9 @@ public: // Views/copies/subset
|
|||
* @param N2 Number of columns
|
||||
* @param N3 Number of elements in the third dimension
|
||||
*/
|
||||
inline void resize( size_t N1, size_t N2, size_t N3 ) { resize( ArraySize( N1, N2, N3 ) ); }
|
||||
inline void resize(size_t N1, size_t N2, size_t N3) {
|
||||
resize(ArraySize(N1, N2, N3));
|
||||
}
|
||||
|
||||
/*!
|
||||
* Resize the Array
|
||||
|
@ -382,7 +371,6 @@ public: // Views/copies/subset
|
|||
*/
|
||||
void resize(const ArraySize &N);
|
||||
|
||||
|
||||
/*!
|
||||
* Resize the given dimension of the array
|
||||
* @param dim The dimension to resize
|
||||
|
@ -391,20 +379,17 @@ public: // Views/copies/subset
|
|||
*/
|
||||
void resizeDim(int dim, size_t N, const TYPE &value);
|
||||
|
||||
|
||||
/*!
|
||||
* Reshape the Array (total size of array will not change)
|
||||
* @param N Number of elements in each dimension
|
||||
*/
|
||||
void reshape(const ArraySize &N);
|
||||
|
||||
|
||||
/*!
|
||||
* Remove singleton dimensions.
|
||||
*/
|
||||
void squeeze();
|
||||
|
||||
|
||||
/*!
|
||||
* Reshape the Array so that the number of dimensions is the
|
||||
* max of ndim and the largest dim>1.
|
||||
|
@ -412,21 +397,18 @@ public: // Views/copies/subset
|
|||
*/
|
||||
inline void setNdim(int ndim) { d_size.setNdim(ndim); }
|
||||
|
||||
|
||||
/*!
|
||||
* Subset the Array
|
||||
* @param index Index to subset (imin,imax,jmin,jmax,kmin,kmax,...)
|
||||
*/
|
||||
Array subset(const std::vector<size_t> &index) const;
|
||||
|
||||
|
||||
/*!
|
||||
* Subset the Array
|
||||
* @param index Index to subset (ix:kx:jx,iy:ky:jy,...)
|
||||
*/
|
||||
Array subset(const std::vector<Range<size_t>> &index) const;
|
||||
|
||||
|
||||
/*!
|
||||
* Copy data from an array into a subset of this array
|
||||
* @param index Index of the subset (imin,imax,jmin,jmax,kmin,kmax,...)
|
||||
|
@ -439,7 +421,8 @@ public: // Views/copies/subset
|
|||
* @param index Index of the subset
|
||||
* @param subset The subset array to copy from
|
||||
*/
|
||||
void copySubset( const std::vector<Range<size_t>> &index, const Array &subset );
|
||||
void copySubset(const std::vector<Range<size_t>> &index,
|
||||
const Array &subset);
|
||||
|
||||
/*!
|
||||
* Add data from an array into a subset of this array
|
||||
|
@ -453,22 +436,23 @@ public: // Views/copies/subset
|
|||
* @param index Index of the subset
|
||||
* @param subset The subset array to add from
|
||||
*/
|
||||
void addSubset( const std::vector<Range<size_t>> &index, const Array &subset );
|
||||
|
||||
void addSubset(const std::vector<Range<size_t>> &index,
|
||||
const Array &subset);
|
||||
|
||||
public: // Accessors
|
||||
/*!
|
||||
* Access the desired element
|
||||
* @param i The row index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()( size_t i ) { return d_data[d_size.index( i )]; }
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()(size_t i) {
|
||||
return d_data[d_size.index(i)];
|
||||
}
|
||||
|
||||
/*!
|
||||
* Access the desired element
|
||||
* @param i The row index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline const TYPE &operator()( size_t i ) const
|
||||
{
|
||||
ARRAY_ATTRIBUTE inline const TYPE &operator()(size_t i) const {
|
||||
return d_data[d_size.index(i)];
|
||||
}
|
||||
|
||||
|
@ -477,8 +461,7 @@ public: // Accessors
|
|||
* @param i The row index
|
||||
* @param j The column index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()( size_t i, size_t j )
|
||||
{
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()(size_t i, size_t j) {
|
||||
return d_data[d_size.index(i, j)];
|
||||
}
|
||||
|
||||
|
@ -487,8 +470,7 @@ public: // Accessors
|
|||
* @param i The row index
|
||||
* @param j The column index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline const TYPE &operator()( size_t i, size_t j ) const
|
||||
{
|
||||
ARRAY_ATTRIBUTE inline const TYPE &operator()(size_t i, size_t j) const {
|
||||
return d_data[d_size.index(i, j)];
|
||||
}
|
||||
|
||||
|
@ -498,8 +480,7 @@ public: // Accessors
|
|||
* @param j The column index
|
||||
* @param k The third index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()( size_t i, size_t j, size_t k )
|
||||
{
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()(size_t i, size_t j, size_t k) {
|
||||
return d_data[d_size.index(i, j, k)];
|
||||
}
|
||||
|
||||
|
@ -509,8 +490,8 @@ public: // Accessors
|
|||
* @param j The column index
|
||||
* @param k The third index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline const TYPE &operator()( size_t i, size_t j, size_t k ) const
|
||||
{
|
||||
ARRAY_ATTRIBUTE inline const TYPE &operator()(size_t i, size_t j,
|
||||
size_t k) const {
|
||||
return d_data[d_size.index(i, j, k)];
|
||||
}
|
||||
|
||||
|
@ -521,8 +502,8 @@ public: // Accessors
|
|||
* @param i3 The third index
|
||||
* @param i4 The fourth index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()( size_t i1, size_t i2, size_t i3, size_t i4 )
|
||||
{
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()(size_t i1, size_t i2, size_t i3,
|
||||
size_t i4) {
|
||||
return d_data[d_size.index(i1, i2, i3, i4)];
|
||||
}
|
||||
|
||||
|
@ -533,9 +514,8 @@ public: // Accessors
|
|||
* @param i3 The third index
|
||||
* @param i4 The fourth index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline const TYPE &
|
||||
operator()( size_t i1, size_t i2, size_t i3, size_t i4 ) const
|
||||
{
|
||||
ARRAY_ATTRIBUTE inline const TYPE &operator()(size_t i1, size_t i2,
|
||||
size_t i3, size_t i4) const {
|
||||
return d_data[d_size.index(i1, i2, i3, i4)];
|
||||
}
|
||||
|
||||
|
@ -547,8 +527,8 @@ public: // Accessors
|
|||
* @param i4 The fourth index
|
||||
* @param i5 The fifth index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()( size_t i1, size_t i2, size_t i3, size_t i4, size_t i5 )
|
||||
{
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()(size_t i1, size_t i2, size_t i3,
|
||||
size_t i4, size_t i5) {
|
||||
return d_data[d_size.index(i1, i2, i3, i4, i5)];
|
||||
}
|
||||
|
||||
|
@ -561,8 +541,7 @@ public: // Accessors
|
|||
* @param i5 The fifth index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline const TYPE &
|
||||
operator()( size_t i1, size_t i2, size_t i3, size_t i4, size_t i5 ) const
|
||||
{
|
||||
operator()(size_t i1, size_t i2, size_t i3, size_t i4, size_t i5) const {
|
||||
return d_data[d_size.index(i1, i2, i3, i4, i5)];
|
||||
}
|
||||
|
||||
|
@ -570,8 +549,7 @@ public: // Accessors
|
|||
* Access the desired element as a raw pointer
|
||||
* @param i The global index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline TYPE *ptr( size_t i )
|
||||
{
|
||||
ARRAY_ATTRIBUTE inline TYPE *ptr(size_t i) {
|
||||
return i >= d_size.length() ? nullptr : &d_data[i];
|
||||
}
|
||||
|
||||
|
@ -579,8 +557,7 @@ public: // Accessors
|
|||
* Access the desired element as a raw pointer
|
||||
* @param i The global index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline const TYPE *ptr( size_t i ) const
|
||||
{
|
||||
ARRAY_ATTRIBUTE inline const TYPE *ptr(size_t i) const {
|
||||
return i >= d_size.length() ? nullptr : &d_data[i];
|
||||
}
|
||||
|
||||
|
@ -608,14 +585,15 @@ public: // Accessors
|
|||
//! Return the pointer to the raw data
|
||||
ARRAY_ATTRIBUTE inline const TYPE *data() const { return d_data; }
|
||||
|
||||
|
||||
public: // Operator overloading
|
||||
//! Check if two matrices are equal
|
||||
// Equality means the dimensions and data have to be identical
|
||||
bool operator==(const Array &rhs) const;
|
||||
|
||||
//! Check if two matrices are not equal
|
||||
inline bool operator!=( const Array &rhs ) const { return !this->operator==( rhs ); }
|
||||
inline bool operator!=(const Array &rhs) const {
|
||||
return !this->operator==(rhs);
|
||||
}
|
||||
|
||||
//! Add another array
|
||||
Array &operator+=(const Array &rhs);
|
||||
|
@ -629,7 +607,6 @@ public: // Operator overloading
|
|||
//! Subtract a scalar
|
||||
Array &operator-=(const TYPE &rhs);
|
||||
|
||||
|
||||
public: // Math operations
|
||||
//! Concatenates the arrays along the dimension dim.
|
||||
static Array cat(const std::vector<Array> &x, int dim = 0);
|
||||
|
@ -695,13 +672,13 @@ public: // Math operations
|
|||
TYPE mean(const std::vector<Range<size_t>> &index) const;
|
||||
|
||||
//! Find all elements that match the operator
|
||||
std::vector<size_t> find( const TYPE &value,
|
||||
std::vector<size_t>
|
||||
find(const TYPE &value,
|
||||
std::function<bool(const TYPE &, const TYPE &)> compare) const;
|
||||
|
||||
|
||||
//! Print an array
|
||||
void
|
||||
print( std::ostream &os, const std::string &name = "A", const std::string &prefix = "" ) const;
|
||||
void print(std::ostream &os, const std::string &name = "A",
|
||||
const std::string &prefix = "") const;
|
||||
|
||||
//! Transpose an array
|
||||
Array reverseDim() const;
|
||||
|
@ -741,7 +718,8 @@ public: // Math operations
|
|||
* @param[in] fun The function operation
|
||||
* @param[in] x The input array
|
||||
*/
|
||||
static Array transform( std::function<TYPE( const TYPE & )> fun, const Array &x );
|
||||
static Array transform(std::function<TYPE(const TYPE &)> fun,
|
||||
const Array &x);
|
||||
|
||||
/*!
|
||||
* Perform a element-wise operation z = f(x,y)
|
||||
|
@ -750,8 +728,7 @@ public: // Math operations
|
|||
* @param[in] y The second array
|
||||
*/
|
||||
static Array transform(std::function<TYPE(const TYPE &, const TYPE &)> fun,
|
||||
const Array &x,
|
||||
const Array &y );
|
||||
const Array &x, const Array &y);
|
||||
|
||||
/*!
|
||||
* axpby operation: this = alpha*x + beta*this
|
||||
|
@ -765,7 +742,9 @@ public: // Math operations
|
|||
* Linear interpolation
|
||||
* @param[in] x Position as a decimal index
|
||||
*/
|
||||
inline TYPE interp( const std::vector<double> &x ) const { return interp( x.data() ); }
|
||||
inline TYPE interp(const std::vector<double> &x) const {
|
||||
return interp(x.data());
|
||||
}
|
||||
|
||||
/*!
|
||||
* Linear interpolation
|
||||
|
@ -792,7 +771,8 @@ private:
|
|||
|
||||
private:
|
||||
inline void checkSubsetIndex(const std::vector<Range<size_t>> &range) const;
|
||||
inline std::vector<Range<size_t>> convert( const std::vector<size_t> &index ) const;
|
||||
inline std::vector<Range<size_t>>
|
||||
convert(const std::vector<size_t> &index) const;
|
||||
static inline void getSubsetArrays(const std::vector<Range<size_t>> &range,
|
||||
std::array<size_t, 5> &first,
|
||||
std::array<size_t, 5> &last,
|
||||
|
@ -800,12 +780,10 @@ private:
|
|||
std::array<size_t, 5> &N);
|
||||
};
|
||||
|
||||
|
||||
/********************************************************
|
||||
* ostream operator *
|
||||
********************************************************/
|
||||
inline std::ostream &operator<<( std::ostream &out, const ArraySize &s )
|
||||
{
|
||||
inline std::ostream &operator<<(std::ostream &out, const ArraySize &s) {
|
||||
out << "[" << s[0];
|
||||
for (size_t i = 1; i < s.ndim(); i++)
|
||||
out << "," << s[i];
|
||||
|
@ -813,70 +791,64 @@ inline std::ostream &operator<<( std::ostream &out, const ArraySize &s )
|
|||
return out;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Math operations *
|
||||
********************************************************/
|
||||
template <class TYPE, class FUN, class Allocator>
|
||||
inline Array<TYPE, FUN, Allocator> operator+(
|
||||
const Array<TYPE, FUN, Allocator> &a, const Array<TYPE, FUN, Allocator> &b )
|
||||
{
|
||||
inline Array<TYPE, FUN, Allocator>
|
||||
operator+(const Array<TYPE, FUN, Allocator> &a,
|
||||
const Array<TYPE, FUN, Allocator> &b) {
|
||||
Array<TYPE, FUN, Allocator> c;
|
||||
const auto &op = [](const TYPE &a, const TYPE &b) { return a + b; };
|
||||
FUN::transform(op, a, b, c);
|
||||
return c;
|
||||
}
|
||||
template <class TYPE, class FUN, class Allocator>
|
||||
inline Array<TYPE, FUN, Allocator> operator-(
|
||||
const Array<TYPE, FUN, Allocator> &a, const Array<TYPE, FUN, Allocator> &b )
|
||||
{
|
||||
inline Array<TYPE, FUN, Allocator>
|
||||
operator-(const Array<TYPE, FUN, Allocator> &a,
|
||||
const Array<TYPE, FUN, Allocator> &b) {
|
||||
Array<TYPE, FUN, Allocator> c;
|
||||
const auto &op = [](const TYPE &a, const TYPE &b) { return a - b; };
|
||||
FUN::transform(op, a, b, c);
|
||||
return c;
|
||||
}
|
||||
template <class TYPE, class FUN, class Allocator>
|
||||
inline Array<TYPE, FUN, Allocator> operator*(
|
||||
const Array<TYPE, FUN, Allocator> &a, const Array<TYPE, FUN, Allocator> &b )
|
||||
{
|
||||
inline Array<TYPE, FUN, Allocator>
|
||||
operator*(const Array<TYPE, FUN, Allocator> &a,
|
||||
const Array<TYPE, FUN, Allocator> &b) {
|
||||
Array<TYPE, FUN, Allocator> c;
|
||||
FUN::multiply(a, b, c);
|
||||
return c;
|
||||
}
|
||||
template <class TYPE, class FUN, class Allocator>
|
||||
inline Array<TYPE, FUN, Allocator> operator*(
|
||||
const Array<TYPE, FUN, Allocator> &a, const std::vector<TYPE> &b )
|
||||
{
|
||||
inline Array<TYPE, FUN, Allocator>
|
||||
operator*(const Array<TYPE, FUN, Allocator> &a, const std::vector<TYPE> &b) {
|
||||
Array<TYPE, FUN, Allocator> b2, c;
|
||||
b2.viewRaw({b.size()}, const_cast<TYPE *>(b.data()));
|
||||
FUN::multiply(a, b2, c);
|
||||
return c;
|
||||
}
|
||||
template <class TYPE, class FUN, class Allocator>
|
||||
inline Array<TYPE, FUN, Allocator> operator*( const TYPE &a,
|
||||
const Array<TYPE, FUN, Allocator> &b )
|
||||
{
|
||||
inline Array<TYPE, FUN, Allocator>
|
||||
operator*(const TYPE &a, const Array<TYPE, FUN, Allocator> &b) {
|
||||
auto c = b;
|
||||
c.scale(a);
|
||||
return c;
|
||||
}
|
||||
template <class TYPE, class FUN, class Allocator>
|
||||
inline Array<TYPE, FUN, Allocator> operator*( const Array<TYPE, FUN, Allocator> &a,
|
||||
const TYPE &b )
|
||||
{
|
||||
inline Array<TYPE, FUN, Allocator>
|
||||
operator*(const Array<TYPE, FUN, Allocator> &a, const TYPE &b) {
|
||||
auto c = a;
|
||||
c.scale(b);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Copy array *
|
||||
********************************************************/
|
||||
template <class TYPE, class FUN, class Allocator>
|
||||
template <class TYPE2>
|
||||
inline void Array<TYPE, FUN, Allocator>::copy( const TYPE2 *data )
|
||||
{
|
||||
inline void Array<TYPE, FUN, Allocator>::copy(const TYPE2 *data) {
|
||||
if (std::is_same<TYPE, TYPE2>::value) {
|
||||
std::copy(data, data + d_size.length(), d_data);
|
||||
} else {
|
||||
|
@ -886,8 +858,7 @@ inline void Array<TYPE, FUN, Allocator>::copy( const TYPE2 *data )
|
|||
}
|
||||
template <class TYPE, class FUN, class Allocator>
|
||||
template <class TYPE2>
|
||||
inline void Array<TYPE, FUN, Allocator>::copyTo( TYPE2 *data ) const
|
||||
{
|
||||
inline void Array<TYPE, FUN, Allocator>::copyTo(TYPE2 *data) const {
|
||||
if (std::is_same<TYPE, TYPE2>::value) {
|
||||
std::copy(d_data, d_data + d_size.length(), data);
|
||||
} else {
|
||||
|
@ -896,7 +867,6 @@ inline void Array<TYPE, FUN, Allocator>::copyTo( TYPE2 *data ) const
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Convience typedefs *
|
||||
* Copy array *
|
||||
|
@ -904,5 +874,4 @@ inline void Array<TYPE, FUN, Allocator>::copyTo( TYPE2 *data ) const
|
|||
typedef Array<double> DoubleArray;
|
||||
typedef Array<int> IntArray;
|
||||
|
||||
|
||||
#endif
|
||||
|
|
466
common/Array.hpp
466
common/Array.hpp
File diff suppressed because it is too large
Load Diff
|
@ -13,7 +13,6 @@
|
|||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#if defined(__CUDA_ARCH__)
|
||||
#include <cuda.h>
|
||||
#define HOST_DEVICE __host__ __device__
|
||||
|
@ -26,7 +25,6 @@
|
|||
#define ARRAY_ATTRIBUTE HOST_DEVICE
|
||||
#endif
|
||||
|
||||
|
||||
#if (defined(DEBUG) || defined(_DEBUG)) && !defined(NDEBUG)
|
||||
#define CHECK_ARRAY_LENGTH(i, length) \
|
||||
do { \
|
||||
|
@ -39,18 +37,14 @@
|
|||
} while (0)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Forward declerations
|
||||
class FunctionTable;
|
||||
template<class TYPE, class FUN = FunctionTable, class Allocator = std::allocator<TYPE>>
|
||||
template <class TYPE, class FUN = FunctionTable,
|
||||
class Allocator = std::allocator<TYPE>>
|
||||
class Array;
|
||||
|
||||
|
||||
//! Simple range class
|
||||
template<class TYPE = size_t>
|
||||
class Range final
|
||||
{
|
||||
template <class TYPE = size_t> class Range final {
|
||||
public:
|
||||
//! Empty constructor
|
||||
Range() : i(0), j(-1), k(1) {}
|
||||
|
@ -62,13 +56,10 @@ public:
|
|||
* @param k_ Increment value
|
||||
*/
|
||||
Range(const TYPE &i_, const TYPE &j_, const TYPE &k_ = 1)
|
||||
: i( i_ ), j( j_ ), k( k_ )
|
||||
{
|
||||
}
|
||||
: i(i_), j(j_), k(k_) {}
|
||||
|
||||
//! Get the number of values in the range
|
||||
size_t size() const
|
||||
{
|
||||
size_t size() const {
|
||||
if (std::is_integral<TYPE>::value) {
|
||||
return (static_cast<int64_t>(j) - static_cast<int64_t>(i)) /
|
||||
static_cast<int64_t>(k);
|
||||
|
@ -88,10 +79,8 @@ public:
|
|||
TYPE i, j, k;
|
||||
};
|
||||
|
||||
|
||||
//! Simple class to store the array dimensions
|
||||
class ArraySize final
|
||||
{
|
||||
class ArraySize final {
|
||||
public:
|
||||
//! Empty constructor
|
||||
ArraySize() : d_ndim(1), d_length(0), d_N{0, 1, 1, 1, 1} {}
|
||||
|
@ -108,9 +97,7 @@ public:
|
|||
* @param N2 Number of elements in the second dimension
|
||||
*/
|
||||
ArraySize(size_t N1, size_t N2)
|
||||
: d_ndim( 2 ), d_length( N1 * N2 ), d_N{ N1, N2, 1, 1, 1 }
|
||||
{
|
||||
}
|
||||
: d_ndim(2), d_length(N1 * N2), d_N{N1, N2, 1, 1, 1} {}
|
||||
|
||||
/*!
|
||||
* Create the vector size
|
||||
|
@ -119,9 +106,7 @@ public:
|
|||
* @param N3 Number of elements in the third dimension
|
||||
*/
|
||||
ArraySize(size_t N1, size_t N2, size_t N3)
|
||||
: d_ndim( 3 ), d_length( N1 * N2 * N3 ), d_N{ N1, N2, N3, 1, 1 }
|
||||
{
|
||||
}
|
||||
: d_ndim(3), d_length(N1 * N2 * N3), d_N{N1, N2, N3, 1, 1} {}
|
||||
|
||||
/*!
|
||||
* Create the vector size
|
||||
|
@ -131,9 +116,7 @@ public:
|
|||
* @param N4 Number of elements in the fourth dimension
|
||||
*/
|
||||
ArraySize(size_t N1, size_t N2, size_t N3, size_t N4)
|
||||
: d_ndim( 4 ), d_length( N1 * N2 * N3 * N4 ), d_N{ N1, N2, N3, N4, 1 }
|
||||
{
|
||||
}
|
||||
: d_ndim(4), d_length(N1 * N2 * N3 * N4), d_N{N1, N2, N3, N4, 1} {}
|
||||
|
||||
/*!
|
||||
* Create the vector size
|
||||
|
@ -144,8 +127,7 @@ public:
|
|||
* @param N5 Number of elements in the fifth dimension
|
||||
*/
|
||||
ArraySize(size_t N1, size_t N2, size_t N3, size_t N4, size_t N5)
|
||||
: d_ndim( 5 ), d_length( N1 * N2 * N3 * N4 * N5 ), d_N{ N1, N2, N3, N4, N5 }
|
||||
{
|
||||
: d_ndim(5), d_length(N1 * N2 * N3 * N4 * N5), d_N{N1, N2, N3, N4, N5} {
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -154,8 +136,7 @@ public:
|
|||
* @param ndim Number of dimensions
|
||||
*/
|
||||
ArraySize(std::initializer_list<size_t> N, int ndim = -1)
|
||||
: d_ndim( N.size() ), d_length( 0 ), d_N{ 0, 1, 1, 1, 1 }
|
||||
{
|
||||
: d_ndim(N.size()), d_length(0), d_N{0, 1, 1, 1, 1} {
|
||||
if (ndim >= 0)
|
||||
d_ndim = ndim;
|
||||
if (d_ndim > 5)
|
||||
|
@ -170,15 +151,13 @@ public:
|
|||
d_length = 0;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* Create from raw pointer
|
||||
* @param ndim Number of dimensions
|
||||
* @param dims Dimensions
|
||||
*/
|
||||
ArraySize(size_t ndim, const size_t *dims)
|
||||
: d_ndim( ndim ), d_length( 0 ), d_N{ 0, 1, 1, 1, 1 }
|
||||
{
|
||||
: d_ndim(ndim), d_length(0), d_N{0, 1, 1, 1, 1} {
|
||||
if (d_ndim > 5)
|
||||
throw std::out_of_range("Maximum number of dimensions exceeded");
|
||||
for (size_t i = 0; i < ndim; i++)
|
||||
|
@ -195,15 +174,14 @@ public:
|
|||
* @param N Size of the array
|
||||
*/
|
||||
template <std::size_t NDIM>
|
||||
ArraySize( const std::array<size_t, NDIM> &N ) : ArraySize( NDIM, N.data() )
|
||||
{
|
||||
}
|
||||
ArraySize(const std::array<size_t, NDIM> &N) : ArraySize(NDIM, N.data()) {}
|
||||
|
||||
/*!
|
||||
* Create from std::vector
|
||||
* @param N Size of the array
|
||||
*/
|
||||
inline ArraySize( const std::vector<size_t> &N ) : ArraySize( N.size(), N.data() ) {}
|
||||
inline ArraySize(const std::vector<size_t> &N)
|
||||
: ArraySize(N.size(), N.data()) {}
|
||||
|
||||
// Copy/assignment constructors
|
||||
ArraySize(ArraySize &&rhs) = default;
|
||||
|
@ -227,8 +205,7 @@ public:
|
|||
ARRAY_ATTRIBUTE size_t length() const { return d_length; }
|
||||
|
||||
//! Resize the dimension
|
||||
void resize( uint8_t dim, size_t N )
|
||||
{
|
||||
void resize(uint8_t dim, size_t N) {
|
||||
if (dim >= d_ndim)
|
||||
throw std::out_of_range("Invalid dimension");
|
||||
d_N[dim] = N;
|
||||
|
@ -247,8 +224,7 @@ public:
|
|||
/*!
|
||||
* Remove singleton dimensions
|
||||
*/
|
||||
void squeeze()
|
||||
{
|
||||
void squeeze() {
|
||||
d_ndim = 0;
|
||||
for (uint8_t i = 0; i < maxDim(); i++) {
|
||||
if (d_N[i] != 1)
|
||||
|
@ -263,20 +239,18 @@ public:
|
|||
const size_t *end() const { return d_N + d_ndim; }
|
||||
|
||||
// Check if two array sizes are equal
|
||||
ARRAY_ATTRIBUTE bool operator==( const ArraySize &rhs ) const
|
||||
{
|
||||
ARRAY_ATTRIBUTE bool operator==(const ArraySize &rhs) const {
|
||||
return d_ndim == rhs.d_ndim && memcmp(d_N, rhs.d_N, sizeof(d_N)) == 0;
|
||||
}
|
||||
|
||||
// Check if two array sizes are equal (ignoring the dimension)
|
||||
ARRAY_ATTRIBUTE bool approxEqual( const ArraySize &rhs ) const
|
||||
{
|
||||
return ( length() == 0 && rhs.length() == 0 ) || memcmp( d_N, rhs.d_N, sizeof( d_N ) ) == 0;
|
||||
ARRAY_ATTRIBUTE bool approxEqual(const ArraySize &rhs) const {
|
||||
return (length() == 0 && rhs.length() == 0) ||
|
||||
memcmp(d_N, rhs.d_N, sizeof(d_N)) == 0;
|
||||
}
|
||||
|
||||
//! Check if two matrices are not equal
|
||||
ARRAY_ATTRIBUTE bool operator!=( const ArraySize &rhs ) const
|
||||
{
|
||||
ARRAY_ATTRIBUTE bool operator!=(const ArraySize &rhs) const {
|
||||
return d_ndim != rhs.d_ndim || memcmp(d_N, rhs.d_N, sizeof(d_N)) != 0;
|
||||
}
|
||||
|
||||
|
@ -284,48 +258,44 @@ public:
|
|||
ARRAY_ATTRIBUTE static uint8_t maxDim() { return 5; }
|
||||
|
||||
//! Get the index
|
||||
ARRAY_ATTRIBUTE size_t index( size_t i ) const
|
||||
{
|
||||
ARRAY_ATTRIBUTE size_t index(size_t i) const {
|
||||
CHECK_ARRAY_LENGTH(i, d_length);
|
||||
return i;
|
||||
}
|
||||
|
||||
//! Get the index
|
||||
ARRAY_ATTRIBUTE size_t index( size_t i1, size_t i2 ) const
|
||||
{
|
||||
ARRAY_ATTRIBUTE size_t index(size_t i1, size_t i2) const {
|
||||
size_t index = i1 + i2 * d_N[0];
|
||||
CHECK_ARRAY_LENGTH(index, d_length);
|
||||
return index;
|
||||
}
|
||||
|
||||
//! Get the index
|
||||
ARRAY_ATTRIBUTE size_t index( size_t i1, size_t i2, size_t i3 ) const
|
||||
{
|
||||
ARRAY_ATTRIBUTE size_t index(size_t i1, size_t i2, size_t i3) const {
|
||||
size_t index = i1 + d_N[0] * (i2 + d_N[1] * i3);
|
||||
CHECK_ARRAY_LENGTH(index, d_length);
|
||||
return index;
|
||||
}
|
||||
|
||||
//! Get the index
|
||||
ARRAY_ATTRIBUTE size_t index( size_t i1, size_t i2, size_t i3, size_t i4 ) const
|
||||
{
|
||||
ARRAY_ATTRIBUTE size_t index(size_t i1, size_t i2, size_t i3,
|
||||
size_t i4) const {
|
||||
size_t index = i1 + d_N[0] * (i2 + d_N[1] * (i3 + d_N[2] * i4));
|
||||
CHECK_ARRAY_LENGTH(index, d_length);
|
||||
return index;
|
||||
}
|
||||
|
||||
//! Get the index
|
||||
ARRAY_ATTRIBUTE size_t
|
||||
index( size_t i1, size_t i2, size_t i3, size_t i4, size_t i5 ) const
|
||||
{
|
||||
size_t index = i1 + d_N[0] * ( i2 + d_N[1] * ( i3 + d_N[2] * ( i4 + d_N[3] * i5 ) ) );
|
||||
ARRAY_ATTRIBUTE size_t index(size_t i1, size_t i2, size_t i3, size_t i4,
|
||||
size_t i5) const {
|
||||
size_t index =
|
||||
i1 + d_N[0] * (i2 + d_N[1] * (i3 + d_N[2] * (i4 + d_N[3] * i5)));
|
||||
CHECK_ARRAY_LENGTH(index, d_length);
|
||||
return index;
|
||||
}
|
||||
|
||||
//! Get the index
|
||||
size_t index( const std::array<size_t, 5> &i ) const
|
||||
{
|
||||
size_t index(const std::array<size_t, 5> &i) const {
|
||||
size_t j = 0;
|
||||
for (size_t m = 0, N = 1; m < 5; m++) {
|
||||
j += i[m] * N;
|
||||
|
@ -335,8 +305,7 @@ public:
|
|||
}
|
||||
|
||||
//! Get the index
|
||||
size_t index( std::initializer_list<size_t> i ) const
|
||||
{
|
||||
size_t index(std::initializer_list<size_t> i) const {
|
||||
size_t N = 1;
|
||||
size_t j = 0;
|
||||
size_t m = 0;
|
||||
|
@ -348,8 +317,7 @@ public:
|
|||
}
|
||||
|
||||
//! Convert the index to ijk values
|
||||
std::array<size_t, 5> ijk( size_t index ) const
|
||||
{
|
||||
std::array<size_t, 5> ijk(size_t index) const {
|
||||
CHECK_ARRAY_LENGTH(index, d_length);
|
||||
size_t i0 = index % d_N[0];
|
||||
index = index / d_N[0];
|
||||
|
@ -363,8 +331,7 @@ public:
|
|||
}
|
||||
|
||||
//! Convert the index to ijk values
|
||||
void ijk( size_t index, size_t *x ) const
|
||||
{
|
||||
void ijk(size_t index, size_t *x) const {
|
||||
CHECK_ARRAY_LENGTH(index, d_length);
|
||||
x[0] = index % d_N[0];
|
||||
index = index / d_N[0];
|
||||
|
@ -383,10 +350,8 @@ private:
|
|||
size_t d_N[5];
|
||||
};
|
||||
|
||||
|
||||
// Function to concatenate dimensions of two array sizes
|
||||
inline ArraySize cat( const ArraySize &x, const ArraySize &y )
|
||||
{
|
||||
inline ArraySize cat(const ArraySize &x, const ArraySize &y) {
|
||||
if (x.ndim() + y.ndim() > 5)
|
||||
throw std::out_of_range("Maximum number of dimensions exceeded");
|
||||
size_t N[5] = {0};
|
||||
|
@ -397,30 +362,24 @@ inline ArraySize cat( const ArraySize &x, const ArraySize &y )
|
|||
return ArraySize(x.ndim() + y.ndim(), N);
|
||||
}
|
||||
|
||||
|
||||
// Operator overloads
|
||||
inline ArraySize operator*( size_t v, const ArraySize &x )
|
||||
{
|
||||
inline ArraySize operator*(size_t v, const ArraySize &x) {
|
||||
size_t N[5] = {v * x[0], v * x[1], v * x[2], v * x[3], v * x[4]};
|
||||
return ArraySize(x.ndim(), N);
|
||||
}
|
||||
inline ArraySize operator*( const ArraySize &x, size_t v )
|
||||
{
|
||||
inline ArraySize operator*(const ArraySize &x, size_t v) {
|
||||
size_t N[5] = {v * x[0], v * x[1], v * x[2], v * x[3], v * x[4]};
|
||||
return ArraySize(x.ndim(), N);
|
||||
}
|
||||
inline ArraySize operator-( const ArraySize &x, size_t v )
|
||||
{
|
||||
inline ArraySize operator-(const ArraySize &x, size_t v) {
|
||||
size_t N[5] = {x[0] - v, x[1] - v, x[2] - v, x[3] - v, x[4] - v};
|
||||
return ArraySize(x.ndim(), N);
|
||||
}
|
||||
inline ArraySize operator+( const ArraySize &x, size_t v )
|
||||
{
|
||||
inline ArraySize operator+(const ArraySize &x, size_t v) {
|
||||
size_t N[5] = {x[0] + v, x[1] + v, x[2] + v, x[3] + v, x[4] + v};
|
||||
return ArraySize(x.ndim(), N);
|
||||
}
|
||||
inline ArraySize operator+( size_t v, const ArraySize &x )
|
||||
{
|
||||
inline ArraySize operator+(size_t v, const ArraySize &x) {
|
||||
size_t N[5] = {x[0] + v, x[1] + v, x[2] + v, x[3] + v, x[4] + v};
|
||||
return ArraySize(x.ndim(), N);
|
||||
}
|
||||
|
@ -429,5 +388,4 @@ inline ArraySize operator+( size_t v, const ArraySize &x )
|
|||
ENABLE_WARNINGS
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,18 +1,31 @@
|
|||
#include "common/Communication.h"
|
||||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "common/Communication.h"
|
||||
|
||||
/********************************************************
|
||||
* Structure to store the rank info *
|
||||
********************************************************/
|
||||
int RankInfoStruct::getRankForBlock( int i, int j, int k ) const
|
||||
{
|
||||
int RankInfoStruct::getRankForBlock(int i, int j, int k) const {
|
||||
int i2 = (i + nx) % nx;
|
||||
int j2 = (j + ny) % ny;
|
||||
int k2 = (k + nz) % nz;
|
||||
return i2 + j2 * nx + k2 * nx * ny;
|
||||
}
|
||||
RankInfoStruct::RankInfoStruct()
|
||||
{
|
||||
RankInfoStruct::RankInfoStruct() {
|
||||
nx = 0;
|
||||
ny = 0;
|
||||
nz = 0;
|
||||
|
@ -27,8 +40,7 @@ RankInfoStruct::RankInfoStruct()
|
|||
}
|
||||
}
|
||||
}
|
||||
RankInfoStruct::RankInfoStruct( int rank0, int nprocx, int nprocy, int nprocz )
|
||||
{
|
||||
RankInfoStruct::RankInfoStruct(int rank0, int nprocx, int nprocy, int nprocz) {
|
||||
memset(this, 0, sizeof(RankInfoStruct));
|
||||
nx = nprocx;
|
||||
ny = nprocy;
|
||||
|
@ -51,7 +63,8 @@ RankInfoStruct::RankInfoStruct( int rank0, int nprocx, int nprocy, int nprocz )
|
|||
for (int i = -1; i <= 1; i++) {
|
||||
for (int j = -1; j <= 1; j++) {
|
||||
for (int k = -1; k <= 1; k++) {
|
||||
rank[i+1][j+1][k+1] = getRankForBlock(ix+i,jy+j,kz+k);
|
||||
rank[i + 1][j + 1][k + 1] =
|
||||
getRankForBlock(ix + i, jy + j, kz + k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,18 +72,16 @@ RankInfoStruct::RankInfoStruct( int rank0, int nprocx, int nprocy, int nprocz )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Deprecated functions *
|
||||
********************************************************/
|
||||
void InitializeRanks( const int rank, const int nprocx, const int nprocy, const int nprocz,
|
||||
int& iproc, int& jproc, int& kproc,
|
||||
int& rank_x, int& rank_y, int& rank_z,
|
||||
int& rank_X, int& rank_Y, int& rank_Z,
|
||||
int& rank_xy, int& rank_XY, int& rank_xY, int& rank_Xy,
|
||||
int& rank_xz, int& rank_XZ, int& rank_xZ, int& rank_Xz,
|
||||
int& rank_yz, int& rank_YZ, int& rank_yZ, int& rank_Yz )
|
||||
{
|
||||
void InitializeRanks(const int rank, const int nprocx, const int nprocy,
|
||||
const int nprocz, int &iproc, int &jproc, int &kproc,
|
||||
int &rank_x, int &rank_y, int &rank_z, int &rank_X,
|
||||
int &rank_Y, int &rank_Z, int &rank_xy, int &rank_XY,
|
||||
int &rank_xY, int &rank_Xy, int &rank_xz, int &rank_XZ,
|
||||
int &rank_xZ, int &rank_Xz, int &rank_yz, int &rank_YZ,
|
||||
int &rank_yZ, int &rank_Yz) {
|
||||
const RankInfoStruct data(rank, nprocx, nprocy, nprocz);
|
||||
iproc = data.ix;
|
||||
jproc = data.jy;
|
||||
|
@ -94,6 +105,3 @@ void InitializeRanks( const int rank, const int nprocx, const int nprocy, const
|
|||
rank_Yz = data.rank[1][2][0];
|
||||
rank_yZ = data.rank[1][0][2];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef COMMUNICATION_H_INC
|
||||
#define COMMUNICATION_H_INC
|
||||
|
||||
|
@ -16,7 +32,6 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Rank info structure
|
||||
* @details Structure used to hold the ranks for the current process and it's neighbors
|
||||
|
@ -34,20 +49,18 @@ struct RankInfoStruct {
|
|||
int getRankForBlock(int i, int j, int k) const;
|
||||
};
|
||||
|
||||
|
||||
//! Redistribute domain data (dst may be smaller than the src)
|
||||
template <class TYPE>
|
||||
Array<TYPE> redistribute( const RankInfoStruct& src_rank, const Array<TYPE>& src_data,
|
||||
const RankInfoStruct& dst_rank, std::array<int,3> dst_size, const Utilities::MPI& comm );
|
||||
|
||||
Array<TYPE>
|
||||
redistribute(const RankInfoStruct &src_rank, const Array<TYPE> &src_data,
|
||||
const RankInfoStruct &dst_rank, std::array<int, 3> dst_size,
|
||||
const Utilities::MPI &comm);
|
||||
|
||||
/*!
|
||||
* @brief Communicate halo
|
||||
* @details Fill the halo cells in an array from the neighboring processes
|
||||
*/
|
||||
template<class TYPE>
|
||||
class fillHalo
|
||||
{
|
||||
template <class TYPE> class fillHalo {
|
||||
public:
|
||||
/*!
|
||||
* @brief Default constructor
|
||||
|
@ -86,7 +99,6 @@ public:
|
|||
template <class TYPE1, class TYPE2>
|
||||
void copy(const Array<TYPE1> &src, Array<TYPE2> &dst);
|
||||
|
||||
|
||||
private:
|
||||
Utilities::MPI comm;
|
||||
RankInfoStruct info;
|
||||
|
@ -102,9 +114,9 @@ private:
|
|||
void unpack(Array<TYPE> &array, int i, int j, int k, const TYPE *buffer);
|
||||
};
|
||||
|
||||
|
||||
//***************************************************************************************
|
||||
inline void PackMeshData(const int *list, int count, double *sendbuf, double *data){
|
||||
inline void PackMeshData(const int *list, int count, double *sendbuf,
|
||||
double *data) {
|
||||
// Fill in the phase ID values from neighboring processors
|
||||
// This packs up the values that need to be sent from one processor to another
|
||||
int idx, n;
|
||||
|
@ -113,7 +125,8 @@ inline void PackMeshData(const int *list, int count, double *sendbuf, double *da
|
|||
sendbuf[idx] = data[n];
|
||||
}
|
||||
}
|
||||
inline void UnpackMeshData(const int *list, int count, double *recvbuf, double *data){
|
||||
inline void UnpackMeshData(const int *list, int count, double *recvbuf,
|
||||
double *data) {
|
||||
// Fill in the phase ID values from neighboring processors
|
||||
// This unpacks the values once they have been recieved from neighbors
|
||||
int idx, n;
|
||||
|
@ -124,35 +137,31 @@ inline void UnpackMeshData(const int *list, int count, double *recvbuf, double *
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Initialize the ranks (this is deprecated, see RankInfoStruct)
|
||||
void InitializeRanks( const int rank, const int nprocx, const int nprocy, const int nprocz,
|
||||
int& iproc, int& jproc, int& kproc,
|
||||
int& rank_x, int& rank_y, int& rank_z,
|
||||
int& rank_X, int& rank_Y, int& rank_Z,
|
||||
int& rank_xy, int& rank_XY, int& rank_xY, int& rank_Xy,
|
||||
int& rank_xz, int& rank_XZ, int& rank_xZ, int& rank_Xz,
|
||||
int& rank_yz, int& rank_YZ, int& rank_yZ, int& rank_Yz );
|
||||
|
||||
void InitializeRanks(const int rank, const int nprocx, const int nprocy,
|
||||
const int nprocz, int &iproc, int &jproc, int &kproc,
|
||||
int &rank_x, int &rank_y, int &rank_z, int &rank_X,
|
||||
int &rank_Y, int &rank_Z, int &rank_xy, int &rank_XY,
|
||||
int &rank_xY, int &rank_Xy, int &rank_xz, int &rank_XZ,
|
||||
int &rank_xZ, int &rank_Xz, int &rank_yz, int &rank_YZ,
|
||||
int &rank_yZ, int &rank_Yz);
|
||||
|
||||
//***************************************************************************************
|
||||
inline void CommunicateSendRecvCounts( const Utilities::MPI& comm, int sendtag, int recvtag,
|
||||
int rank_x, int rank_y, int rank_z,
|
||||
int rank_X, int rank_Y, int rank_Z,
|
||||
int rank_xy, int rank_XY, int rank_xY, int rank_Xy,
|
||||
int rank_xz, int rank_XZ, int rank_xZ, int rank_Xz,
|
||||
int rank_yz, int rank_YZ, int rank_yZ, int rank_Yz,
|
||||
int sendCount_x, int sendCount_y, int sendCount_z,
|
||||
int sendCount_X, int sendCount_Y, int sendCount_Z,
|
||||
int sendCount_xy, int sendCount_XY, int sendCount_xY, int sendCount_Xy,
|
||||
int sendCount_xz, int sendCount_XZ, int sendCount_xZ, int sendCount_Xz,
|
||||
int sendCount_yz, int sendCount_YZ, int sendCount_yZ, int sendCount_Yz,
|
||||
int& recvCount_x, int& recvCount_y, int& recvCount_z,
|
||||
int& recvCount_X, int& recvCount_Y, int& recvCount_Z,
|
||||
int& recvCount_xy, int& recvCount_XY, int& recvCount_xY, int& recvCount_Xy,
|
||||
int& recvCount_xz, int& recvCount_XZ, int& recvCount_xZ, int& recvCount_Xz,
|
||||
int& recvCount_yz, int& recvCount_YZ, int& recvCount_yZ, int& recvCount_Yz )
|
||||
{
|
||||
inline void CommunicateSendRecvCounts(
|
||||
const Utilities::MPI &comm, int sendtag, int recvtag, int rank_x,
|
||||
int rank_y, int rank_z, int rank_X, int rank_Y, int rank_Z, int rank_xy,
|
||||
int rank_XY, int rank_xY, int rank_Xy, int rank_xz, int rank_XZ,
|
||||
int rank_xZ, int rank_Xz, int rank_yz, int rank_YZ, int rank_yZ,
|
||||
int rank_Yz, int sendCount_x, int sendCount_y, int sendCount_z,
|
||||
int sendCount_X, int sendCount_Y, int sendCount_Z, int sendCount_xy,
|
||||
int sendCount_XY, int sendCount_xY, int sendCount_Xy, int sendCount_xz,
|
||||
int sendCount_XZ, int sendCount_xZ, int sendCount_Xz, int sendCount_yz,
|
||||
int sendCount_YZ, int sendCount_yZ, int sendCount_Yz, int &recvCount_x,
|
||||
int &recvCount_y, int &recvCount_z, int &recvCount_X, int &recvCount_Y,
|
||||
int &recvCount_Z, int &recvCount_xy, int &recvCount_XY, int &recvCount_xY,
|
||||
int &recvCount_Xy, int &recvCount_xz, int &recvCount_XZ, int &recvCount_xZ,
|
||||
int &recvCount_Xz, int &recvCount_yz, int &recvCount_YZ, int &recvCount_yZ,
|
||||
int &recvCount_Yz) {
|
||||
MPI_Request req1[18], req2[18];
|
||||
req1[0] = comm.Isend(&sendCount_x, 1, rank_x, sendtag + 0);
|
||||
req2[0] = comm.Irecv(&recvCount_X, 1, rank_X, recvtag + 0);
|
||||
|
@ -198,7 +207,6 @@ inline void CommunicateSendRecvCounts( const Utilities::MPI& comm, int sendtag,
|
|||
comm.barrier();
|
||||
}
|
||||
|
||||
|
||||
//***************************************************************************************
|
||||
inline void CommunicateRecvLists( const Utilities::MPI& comm, int sendtag, int recvtag,
|
||||
int *sendList_x, int *sendList_y, int *sendList_z, int *sendList_X, int *sendList_Y, int *sendList_Z,
|
||||
|
@ -264,36 +272,41 @@ inline void CommunicateRecvLists( const Utilities::MPI& comm, int sendtag, int r
|
|||
comm.waitAll( 18, req2 );
|
||||
}
|
||||
|
||||
|
||||
//***************************************************************************************
|
||||
inline void CommunicateMeshHalo(DoubleArray &Mesh, const Utilities::MPI& comm,
|
||||
double *sendbuf_x,double *sendbuf_y,double *sendbuf_z,double *sendbuf_X,double *sendbuf_Y,double *sendbuf_Z,
|
||||
double *sendbuf_xy,double *sendbuf_XY,double *sendbuf_xY,double *sendbuf_Xy,
|
||||
double *sendbuf_xz,double *sendbuf_XZ,double *sendbuf_xZ,double *sendbuf_Xz,
|
||||
double *sendbuf_yz,double *sendbuf_YZ,double *sendbuf_yZ,double *sendbuf_Yz,
|
||||
double *recvbuf_x,double *recvbuf_y,double *recvbuf_z,double *recvbuf_X,double *recvbuf_Y,double *recvbuf_Z,
|
||||
double *recvbuf_xy,double *recvbuf_XY,double *recvbuf_xY,double *recvbuf_Xy,
|
||||
double *recvbuf_xz,double *recvbuf_XZ,double *recvbuf_xZ,double *recvbuf_Xz,
|
||||
double *recvbuf_yz,double *recvbuf_YZ,double *recvbuf_yZ,double *recvbuf_Yz,
|
||||
int *sendList_x,int *sendList_y,int *sendList_z,int *sendList_X,int *sendList_Y,int *sendList_Z,
|
||||
inline void CommunicateMeshHalo(
|
||||
DoubleArray &Mesh, const Utilities::MPI &comm, double *sendbuf_x,
|
||||
double *sendbuf_y, double *sendbuf_z, double *sendbuf_X, double *sendbuf_Y,
|
||||
double *sendbuf_Z, double *sendbuf_xy, double *sendbuf_XY,
|
||||
double *sendbuf_xY, double *sendbuf_Xy, double *sendbuf_xz,
|
||||
double *sendbuf_XZ, double *sendbuf_xZ, double *sendbuf_Xz,
|
||||
double *sendbuf_yz, double *sendbuf_YZ, double *sendbuf_yZ,
|
||||
double *sendbuf_Yz, double *recvbuf_x, double *recvbuf_y, double *recvbuf_z,
|
||||
double *recvbuf_X, double *recvbuf_Y, double *recvbuf_Z, double *recvbuf_xy,
|
||||
double *recvbuf_XY, double *recvbuf_xY, double *recvbuf_Xy,
|
||||
double *recvbuf_xz, double *recvbuf_XZ, double *recvbuf_xZ,
|
||||
double *recvbuf_Xz, double *recvbuf_yz, double *recvbuf_YZ,
|
||||
double *recvbuf_yZ, double *recvbuf_Yz, int *sendList_x, int *sendList_y,
|
||||
int *sendList_z, int *sendList_X, int *sendList_Y, int *sendList_Z,
|
||||
int *sendList_xy, int *sendList_XY, int *sendList_xY, int *sendList_Xy,
|
||||
int *sendList_xz, int *sendList_XZ, int *sendList_xZ, int *sendList_Xz,
|
||||
int *sendList_yz, int *sendList_YZ, int *sendList_yZ, int *sendList_Yz,
|
||||
int sendCount_x,int sendCount_y,int sendCount_z,int sendCount_X,int sendCount_Y,int sendCount_Z,
|
||||
int sendCount_xy,int sendCount_XY,int sendCount_xY,int sendCount_Xy,
|
||||
int sendCount_xz,int sendCount_XZ,int sendCount_xZ,int sendCount_Xz,
|
||||
int sendCount_yz,int sendCount_YZ,int sendCount_yZ,int sendCount_Yz,
|
||||
int *recvList_x,int *recvList_y,int *recvList_z,int *recvList_X,int *recvList_Y,int *recvList_Z,
|
||||
int sendCount_x, int sendCount_y, int sendCount_z, int sendCount_X,
|
||||
int sendCount_Y, int sendCount_Z, int sendCount_xy, int sendCount_XY,
|
||||
int sendCount_xY, int sendCount_Xy, int sendCount_xz, int sendCount_XZ,
|
||||
int sendCount_xZ, int sendCount_Xz, int sendCount_yz, int sendCount_YZ,
|
||||
int sendCount_yZ, int sendCount_Yz, int *recvList_x, int *recvList_y,
|
||||
int *recvList_z, int *recvList_X, int *recvList_Y, int *recvList_Z,
|
||||
int *recvList_xy, int *recvList_XY, int *recvList_xY, int *recvList_Xy,
|
||||
int *recvList_xz, int *recvList_XZ, int *recvList_xZ, int *recvList_Xz,
|
||||
int *recvList_yz, int *recvList_YZ, int *recvList_yZ, int *recvList_Yz,
|
||||
int recvCount_x,int recvCount_y,int recvCount_z,int recvCount_X,int recvCount_Y,int recvCount_Z,
|
||||
int recvCount_xy,int recvCount_XY,int recvCount_xY,int recvCount_Xy,
|
||||
int recvCount_xz,int recvCount_XZ,int recvCount_xZ,int recvCount_Xz,
|
||||
int recvCount_yz,int recvCount_YZ,int recvCount_yZ,int recvCount_Yz,
|
||||
int rank_x,int rank_y,int rank_z,int rank_X,int rank_Y,int rank_Z,int rank_xy,int rank_XY,int rank_xY,
|
||||
int rank_Xy,int rank_xz,int rank_XZ,int rank_xZ,int rank_Xz,int rank_yz,int rank_YZ,int rank_yZ,int rank_Yz)
|
||||
{
|
||||
int recvCount_x, int recvCount_y, int recvCount_z, int recvCount_X,
|
||||
int recvCount_Y, int recvCount_Z, int recvCount_xy, int recvCount_XY,
|
||||
int recvCount_xY, int recvCount_Xy, int recvCount_xz, int recvCount_XZ,
|
||||
int recvCount_xZ, int recvCount_Xz, int recvCount_yz, int recvCount_YZ,
|
||||
int recvCount_yZ, int recvCount_Yz, int rank_x, int rank_y, int rank_z,
|
||||
int rank_X, int rank_Y, int rank_Z, int rank_xy, int rank_XY, int rank_xY,
|
||||
int rank_Xy, int rank_xz, int rank_XZ, int rank_xZ, int rank_Xz,
|
||||
int rank_yz, int rank_YZ, int rank_yZ, int rank_Yz) {
|
||||
int sendtag, recvtag;
|
||||
sendtag = recvtag = 7;
|
||||
double *MeshData = Mesh.data();
|
||||
|
@ -316,24 +329,42 @@ inline void CommunicateMeshHalo(DoubleArray &Mesh, const Utilities::MPI& comm,
|
|||
PackMeshData(sendList_yZ, sendCount_yZ, sendbuf_yZ, MeshData);
|
||||
PackMeshData(sendList_YZ, sendCount_YZ, sendbuf_YZ, MeshData);
|
||||
//......................................................................................
|
||||
comm.sendrecv(sendbuf_x,sendCount_x,rank_x,sendtag,recvbuf_X,recvCount_X,rank_X,recvtag);
|
||||
comm.sendrecv(sendbuf_X,sendCount_X,rank_X,sendtag,recvbuf_x,recvCount_x,rank_x,recvtag);
|
||||
comm.sendrecv(sendbuf_y,sendCount_y,rank_y,sendtag,recvbuf_Y,recvCount_Y,rank_Y,recvtag);
|
||||
comm.sendrecv(sendbuf_Y,sendCount_Y,rank_Y,sendtag,recvbuf_y,recvCount_y,rank_y,recvtag);
|
||||
comm.sendrecv(sendbuf_z,sendCount_z,rank_z,sendtag,recvbuf_Z,recvCount_Z,rank_Z,recvtag);
|
||||
comm.sendrecv(sendbuf_Z,sendCount_Z,rank_Z,sendtag,recvbuf_z,recvCount_z,rank_z,recvtag);
|
||||
comm.sendrecv(sendbuf_xy,sendCount_xy,rank_xy,sendtag,recvbuf_XY,recvCount_XY,rank_XY,recvtag);
|
||||
comm.sendrecv(sendbuf_XY,sendCount_XY,rank_XY,sendtag,recvbuf_xy,recvCount_xy,rank_xy,recvtag);
|
||||
comm.sendrecv(sendbuf_Xy,sendCount_Xy,rank_Xy,sendtag,recvbuf_xY,recvCount_xY,rank_xY,recvtag);
|
||||
comm.sendrecv(sendbuf_xY,sendCount_xY,rank_xY,sendtag,recvbuf_Xy,recvCount_Xy,rank_Xy,recvtag);
|
||||
comm.sendrecv(sendbuf_xz,sendCount_xz,rank_xz,sendtag,recvbuf_XZ,recvCount_XZ,rank_XZ,recvtag);
|
||||
comm.sendrecv(sendbuf_XZ,sendCount_XZ,rank_XZ,sendtag,recvbuf_xz,recvCount_xz,rank_xz,recvtag);
|
||||
comm.sendrecv(sendbuf_Xz,sendCount_Xz,rank_Xz,sendtag,recvbuf_xZ,recvCount_xZ,rank_xZ,recvtag);
|
||||
comm.sendrecv(sendbuf_xZ,sendCount_xZ,rank_xZ,sendtag,recvbuf_Xz,recvCount_Xz,rank_Xz,recvtag);
|
||||
comm.sendrecv(sendbuf_yz,sendCount_yz,rank_yz,sendtag,recvbuf_YZ,recvCount_YZ,rank_YZ,recvtag);
|
||||
comm.sendrecv(sendbuf_YZ,sendCount_YZ,rank_YZ,sendtag,recvbuf_yz,recvCount_yz,rank_yz,recvtag);
|
||||
comm.sendrecv(sendbuf_Yz,sendCount_Yz,rank_Yz,sendtag,recvbuf_yZ,recvCount_yZ,rank_yZ,recvtag);
|
||||
comm.sendrecv(sendbuf_yZ,sendCount_yZ,rank_yZ,sendtag,recvbuf_Yz,recvCount_Yz,rank_Yz,recvtag);
|
||||
comm.sendrecv(sendbuf_x, sendCount_x, rank_x, sendtag, recvbuf_X,
|
||||
recvCount_X, rank_X, recvtag);
|
||||
comm.sendrecv(sendbuf_X, sendCount_X, rank_X, sendtag, recvbuf_x,
|
||||
recvCount_x, rank_x, recvtag);
|
||||
comm.sendrecv(sendbuf_y, sendCount_y, rank_y, sendtag, recvbuf_Y,
|
||||
recvCount_Y, rank_Y, recvtag);
|
||||
comm.sendrecv(sendbuf_Y, sendCount_Y, rank_Y, sendtag, recvbuf_y,
|
||||
recvCount_y, rank_y, recvtag);
|
||||
comm.sendrecv(sendbuf_z, sendCount_z, rank_z, sendtag, recvbuf_Z,
|
||||
recvCount_Z, rank_Z, recvtag);
|
||||
comm.sendrecv(sendbuf_Z, sendCount_Z, rank_Z, sendtag, recvbuf_z,
|
||||
recvCount_z, rank_z, recvtag);
|
||||
comm.sendrecv(sendbuf_xy, sendCount_xy, rank_xy, sendtag, recvbuf_XY,
|
||||
recvCount_XY, rank_XY, recvtag);
|
||||
comm.sendrecv(sendbuf_XY, sendCount_XY, rank_XY, sendtag, recvbuf_xy,
|
||||
recvCount_xy, rank_xy, recvtag);
|
||||
comm.sendrecv(sendbuf_Xy, sendCount_Xy, rank_Xy, sendtag, recvbuf_xY,
|
||||
recvCount_xY, rank_xY, recvtag);
|
||||
comm.sendrecv(sendbuf_xY, sendCount_xY, rank_xY, sendtag, recvbuf_Xy,
|
||||
recvCount_Xy, rank_Xy, recvtag);
|
||||
comm.sendrecv(sendbuf_xz, sendCount_xz, rank_xz, sendtag, recvbuf_XZ,
|
||||
recvCount_XZ, rank_XZ, recvtag);
|
||||
comm.sendrecv(sendbuf_XZ, sendCount_XZ, rank_XZ, sendtag, recvbuf_xz,
|
||||
recvCount_xz, rank_xz, recvtag);
|
||||
comm.sendrecv(sendbuf_Xz, sendCount_Xz, rank_Xz, sendtag, recvbuf_xZ,
|
||||
recvCount_xZ, rank_xZ, recvtag);
|
||||
comm.sendrecv(sendbuf_xZ, sendCount_xZ, rank_xZ, sendtag, recvbuf_Xz,
|
||||
recvCount_Xz, rank_Xz, recvtag);
|
||||
comm.sendrecv(sendbuf_yz, sendCount_yz, rank_yz, sendtag, recvbuf_YZ,
|
||||
recvCount_YZ, rank_YZ, recvtag);
|
||||
comm.sendrecv(sendbuf_YZ, sendCount_YZ, rank_YZ, sendtag, recvbuf_yz,
|
||||
recvCount_yz, rank_yz, recvtag);
|
||||
comm.sendrecv(sendbuf_Yz, sendCount_Yz, rank_Yz, sendtag, recvbuf_yZ,
|
||||
recvCount_yZ, rank_yZ, recvtag);
|
||||
comm.sendrecv(sendbuf_yZ, sendCount_yZ, rank_yZ, sendtag, recvbuf_Yz,
|
||||
recvCount_Yz, rank_Yz, recvtag);
|
||||
//........................................................................................
|
||||
UnpackMeshData(recvList_x, recvCount_x, recvbuf_x, MeshData);
|
||||
UnpackMeshData(recvList_X, recvCount_X, recvbuf_X, MeshData);
|
||||
|
@ -355,9 +386,6 @@ inline void CommunicateMeshHalo(DoubleArray &Mesh, const Utilities::MPI& comm,
|
|||
UnpackMeshData(recvList_YZ, recvCount_YZ, recvbuf_YZ, MeshData);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#include "common/Communication.hpp"
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,35 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef COMMUNICATION_HPP_INC
|
||||
#define COMMUNICATION_HPP_INC
|
||||
|
||||
|
@ -5,30 +37,36 @@
|
|||
#include "common/MPI.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Redistribute data between two grids *
|
||||
********************************************************/
|
||||
template <class TYPE>
|
||||
Array<TYPE> redistribute( const RankInfoStruct& src_rank, const Array<TYPE>& src_data,
|
||||
const RankInfoStruct& dst_rank, std::array<int,3> dst_size, const Utilities::MPI& comm )
|
||||
{
|
||||
Array<TYPE>
|
||||
redistribute(const RankInfoStruct &src_rank, const Array<TYPE> &src_data,
|
||||
const RankInfoStruct &dst_rank, std::array<int, 3> dst_size,
|
||||
const Utilities::MPI &comm) {
|
||||
if (comm.getSize() == 1) {
|
||||
return src_data.subset( { 0, (size_t) dst_size[0]-1, 0, (size_t) dst_size[1]-1, 0, (size_t) dst_size[2]-1 } );
|
||||
return src_data.subset({0, (size_t)dst_size[0] - 1, 0,
|
||||
(size_t)dst_size[1] - 1, 0,
|
||||
(size_t)dst_size[2] - 1});
|
||||
}
|
||||
// Get the src size
|
||||
std::array<int, 3> src_size;
|
||||
int size0[3] = { (int) src_data.size(0), (int) src_data.size(1), (int) src_data.size(2) };
|
||||
int size0[3] = {(int)src_data.size(0), (int)src_data.size(1),
|
||||
(int)src_data.size(2)};
|
||||
comm.maxReduce(size0, src_size.data(), 3);
|
||||
if (!src_data.empty())
|
||||
ASSERT( src_size[0] == size0[0] && src_size[1] == size0[1] && src_size[2] == size0[2] );
|
||||
ASSERT(src_size[0] == size0[0] && src_size[1] == size0[1] &&
|
||||
src_size[2] == size0[2]);
|
||||
// Check that dst_size matches on all ranks
|
||||
comm.maxReduce(dst_size.data(), size0, 3);
|
||||
ASSERT( dst_size[0] == size0[0] && dst_size[1] == size0[1] && dst_size[2] == size0[2] );
|
||||
ASSERT(dst_size[0] == size0[0] && dst_size[1] == size0[1] &&
|
||||
dst_size[2] == size0[2]);
|
||||
// Function to get overlap range
|
||||
auto calcOverlap = [](int i1[3], int i2[3], int j1[3], int j2[3]) {
|
||||
std::vector<size_t> index;
|
||||
if ( i1[0] > j2[0] || i2[0] < j1[0] || i1[1] > j2[1] || i2[1] < j1[1] || i1[2] > j2[2] || i2[2] < j1[2] )
|
||||
if (i1[0] > j2[0] || i2[0] < j1[0] || i1[1] > j2[1] || i2[1] < j1[1] ||
|
||||
i1[2] > j2[2] || i2[2] < j1[2])
|
||||
return index;
|
||||
index.resize(6);
|
||||
index[0] = std::max(j1[0] - i1[0], 0);
|
||||
|
@ -43,13 +81,18 @@ Array<TYPE> redistribute( const RankInfoStruct& src_rank, const Array<TYPE>& src
|
|||
std::vector<int> send_rank;
|
||||
std::vector<Array<TYPE>> send_data;
|
||||
if (!src_data.empty()) {
|
||||
int i1[3] = { src_size[0] * src_rank.ix, src_size[1] * src_rank.jy, src_size[2] * src_rank.kz };
|
||||
int i2[3] = { i1[0] + src_size[0] - 1, i1[1] + src_size[1] - 1, i1[2] + src_size[2] - 1 };
|
||||
int i1[3] = {src_size[0] * src_rank.ix, src_size[1] * src_rank.jy,
|
||||
src_size[2] * src_rank.kz};
|
||||
int i2[3] = {i1[0] + src_size[0] - 1, i1[1] + src_size[1] - 1,
|
||||
i1[2] + src_size[2] - 1};
|
||||
for (int i = 0; i < dst_rank.nx; i++) {
|
||||
for (int j = 0; j < dst_rank.ny; j++) {
|
||||
for (int k = 0; k < dst_rank.nz; k++) {
|
||||
int j1[3] = { i * dst_size[0], j * dst_size[1], k * dst_size[2] };
|
||||
int j2[3] = { j1[0] + dst_size[0] - 1, j1[1] + dst_size[1] - 1, j1[2] + dst_size[2] - 1 };
|
||||
int j1[3] = {i * dst_size[0], j * dst_size[1],
|
||||
k * dst_size[2]};
|
||||
int j2[3] = {j1[0] + dst_size[0] - 1,
|
||||
j1[1] + dst_size[1] - 1,
|
||||
j1[2] + dst_size[2] - 1};
|
||||
auto index = calcOverlap(i1, i2, j1, j2);
|
||||
if (index.empty())
|
||||
continue;
|
||||
|
@ -61,21 +104,27 @@ Array<TYPE> redistribute( const RankInfoStruct& src_rank, const Array<TYPE>& src
|
|||
}
|
||||
std::vector<MPI_Request> send_request(send_rank.size());
|
||||
for (size_t i = 0; i < send_rank.size(); i++)
|
||||
send_request[i] = comm.Isend( send_data[i].data(), send_data[i].length(), send_rank[i], 5462 );
|
||||
send_request[i] = comm.Isend(send_data[i].data(), send_data[i].length(),
|
||||
send_rank[i], 5462);
|
||||
// Unpack data from the appropriate ranks (including myself)
|
||||
Array<TYPE> dst_data(dst_size[0], dst_size[1], dst_size[2]);
|
||||
int i1[3] = { dst_size[0] * dst_rank.ix, dst_size[1] * dst_rank.jy, dst_size[2] * dst_rank.kz };
|
||||
int i2[3] = { i1[0] + dst_size[0] - 1, i1[1] + dst_size[1] - 1, i1[2] + dst_size[2] - 1 };
|
||||
int i1[3] = {dst_size[0] * dst_rank.ix, dst_size[1] * dst_rank.jy,
|
||||
dst_size[2] * dst_rank.kz};
|
||||
int i2[3] = {i1[0] + dst_size[0] - 1, i1[1] + dst_size[1] - 1,
|
||||
i1[2] + dst_size[2] - 1};
|
||||
for (int i = 0; i < src_rank.nx; i++) {
|
||||
for (int j = 0; j < src_rank.ny; j++) {
|
||||
for (int k = 0; k < src_rank.nz; k++) {
|
||||
int j1[3] = {i * src_size[0], j * src_size[1], k * src_size[2]};
|
||||
int j2[3] = { j1[0] + src_size[0] - 1, j1[1] + src_size[1] - 1, j1[2] + src_size[2] - 1 };
|
||||
int j2[3] = {j1[0] + src_size[0] - 1, j1[1] + src_size[1] - 1,
|
||||
j1[2] + src_size[2] - 1};
|
||||
auto index = calcOverlap(i1, i2, j1, j2);
|
||||
if (index.empty())
|
||||
continue;
|
||||
int rank = src_rank.getRankForBlock(i, j, k);
|
||||
Array<TYPE> data( index[1] - index[0] + 1, index[3] - index[2] + 1, index[5] - index[4] + 1 );
|
||||
Array<TYPE> data(index[1] - index[0] + 1,
|
||||
index[3] - index[2] + 1,
|
||||
index[5] - index[4] + 1);
|
||||
comm.recv(data.data(), data.length(), rank, 5462);
|
||||
dst_data.copySubset(index, data);
|
||||
}
|
||||
|
@ -86,17 +135,15 @@ Array<TYPE> redistribute( const RankInfoStruct& src_rank, const Array<TYPE>& src
|
|||
return dst_data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Structure to fill halo cells *
|
||||
********************************************************/
|
||||
template <class TYPE>
|
||||
fillHalo<TYPE>::fillHalo( const Utilities::MPI& comm_, const RankInfoStruct& info_,
|
||||
std::array<int,3> n_, std::array<int,3> ng_, int tag0, int depth_,
|
||||
std::array<bool,3> fill, std::array<bool,3> periodic ):
|
||||
comm(comm_), info(info_), n(n_), ng(ng_), depth(depth_)
|
||||
{
|
||||
fillHalo<TYPE>::fillHalo(const Utilities::MPI &comm_,
|
||||
const RankInfoStruct &info_, std::array<int, 3> n_,
|
||||
std::array<int, 3> ng_, int tag0, int depth_,
|
||||
std::array<bool, 3> fill, std::array<bool, 3> periodic)
|
||||
: comm(comm_), info(info_), n(n_), ng(ng_), depth(depth_) {
|
||||
// Set the fill pattern
|
||||
memset(fill_pattern, 0, sizeof(fill_pattern));
|
||||
if (fill[0]) {
|
||||
|
@ -210,16 +257,9 @@ fillHalo<TYPE>::fillHalo( const Utilities::MPI& comm_, const RankInfoStruct& inf
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
template<class TYPE>
|
||||
fillHalo<TYPE>::~fillHalo( )
|
||||
{
|
||||
delete [] mem;
|
||||
}
|
||||
template<class TYPE>
|
||||
void fillHalo<TYPE>::fill( Array<TYPE>& data )
|
||||
{
|
||||
template <class TYPE> fillHalo<TYPE>::~fillHalo() { delete[] mem; }
|
||||
template <class TYPE> void fillHalo<TYPE>::fill(Array<TYPE> &data) {
|
||||
//PROFILE_START("fillHalo::fill",1);
|
||||
int depth2 = data.size(3);
|
||||
ASSERT((int)data.size(0) == n[0] + 2 * ng[0]);
|
||||
|
@ -233,7 +273,8 @@ void fillHalo<TYPE>::fill( Array<TYPE>& data )
|
|||
for (int k = 0; k < 3; k++) {
|
||||
if (!fill_pattern[i][j][k])
|
||||
continue;
|
||||
recv_req[i][j][k] = comm.Irecv( recv[i][j][k], depth2*N_send_recv[i][j][k],
|
||||
recv_req[i][j][k] =
|
||||
comm.Irecv(recv[i][j][k], depth2 * N_send_recv[i][j][k],
|
||||
info.rank[i][j][k], tag[2 - i][2 - j][2 - k]);
|
||||
}
|
||||
}
|
||||
|
@ -245,7 +286,8 @@ void fillHalo<TYPE>::fill( Array<TYPE>& data )
|
|||
if (!fill_pattern[i][j][k])
|
||||
continue;
|
||||
pack(data, i - 1, j - 1, k - 1, send[i][j][k]);
|
||||
send_req[i][j][k] = comm.Isend( send[i][j][k], depth2*N_send_recv[i][j][k],
|
||||
send_req[i][j][k] =
|
||||
comm.Isend(send[i][j][k], depth2 * N_send_recv[i][j][k],
|
||||
info.rank[i][j][k], tag[i][j][k]);
|
||||
}
|
||||
}
|
||||
|
@ -274,8 +316,8 @@ void fillHalo<TYPE>::fill( Array<TYPE>& data )
|
|||
//PROFILE_STOP("fillHalo::fill",1);
|
||||
}
|
||||
template <class TYPE>
|
||||
void fillHalo<TYPE>::pack( const Array<TYPE>& data, int i0, int j0, int k0, TYPE *buffer )
|
||||
{
|
||||
void fillHalo<TYPE>::pack(const Array<TYPE> &data, int i0, int j0, int k0,
|
||||
TYPE *buffer) {
|
||||
int depth2 = data.size(3);
|
||||
int ni = i0 == 0 ? n[0] : ng[0];
|
||||
int nj = j0 == 0 ? n[1] : ng[1];
|
||||
|
@ -287,15 +329,16 @@ void fillHalo<TYPE>::pack( const Array<TYPE>& data, int i0, int j0, int k0, TYPE
|
|||
for (int k = 0; k < nk; k++) {
|
||||
for (int j = 0; j < nj; j++) {
|
||||
for (int i = 0; i < ni; i++) {
|
||||
buffer[i+j*ni+k*ni*nj+d*ni*nj*nk] = data(i+is,j+js,k+ks,d);
|
||||
buffer[i + j * ni + k * ni * nj + d * ni * nj * nk] =
|
||||
data(i + is, j + js, k + ks, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
template <class TYPE>
|
||||
void fillHalo<TYPE>::unpack( Array<TYPE>& data, int i0, int j0, int k0, const TYPE *buffer )
|
||||
{
|
||||
void fillHalo<TYPE>::unpack(Array<TYPE> &data, int i0, int j0, int k0,
|
||||
const TYPE *buffer) {
|
||||
int depth2 = data.size(3);
|
||||
int ni = i0 == 0 ? n[0] : ng[0];
|
||||
int nj = j0 == 0 ? n[1] : ng[1];
|
||||
|
@ -307,21 +350,20 @@ void fillHalo<TYPE>::unpack( Array<TYPE>& data, int i0, int j0, int k0, const TY
|
|||
for (int k = 0; k < nk; k++) {
|
||||
for (int j = 0; j < nj; j++) {
|
||||
for (int i = 0; i < ni; i++) {
|
||||
data(i+is,j+js,k+ks,d) = buffer[i+j*ni+k*ni*nj+d*ni*nj*nk];
|
||||
data(i + is, j + js, k + ks, d) =
|
||||
buffer[i + j * ni + k * ni * nj + d * ni * nj * nk];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Function to remove the ghost halo *
|
||||
********************************************************/
|
||||
template <class TYPE>
|
||||
template <class TYPE1, class TYPE2>
|
||||
void fillHalo<TYPE>::copy( const Array<TYPE1>& src, Array<TYPE2>& dst )
|
||||
{
|
||||
void fillHalo<TYPE>::copy(const Array<TYPE1> &src, Array<TYPE2> &dst) {
|
||||
//PROFILE_START("fillHalo::copy",1);
|
||||
ASSERT((int)src.size(0) == n[0] || (int)src.size(0) == n[0] + 2 * ng[0]);
|
||||
ASSERT((int)dst.size(0) == n[0] || (int)dst.size(0) == n[0] + 2 * ng[0]);
|
||||
|
@ -372,5 +414,4 @@ void fillHalo<TYPE>::copy( const Array<TYPE1>& src, Array<TYPE2>& dst )
|
|||
//PROFILE_STOP("fillHalo::copy",1);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "common/Database.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
|
@ -8,20 +24,17 @@
|
|||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Constructors/destructor *
|
||||
********************************************************************/
|
||||
Database::Database() = default;
|
||||
Database::~Database() = default;
|
||||
Database::Database( const Database& rhs ) : KeyData( rhs )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
Database &Database::operator=(const Database &rhs) {
|
||||
if (this == &rhs)
|
||||
return *this;
|
||||
d_data.clear();
|
||||
|
@ -30,36 +43,30 @@ Database& Database::operator=( const Database& rhs )
|
|||
return *this;
|
||||
}
|
||||
Database::Database(Database &&rhs) { std::swap(d_data, rhs.d_data); }
|
||||
Database& Database::operator=( Database&& rhs )
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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 )
|
||||
{
|
||||
std::shared_ptr<KeyData> Database::getData(const std::string &key) {
|
||||
auto it = d_data.find(key);
|
||||
if (it == d_data.end()) {
|
||||
char msg[1000];
|
||||
|
@ -68,18 +75,15 @@ std::shared_ptr<KeyData> Database::getData( const std::string& key )
|
|||
}
|
||||
return it->second;
|
||||
}
|
||||
std::shared_ptr<const KeyData> Database::getData( const std::string& key ) const
|
||||
{
|
||||
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
|
||||
{
|
||||
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<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) {
|
||||
|
@ -89,46 +93,37 @@ std::shared_ptr<Database> Database::getDatabase( const std::string& key )
|
|||
}
|
||||
return ptr2;
|
||||
}
|
||||
std::shared_ptr<const Database> Database::getDatabase( const std::string& key ) const
|
||||
{
|
||||
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> 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 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
template <> bool Database::isType<int>(const std::string &key) const {
|
||||
bool pass = true;
|
||||
auto type = getData(key)->type();
|
||||
if (type == "double") {
|
||||
|
@ -140,27 +135,21 @@ bool Database::isType<int>( const std::string& key ) const
|
|||
}
|
||||
return pass;
|
||||
}
|
||||
template<>
|
||||
bool Database::isType<std::string>( const std::string& key ) const
|
||||
{
|
||||
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
|
||||
{
|
||||
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::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>();
|
||||
|
@ -171,8 +160,8 @@ std::vector<std::string> Database::getVector<std::string>(
|
|||
return ptr2->d_data;
|
||||
}
|
||||
template <>
|
||||
std::vector<bool> Database::getVector<bool>( const std::string& key, const Units& ) const
|
||||
{
|
||||
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>();
|
||||
|
@ -183,8 +172,8 @@ std::vector<bool> Database::getVector<bool>( const std::string& key, const Units
|
|||
return ptr2->d_data;
|
||||
}
|
||||
template <class TYPE>
|
||||
std::vector<TYPE> Database::getVector( const std::string& key, const Units& unit ) const
|
||||
{
|
||||
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>();
|
||||
|
@ -211,29 +200,27 @@ std::vector<TYPE> Database::getVector( const std::string& key, const Units& unit
|
|||
return data;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Put a vector *
|
||||
********************************************************************/
|
||||
template <>
|
||||
void Database::putVector<std::string>(
|
||||
const std::string& key, const std::vector<std::string>& data, const Units& )
|
||||
{
|
||||
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& )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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());
|
||||
|
@ -242,12 +229,10 @@ void Database::putVector( const std::string& key, const std::vector<TYPE>& data,
|
|||
d_data[key] = ptr;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Print the database *
|
||||
********************************************************************/
|
||||
void Database::print( std::ostream& os, const std::string& indent ) const
|
||||
{
|
||||
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())) {
|
||||
|
@ -261,19 +246,16 @@ void Database::print( std::ostream& os, const std::string& indent ) const
|
|||
}
|
||||
}
|
||||
}
|
||||
std::string Database::print( const std::string& indent ) const
|
||||
{
|
||||
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 )
|
||||
{
|
||||
Database::Database(const std::string &filename) {
|
||||
// Read the input file into memory
|
||||
FILE *fid = fopen(filename.c_str(), "rb");
|
||||
if (fid == nullptr)
|
||||
|
@ -295,8 +277,7 @@ Database::Database( const std::string& filename )
|
|||
// Free temporary memory
|
||||
delete[] buffer;
|
||||
}
|
||||
std::shared_ptr<Database> Database::createFromString( const std::string& data )
|
||||
{
|
||||
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());
|
||||
|
@ -319,21 +300,20 @@ enum class token_type {
|
|||
end_bracket,
|
||||
end
|
||||
};
|
||||
inline size_t length( token_type type )
|
||||
{
|
||||
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 ) {
|
||||
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 ||
|
||||
} 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 )
|
||||
{
|
||||
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') {
|
||||
|
@ -347,23 +327,26 @@ inline std::tuple<size_t, token_type> find_next_token( const char* buffer )
|
|||
} 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 );
|
||||
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 );
|
||||
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 );
|
||||
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 );
|
||||
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 )
|
||||
{
|
||||
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] != ' ') {
|
||||
|
@ -373,12 +356,11 @@ inline std::string deblank( const std::string& str )
|
|||
}
|
||||
return i1 <= i2 ? str.substr(i1, i2 - i1 + 1) : std::string();
|
||||
}
|
||||
size_t skip_comment( const char* buffer )
|
||||
{
|
||||
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;
|
||||
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)
|
||||
|
@ -389,15 +371,13 @@ size_t skip_comment( const char* buffer )
|
|||
pos += std::get<0>(tmp);
|
||||
return pos;
|
||||
}
|
||||
inline std::string lower( const std::string& str )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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;
|
||||
|
@ -413,7 +393,8 @@ static std::tuple<size_t, std::shared_ptr<KeyData>> read_value(
|
|||
std::tie(i, type) = find_next_token(&buffer[pos]);
|
||||
pos += i;
|
||||
}
|
||||
} else if ( type == token_type::line_comment || type == token_type::block_start ) {
|
||||
} 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;
|
||||
|
@ -446,7 +427,8 @@ static std::tuple<size_t, std::shared_ptr<KeyData>> read_value(
|
|||
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] == '"' );
|
||||
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") {
|
||||
|
@ -474,16 +456,16 @@ static std::tuple<size_t, std::shared_ptr<KeyData>> read_value(
|
|||
}
|
||||
return std::tuple<size_t, std::shared_ptr<KeyData>>(pos, data);
|
||||
}
|
||||
size_t Database::loadDatabase( const char* buffer, Database& db )
|
||||
{
|
||||
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 ) {
|
||||
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]);
|
||||
|
@ -517,12 +499,10 @@ size_t Database::loadDatabase( const char* buffer, Database& db )
|
|||
return pos;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Data type helper functions *
|
||||
********************************************************************/
|
||||
void KeyDataDouble::print( std::ostream& os, const std::string& indent ) const
|
||||
{
|
||||
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)
|
||||
|
@ -541,19 +521,17 @@ void KeyDataDouble::print( std::ostream& os, const std::string& indent ) const
|
|||
os << " " << d_unit.str();
|
||||
os << std::endl;
|
||||
}
|
||||
std::tuple<double, Units> KeyDataDouble::read( const std::string& str )
|
||||
{
|
||||
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 ) ) );
|
||||
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 )
|
||||
{
|
||||
double KeyDataDouble::readValue(const std::string &str) {
|
||||
const std::string tmp = lower(str);
|
||||
double data = 0;
|
||||
if (tmp == "inf" || tmp == "infinity") {
|
||||
|
@ -573,24 +551,33 @@ double KeyDataDouble::readValue( const std::string& str )
|
|||
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 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;
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef included_Database
|
||||
#define included_Database
|
||||
|
||||
|
@ -10,17 +26,13 @@
|
|||
|
||||
#include "common/Units.h"
|
||||
|
||||
|
||||
inline bool exists( const std::string& filename )
|
||||
{
|
||||
inline bool exists(const std::string &filename) {
|
||||
std::ifstream domain(filename);
|
||||
return domain.good();
|
||||
}
|
||||
|
||||
|
||||
//! Base class to hold data of a given type
|
||||
class KeyData
|
||||
{
|
||||
class KeyData {
|
||||
protected:
|
||||
//! Empty constructor
|
||||
KeyData() {}
|
||||
|
@ -31,7 +43,8 @@ public:
|
|||
//! 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;
|
||||
virtual void print(std::ostream &os,
|
||||
const std::string &indent = "") const = 0;
|
||||
//! Return the native data type
|
||||
virtual std::string type() const = 0;
|
||||
|
||||
|
@ -40,10 +53,8 @@ protected:
|
|||
KeyData &operator=(const KeyData &);
|
||||
};
|
||||
|
||||
|
||||
//! Class to a database
|
||||
class Database : public KeyData
|
||||
{
|
||||
class Database : public KeyData {
|
||||
public:
|
||||
//! Empty constructor
|
||||
Database();
|
||||
|
@ -81,7 +92,6 @@ public:
|
|||
//! Copy the data
|
||||
std::shared_ptr<Database> cloneDatabase() const;
|
||||
|
||||
|
||||
/**
|
||||
* Return true if the specified key exists in the database and false
|
||||
* otherwise.
|
||||
|
@ -89,17 +99,14 @@ public:
|
|||
*/
|
||||
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
|
||||
|
@ -110,13 +117,13 @@ public:
|
|||
* @param[in] unit Desired units
|
||||
*/
|
||||
template <class TYPE>
|
||||
inline TYPE getScalar( const std::string& key, const Units& unit = Units() ) const;
|
||||
|
||||
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;
|
||||
|
||||
inline TYPE getScalar(const std::string &key,
|
||||
const std::string &unit) const;
|
||||
|
||||
/**
|
||||
* Get the scalar entry from the database with the specified key
|
||||
|
@ -128,15 +135,13 @@ public:
|
|||
* @param[in] unit Desired units
|
||||
*/
|
||||
template <class TYPE>
|
||||
inline TYPE getWithDefault(
|
||||
const std::string& key, const TYPE& value, const Units& unit = Units() ) const;
|
||||
|
||||
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;
|
||||
|
||||
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.
|
||||
|
@ -145,8 +150,8 @@ public:
|
|||
* @param unit Desired units
|
||||
*/
|
||||
template <class TYPE>
|
||||
inline void putScalar( const std::string& key, const TYPE& value, const Units& unit = Units() );
|
||||
|
||||
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.
|
||||
|
@ -155,8 +160,8 @@ public:
|
|||
* @param unit Desired units
|
||||
*/
|
||||
template <class TYPE>
|
||||
inline void putScalar( const std::string& key, const TYPE& value, const std::string& unit );
|
||||
|
||||
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
|
||||
|
@ -168,13 +173,13 @@ public:
|
|||
* @param unit Desired units
|
||||
*/
|
||||
template <class TYPE>
|
||||
std::vector<TYPE> getVector( const std::string& key, const Units& unit = Units() ) const;
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
|
@ -187,15 +192,13 @@ public:
|
|||
* @param unit Desired units
|
||||
*/
|
||||
template <class TYPE>
|
||||
void putVector(
|
||||
const std::string& key, const std::vector<TYPE>& data, const Units& unit = Units() );
|
||||
|
||||
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 );
|
||||
|
||||
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
|
||||
|
@ -215,7 +218,6 @@ public:
|
|||
*/
|
||||
std::shared_ptr<const KeyData> getData(const std::string &key) const;
|
||||
|
||||
|
||||
/**
|
||||
* Put the data for a key in the database.
|
||||
*
|
||||
|
@ -224,15 +226,11 @@ public:
|
|||
*/
|
||||
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;
|
||||
|
||||
template <class TYPE> bool isType(const std::string &key) const;
|
||||
|
||||
/**
|
||||
* Get the database for a key in the database. If the specified key
|
||||
|
@ -252,7 +250,6 @@ public:
|
|||
*/
|
||||
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
|
||||
|
@ -263,26 +260,23 @@ public:
|
|||
*/
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
|
@ -290,7 +284,6 @@ protected:
|
|||
static size_t loadDatabase(const char *buffer, Database &db);
|
||||
};
|
||||
|
||||
|
||||
#include "common/Database.hpp"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,35 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef included_Database_hpp
|
||||
#define included_Database_hpp
|
||||
|
||||
|
@ -6,39 +38,33 @@
|
|||
|
||||
#include <tuple>
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Basic classes for primative data types *
|
||||
********************************************************************/
|
||||
class EmptyKeyData : public KeyData
|
||||
{
|
||||
class EmptyKeyData : public KeyData {
|
||||
public:
|
||||
EmptyKeyData() {}
|
||||
virtual ~EmptyKeyData() {}
|
||||
virtual std::shared_ptr<KeyData> clone() const override
|
||||
{
|
||||
virtual std::shared_ptr<KeyData> clone() const override {
|
||||
return std::make_shared<EmptyKeyData>();
|
||||
}
|
||||
virtual void print( std::ostream& os, const std::string& = "" ) const override
|
||||
{
|
||||
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
|
||||
{
|
||||
class KeyDataDouble : public KeyData {
|
||||
public:
|
||||
KeyDataDouble() {}
|
||||
explicit KeyDataDouble(const std::vector<double> &data, const Units &unit)
|
||||
: d_data( data ), d_unit( unit )
|
||||
{
|
||||
}
|
||||
: d_data(data), d_unit(unit) {}
|
||||
virtual ~KeyDataDouble() {}
|
||||
virtual std::shared_ptr<KeyData> clone() const override
|
||||
{
|
||||
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 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 &);
|
||||
|
@ -48,18 +74,16 @@ public:
|
|||
std::vector<double> d_data;
|
||||
Units d_unit;
|
||||
};
|
||||
class KeyDataBool : public KeyData
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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) {
|
||||
|
@ -76,18 +100,17 @@ public:
|
|||
virtual std::string type() const override { return "bool"; }
|
||||
std::vector<bool> d_data;
|
||||
};
|
||||
class KeyDataString : public KeyData
|
||||
{
|
||||
class KeyDataString : public KeyData {
|
||||
public:
|
||||
KeyDataString() {}
|
||||
explicit KeyDataString( const std::vector<std::string>& data ) : d_data( data ) {}
|
||||
explicit KeyDataString(const std::vector<std::string> &data)
|
||||
: d_data(data) {}
|
||||
virtual ~KeyDataString() {}
|
||||
virtual std::shared_ptr<KeyData> clone() const override
|
||||
{
|
||||
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
|
||||
{
|
||||
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) {
|
||||
|
@ -101,30 +124,27 @@ public:
|
|||
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
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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
|
||||
{
|
||||
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];
|
||||
|
@ -134,40 +154,36 @@ inline TYPE Database::getScalar( const std::string& key, const Units& unit ) con
|
|||
return data[0];
|
||||
}
|
||||
template <class TYPE>
|
||||
inline TYPE Database::getWithDefault(
|
||||
const std::string& key, const TYPE& value, const Units& unit ) const
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
inline void putVector(const std::string &key, const std::vector<TYPE> &data,
|
||||
const std::string &unit) {
|
||||
putVector<TYPE>(key, data, Units(unit));
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
76
common/Domain.h
Executable file → Normal file
76
common/Domain.h
Executable file → Normal file
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef Domain_INC
|
||||
#define Domain_INC
|
||||
|
||||
|
@ -21,7 +37,6 @@
|
|||
* \brief Parallel Domain data structures and helper functions
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* \class Box
|
||||
*
|
||||
|
@ -102,9 +117,7 @@ public:
|
|||
*/
|
||||
inline const std::vector<Patch> &getAllPatch() const { return d_patches; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* \brief initialize from database
|
||||
*/
|
||||
|
@ -115,9 +128,7 @@ private:
|
|||
Patch *d_localPatch;
|
||||
std::vector<Patch> d_patches;
|
||||
|
||||
|
||||
public: // Public variables (need to create accessors instead)
|
||||
|
||||
std::shared_ptr<Database> database;
|
||||
double Lx, Ly, Lz, Volume, voxel_length;
|
||||
int Nx, Ny, Nz, N;
|
||||
|
@ -170,10 +181,18 @@ public: // Public variables (need to create accessors instead)
|
|||
// Get the actual D3Q19 communication counts (based on location of solid phase)
|
||||
// Discrete velocity set symmetry implies the sendcount = recvcount
|
||||
//......................................................................................
|
||||
inline int recvCount( const char* dir ) const { return getRecvList( dir ).size(); }
|
||||
inline int sendCount( const char* dir ) const { return getSendList( dir ).size(); }
|
||||
inline const int* recvList( const char* dir ) const { return getRecvList( dir ).data(); }
|
||||
inline const int* sendList( const char* dir ) const { return getSendList( dir ).data(); }
|
||||
inline int recvCount(const char *dir) const {
|
||||
return getRecvList(dir).size();
|
||||
}
|
||||
inline int sendCount(const char *dir) const {
|
||||
return getSendList(dir).size();
|
||||
}
|
||||
inline const int *recvList(const char *dir) const {
|
||||
return getRecvList(dir).data();
|
||||
}
|
||||
inline const int *sendList(const char *dir) const {
|
||||
return getSendList(dir).data();
|
||||
}
|
||||
|
||||
//......................................................................................
|
||||
// Solid indicator function
|
||||
|
@ -218,7 +237,8 @@ public: // Public variables (need to create accessors instead)
|
|||
* @param Datatype - data type to use
|
||||
* @param UserData - Array to store the values that are read
|
||||
*/
|
||||
void ReadFromFile(const std::string& Filename,const std::string& Datatype, double *UserData);
|
||||
void ReadFromFile(const std::string &Filename, const std::string &Datatype,
|
||||
double *UserData);
|
||||
|
||||
/**
|
||||
* \brief Aggregate labels from all MPI processes and write to a file
|
||||
|
@ -233,7 +253,6 @@ public: // Public variables (need to create accessors instead)
|
|||
void AggregateLabels(const std::string &filename, DoubleArray &UserData);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* \brief Pack halo data for 8-bit integer
|
||||
* @param list - list of values in the halo
|
||||
|
@ -255,25 +274,28 @@ private:
|
|||
//......................................................................................
|
||||
MPI_Request req1[18], req2[18];
|
||||
//......................................................................................
|
||||
std::vector<int> sendList_x, sendList_y, sendList_z, sendList_X, sendList_Y, sendList_Z;
|
||||
std::vector<int> sendList_xy, sendList_yz, sendList_xz, sendList_Xy, sendList_Yz, sendList_xZ;
|
||||
std::vector<int> sendList_xY, sendList_yZ, sendList_Xz, sendList_XY, sendList_YZ, sendList_XZ;
|
||||
std::vector<int> sendList_x, sendList_y, sendList_z, sendList_X, sendList_Y,
|
||||
sendList_Z;
|
||||
std::vector<int> sendList_xy, sendList_yz, sendList_xz, sendList_Xy,
|
||||
sendList_Yz, sendList_xZ;
|
||||
std::vector<int> sendList_xY, sendList_yZ, sendList_Xz, sendList_XY,
|
||||
sendList_YZ, sendList_XZ;
|
||||
//......................................................................................
|
||||
std::vector<int> recvList_x, recvList_y, recvList_z, recvList_X, recvList_Y, recvList_Z;
|
||||
std::vector<int> recvList_xy, recvList_yz, recvList_xz, recvList_Xy, recvList_Yz, recvList_xZ;
|
||||
std::vector<int> recvList_xY, recvList_yZ, recvList_Xz, recvList_XY, recvList_YZ, recvList_XZ;
|
||||
std::vector<int> recvList_x, recvList_y, recvList_z, recvList_X, recvList_Y,
|
||||
recvList_Z;
|
||||
std::vector<int> recvList_xy, recvList_yz, recvList_xz, recvList_Xy,
|
||||
recvList_Yz, recvList_xZ;
|
||||
std::vector<int> recvList_xY, recvList_yZ, recvList_Xz, recvList_XY,
|
||||
recvList_YZ, recvList_XZ;
|
||||
//......................................................................................
|
||||
const std::vector<int> &getRecvList(const char *dir) const;
|
||||
const std::vector<int> &getSendList(const char *dir) const;
|
||||
|
||||
};
|
||||
|
||||
template <class TYPE> class PatchData;
|
||||
|
||||
|
||||
enum class DataLocation { CPU, DEVICE };
|
||||
|
||||
|
||||
/**
|
||||
* \class Patch
|
||||
*
|
||||
|
@ -282,7 +304,6 @@ enum class DataLocation { CPU, DEVICE };
|
|||
*/
|
||||
class Patch {
|
||||
public:
|
||||
|
||||
//! Empty constructor
|
||||
Patch() = delete;
|
||||
|
||||
|
@ -297,21 +318,18 @@ public:
|
|||
|
||||
//! Create patch data
|
||||
template <class TYPE>
|
||||
std::shared_ptr<PatchData<TYPE>> createPatchData( DataLocation location ) const;
|
||||
std::shared_ptr<PatchData<TYPE>>
|
||||
createPatchData(DataLocation location) const;
|
||||
|
||||
private:
|
||||
Box d_box;
|
||||
int d_owner;
|
||||
Domain *d_domain;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Class to hold data on a patch
|
||||
template<class TYPE>
|
||||
class PatchData {
|
||||
template <class TYPE> class PatchData {
|
||||
public:
|
||||
|
||||
//! Get the raw data pointer
|
||||
TYPE *data() { return d_data; }
|
||||
|
||||
|
@ -338,10 +356,10 @@ private:
|
|||
const Patch *d_patch;
|
||||
TYPE *d_data;
|
||||
TYPE *d_gcw;
|
||||
|
||||
};
|
||||
|
||||
void WriteCheckpoint(const char *FILENAME, const double *cDen, const double *cfq, size_t Np);
|
||||
void WriteCheckpoint(const char *FILENAME, const double *cDen,
|
||||
const double *cfq, size_t Np);
|
||||
|
||||
void ReadCheckpoint(char *FILENAME, double *cDen, double *cfq, size_t Np);
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "FunctionTable.hpp"
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Random number generation *
|
||||
********************************************************/
|
||||
|
@ -94,54 +93,35 @@ template<> long double genRand<long double>()
|
|||
* axpy *
|
||||
********************************************************/
|
||||
template <>
|
||||
void call_axpy<float>( size_t N, const float alpha, const float *x, float *y )
|
||||
{
|
||||
void call_axpy<float>(size_t N, const float alpha, const float *x, float *y) {
|
||||
ERROR("Not finished");
|
||||
}
|
||||
template <>
|
||||
void call_axpy<double>( size_t N, const double alpha, const double *x, double *y )
|
||||
{
|
||||
void call_axpy<double>(size_t N, const double alpha, const double *x,
|
||||
double *y) {
|
||||
ERROR("Not finished");
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Multiply two arrays *
|
||||
********************************************************/
|
||||
template <>
|
||||
void call_gemv<double>(
|
||||
size_t M, size_t N, double alpha, double beta, const double *A, const double *x, double *y )
|
||||
{
|
||||
void call_gemv<double>(size_t M, size_t N, double alpha, double beta,
|
||||
const double *A, const double *x, double *y) {
|
||||
ERROR("Not finished");
|
||||
}
|
||||
template <>
|
||||
void call_gemv<float>(
|
||||
size_t M, size_t N, float alpha, float beta, const float *A, const float *x, float *y )
|
||||
{
|
||||
void call_gemv<float>(size_t M, size_t N, float alpha, float beta,
|
||||
const float *A, const float *x, float *y) {
|
||||
ERROR("Not finished");
|
||||
}
|
||||
template <>
|
||||
void call_gemm<double>( size_t M,
|
||||
size_t N,
|
||||
size_t K,
|
||||
double alpha,
|
||||
double beta,
|
||||
const double *A,
|
||||
const double *B,
|
||||
double *C )
|
||||
{
|
||||
void call_gemm<double>(size_t M, size_t N, size_t K, double alpha, double beta,
|
||||
const double *A, const double *B, double *C) {
|
||||
ERROR("Not finished");
|
||||
}
|
||||
template <>
|
||||
void call_gemm<float>( size_t M,
|
||||
size_t N,
|
||||
size_t K,
|
||||
float alpha,
|
||||
float beta,
|
||||
const float *A,
|
||||
const float *B,
|
||||
float *C )
|
||||
{
|
||||
void call_gemm<float>(size_t M, size_t N, size_t K, float alpha, float beta,
|
||||
const float *A, const float *B, float *C) {
|
||||
ERROR("Not finished");
|
||||
}
|
||||
|
||||
|
|
|
@ -1,28 +1,39 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef included_FunctionTable
|
||||
#define included_FunctionTable
|
||||
|
||||
|
||||
#include "common/ArraySize.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
* Class FunctionTable is a serial function table class that defines
|
||||
* a series of operations that can be performed on the Array class.
|
||||
* Users can impliment additional versions of the function table that match
|
||||
* the interface to change the behavior of the array class.
|
||||
*/
|
||||
class FunctionTable final
|
||||
{
|
||||
class FunctionTable final {
|
||||
public:
|
||||
/*!
|
||||
* Initialize the array with random values
|
||||
* @param[in] x The array to operate on
|
||||
*/
|
||||
template<class TYPE, class FUN>
|
||||
static void rand( Array<TYPE, FUN> &x );
|
||||
template <class TYPE, class FUN> static void rand(Array<TYPE, FUN> &x);
|
||||
|
||||
/*!
|
||||
* Perform a reduce operator y = f(x)
|
||||
|
@ -34,7 +45,8 @@ public:
|
|||
* @return The reduction
|
||||
*/
|
||||
template <class TYPE, class FUN, typename LAMBDA>
|
||||
static inline TYPE reduce( LAMBDA &op, const Array<TYPE, FUN> &A, const TYPE &initialValue );
|
||||
static inline TYPE reduce(LAMBDA &op, const Array<TYPE, FUN> &A,
|
||||
const TYPE &initialValue);
|
||||
|
||||
/*!
|
||||
* Perform a reduce operator z = f(x,y)
|
||||
|
@ -47,8 +59,7 @@ public:
|
|||
* @return The reduction
|
||||
*/
|
||||
template <class TYPE, class FUN, typename LAMBDA>
|
||||
static inline TYPE reduce( LAMBDA &op,
|
||||
const Array<TYPE, FUN> &A,
|
||||
static inline TYPE reduce(LAMBDA &op, const Array<TYPE, FUN> &A,
|
||||
const Array<TYPE, FUN> &B,
|
||||
const TYPE &initialValue);
|
||||
|
||||
|
@ -60,7 +71,8 @@ public:
|
|||
* @param[out] y The output array
|
||||
*/
|
||||
template <class TYPE, class FUN, typename LAMBDA>
|
||||
static inline void transform( LAMBDA &fun, const Array<TYPE, FUN> &x, Array<TYPE, FUN> &y );
|
||||
static inline void transform(LAMBDA &fun, const Array<TYPE, FUN> &x,
|
||||
Array<TYPE, FUN> &y);
|
||||
|
||||
/*!
|
||||
* Perform a element-wise operation z = f(x,y)
|
||||
|
@ -71,8 +83,7 @@ public:
|
|||
* @param[out] z The output array
|
||||
*/
|
||||
template <class TYPE, class FUN, typename LAMBDA>
|
||||
static inline void transform( LAMBDA &fun,
|
||||
const Array<TYPE, FUN> &x,
|
||||
static inline void transform(LAMBDA &fun, const Array<TYPE, FUN> &x,
|
||||
const Array<TYPE, FUN> &y,
|
||||
Array<TYPE, FUN> &z);
|
||||
|
||||
|
@ -83,8 +94,8 @@ public:
|
|||
* @param[out] c The output array
|
||||
*/
|
||||
template <class TYPE, class FUN>
|
||||
static void
|
||||
multiply( const Array<TYPE, FUN> &a, const Array<TYPE, FUN> &b, Array<TYPE, FUN> &c );
|
||||
static void multiply(const Array<TYPE, FUN> &a, const Array<TYPE, FUN> &b,
|
||||
Array<TYPE, FUN> &c);
|
||||
|
||||
/*!
|
||||
* Perform dgemv/dgemm equavalent operation ( C = alpha*A*B + beta*C )
|
||||
|
@ -95,10 +106,8 @@ public:
|
|||
* @param[in,out] C The output array C
|
||||
*/
|
||||
template <class TYPE, class FUN>
|
||||
static void gemm( const TYPE alpha,
|
||||
const Array<TYPE, FUN> &A,
|
||||
const Array<TYPE, FUN> &B,
|
||||
const TYPE beta,
|
||||
static void gemm(const TYPE alpha, const Array<TYPE, FUN> &A,
|
||||
const Array<TYPE, FUN> &B, const TYPE beta,
|
||||
Array<TYPE, FUN> &C);
|
||||
|
||||
/*!
|
||||
|
@ -108,7 +117,8 @@ public:
|
|||
* @param[in,out] y The output array y
|
||||
*/
|
||||
template <class TYPE, class FUN>
|
||||
static void axpy( const TYPE alpha, const Array<TYPE, FUN> &x, Array<TYPE, FUN> &y );
|
||||
static void axpy(const TYPE alpha, const Array<TYPE, FUN> &x,
|
||||
Array<TYPE, FUN> &y);
|
||||
|
||||
/*!
|
||||
* Check if two arrays are approximately equal
|
||||
|
@ -117,24 +127,15 @@ public:
|
|||
* @param[in] tol The tolerance
|
||||
*/
|
||||
template <class TYPE, class FUN>
|
||||
static bool equals( const Array<TYPE, FUN> &A, const Array<TYPE, FUN> &B, TYPE tol );
|
||||
static bool equals(const Array<TYPE, FUN> &A, const Array<TYPE, FUN> &B,
|
||||
TYPE tol);
|
||||
|
||||
template <class TYPE>
|
||||
static inline void gemmWrapper( char TRANSA,
|
||||
char TRANSB,
|
||||
int M,
|
||||
int N,
|
||||
int K,
|
||||
TYPE alpha,
|
||||
const TYPE *A,
|
||||
int LDA,
|
||||
const TYPE *B,
|
||||
int LDB,
|
||||
TYPE beta,
|
||||
TYPE *C,
|
||||
static inline void gemmWrapper(char TRANSA, char TRANSB, int M, int N,
|
||||
int K, TYPE alpha, const TYPE *A, int LDA,
|
||||
const TYPE *B, int LDB, TYPE beta, TYPE *C,
|
||||
int LDC);
|
||||
|
||||
|
||||
/* Specialized Functions */
|
||||
|
||||
/*!
|
||||
|
@ -143,7 +144,8 @@ public:
|
|||
* @param[out] B The output array
|
||||
*/
|
||||
template <class TYPE, class FUN, class ALLOC>
|
||||
static void transformReLU( const Array<TYPE, FUN, ALLOC> &A, Array<TYPE, FUN, ALLOC> &B );
|
||||
static void transformReLU(const Array<TYPE, FUN, ALLOC> &A,
|
||||
Array<TYPE, FUN, ALLOC> &B);
|
||||
|
||||
/*!
|
||||
* Perform a element-wise operation B = |A|
|
||||
|
@ -151,7 +153,8 @@ public:
|
|||
* @param[out] B The output array
|
||||
*/
|
||||
template <class TYPE, class FUN, class ALLOC>
|
||||
static void transformAbs( const Array<TYPE, FUN, ALLOC> &A, Array<TYPE, FUN, ALLOC> &B );
|
||||
static void transformAbs(const Array<TYPE, FUN, ALLOC> &A,
|
||||
Array<TYPE, FUN, ALLOC> &B);
|
||||
|
||||
/*!
|
||||
* Perform a element-wise operation B = tanh(A)
|
||||
|
@ -159,7 +162,8 @@ public:
|
|||
* @param[out] B The output array
|
||||
*/
|
||||
template <class TYPE, class FUN, class ALLOC>
|
||||
static void transformTanh( const Array<TYPE, FUN, ALLOC> &A, Array<TYPE, FUN, ALLOC> &B );
|
||||
static void transformTanh(const Array<TYPE, FUN, ALLOC> &A,
|
||||
Array<TYPE, FUN, ALLOC> &B);
|
||||
|
||||
/*!
|
||||
* Perform a element-wise operation B = max(-1 , min(1 , A) )
|
||||
|
@ -167,7 +171,8 @@ public:
|
|||
* @param[out] B The output array
|
||||
*/
|
||||
template <class TYPE, class FUN, class ALLOC>
|
||||
static void transformHardTanh( const Array<TYPE, FUN, ALLOC> &A, Array<TYPE, FUN, ALLOC> &B );
|
||||
static void transformHardTanh(const Array<TYPE, FUN, ALLOC> &A,
|
||||
Array<TYPE, FUN, ALLOC> &B);
|
||||
|
||||
/*!
|
||||
* Perform a element-wise operation B = 1 / (1 + exp(-A))
|
||||
|
@ -175,7 +180,8 @@ public:
|
|||
* @param[out] B The output array
|
||||
*/
|
||||
template <class TYPE, class FUN, class ALLOC>
|
||||
static void transformSigmoid( const Array<TYPE, FUN, ALLOC> &A, Array<TYPE, FUN, ALLOC> &B );
|
||||
static void transformSigmoid(const Array<TYPE, FUN, ALLOC> &A,
|
||||
Array<TYPE, FUN, ALLOC> &B);
|
||||
|
||||
/*!
|
||||
* Perform a element-wise operation B = log(exp(A) + 1)
|
||||
|
@ -183,7 +189,8 @@ public:
|
|||
* @param[out] B The output array
|
||||
*/
|
||||
template <class TYPE, class FUN, class ALLOC>
|
||||
static void transformSoftPlus( const Array<TYPE, FUN, ALLOC> &A, Array<TYPE, FUN, ALLOC> &B );
|
||||
static void transformSoftPlus(const Array<TYPE, FUN, ALLOC> &A,
|
||||
Array<TYPE, FUN, ALLOC> &B);
|
||||
|
||||
/*!
|
||||
* Sum the elements of the Array
|
||||
|
@ -195,9 +202,7 @@ public:
|
|||
private:
|
||||
FunctionTable();
|
||||
|
||||
template<class T>
|
||||
static inline void rand( size_t N, T *x );
|
||||
template <class T> static inline void rand(size_t N, T *x);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,35 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef included_FunctionTable_hpp
|
||||
#define included_FunctionTable_hpp
|
||||
|
||||
|
@ -9,7 +41,6 @@
|
|||
#include <limits>
|
||||
//#include <random>
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Random number initialization *
|
||||
********************************************************/
|
||||
|
@ -26,8 +57,8 @@ inline void FunctionTable::rand( Array<TYPE, FUN> &x )
|
|||
* Reduction *
|
||||
********************************************************/
|
||||
template <class TYPE, class FUN, typename LAMBDA>
|
||||
inline TYPE FunctionTable::reduce( LAMBDA &op, const Array<TYPE, FUN> &A, const TYPE &initialValue )
|
||||
{
|
||||
inline TYPE FunctionTable::reduce(LAMBDA &op, const Array<TYPE, FUN> &A,
|
||||
const TYPE &initialValue) {
|
||||
if (A.length() == 0)
|
||||
return TYPE();
|
||||
const TYPE *x = A.data();
|
||||
|
@ -37,11 +68,9 @@ inline TYPE FunctionTable::reduce( LAMBDA &op, const Array<TYPE, FUN> &A, const
|
|||
return y;
|
||||
}
|
||||
template <class TYPE, class FUN, typename LAMBDA>
|
||||
inline TYPE FunctionTable::reduce( LAMBDA &op,
|
||||
const Array<TYPE, FUN> &A,
|
||||
inline TYPE FunctionTable::reduce(LAMBDA &op, const Array<TYPE, FUN> &A,
|
||||
const Array<TYPE, FUN> &B,
|
||||
const TYPE &initialValue )
|
||||
{
|
||||
const TYPE &initialValue) {
|
||||
ARRAY_ASSERT(A.length() == B.length());
|
||||
if (A.length() == 0)
|
||||
return TYPE();
|
||||
|
@ -53,24 +82,21 @@ inline TYPE FunctionTable::reduce( LAMBDA &op,
|
|||
return z;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Unary transformation *
|
||||
********************************************************/
|
||||
template <class TYPE, class FUN, typename LAMBDA>
|
||||
inline void FunctionTable::transform( LAMBDA &fun, const Array<TYPE, FUN> &x, Array<TYPE, FUN> &y )
|
||||
{
|
||||
inline void FunctionTable::transform(LAMBDA &fun, const Array<TYPE, FUN> &x,
|
||||
Array<TYPE, FUN> &y) {
|
||||
y.resize(x.size());
|
||||
const size_t N = x.length();
|
||||
for (size_t i = 0; i < N; i++)
|
||||
y(i) = fun(x(i));
|
||||
}
|
||||
template <class TYPE, class FUN, typename LAMBDA>
|
||||
inline void FunctionTable::transform( LAMBDA &fun,
|
||||
const Array<TYPE, FUN> &x,
|
||||
inline void FunctionTable::transform(LAMBDA &fun, const Array<TYPE, FUN> &x,
|
||||
const Array<TYPE, FUN> &y,
|
||||
Array<TYPE, FUN> &z )
|
||||
{
|
||||
Array<TYPE, FUN> &z) {
|
||||
if (x.size() != y.size())
|
||||
throw std::logic_error("Sizes of x and y do not match");
|
||||
z.resize(x.size());
|
||||
|
@ -79,7 +105,6 @@ inline void FunctionTable::transform( LAMBDA &fun,
|
|||
z(i) = fun(x(i), y(i));
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* axpy *
|
||||
********************************************************/
|
||||
|
@ -88,36 +113,36 @@ void call_axpy( size_t N, const TYPE alpha, const TYPE *x, TYPE *y );
|
|||
template <>
|
||||
void call_axpy<float>(size_t N, const float alpha, const float *x, float *y);
|
||||
template <>
|
||||
void call_axpy<double>( size_t N, const double alpha, const double *x, double *y );
|
||||
void call_axpy<double>(size_t N, const double alpha, const double *x,
|
||||
double *y);
|
||||
template <class TYPE>
|
||||
void call_axpy( size_t N, const TYPE alpha, const TYPE *x, TYPE *y )
|
||||
{
|
||||
void call_axpy(size_t N, const TYPE alpha, const TYPE *x, TYPE *y) {
|
||||
for (size_t i = 0; i < N; i++)
|
||||
y[i] += alpha * x[i];
|
||||
}
|
||||
template <class TYPE, class FUN>
|
||||
void FunctionTable::axpy( const TYPE alpha, const Array<TYPE, FUN> &x, Array<TYPE, FUN> &y )
|
||||
{
|
||||
void FunctionTable::axpy(const TYPE alpha, const Array<TYPE, FUN> &x,
|
||||
Array<TYPE, FUN> &y) {
|
||||
if (x.size() != y.size())
|
||||
throw std::logic_error("Array sizes do not match");
|
||||
call_axpy(x.length(), alpha, x.data(), y.data());
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Multiply two arrays *
|
||||
********************************************************/
|
||||
template <class TYPE>
|
||||
void call_gemv( size_t M, size_t N, TYPE alpha, TYPE beta, const TYPE *A, const TYPE *x, TYPE *y );
|
||||
void call_gemv(size_t M, size_t N, TYPE alpha, TYPE beta, const TYPE *A,
|
||||
const TYPE *x, TYPE *y);
|
||||
template <>
|
||||
void call_gemv<double>(
|
||||
size_t M, size_t N, double alpha, double beta, const double *A, const double *x, double *y );
|
||||
void call_gemv<double>(size_t M, size_t N, double alpha, double beta,
|
||||
const double *A, const double *x, double *y);
|
||||
template <>
|
||||
void call_gemv<float>(
|
||||
size_t M, size_t N, float alpha, float beta, const float *A, const float *x, float *y );
|
||||
void call_gemv<float>(size_t M, size_t N, float alpha, float beta,
|
||||
const float *A, const float *x, float *y);
|
||||
template <class TYPE>
|
||||
void call_gemv( size_t M, size_t N, TYPE alpha, TYPE beta, const TYPE *A, const TYPE *x, TYPE *y )
|
||||
{
|
||||
void call_gemv(size_t M, size_t N, TYPE alpha, TYPE beta, const TYPE *A,
|
||||
const TYPE *x, TYPE *y) {
|
||||
for (size_t i = 0; i < M; i++)
|
||||
y[i] = beta * y[i];
|
||||
for (size_t j = 0; j < N; j++) {
|
||||
|
@ -126,30 +151,17 @@ void call_gemv( size_t M, size_t N, TYPE alpha, TYPE beta, const TYPE *A, const
|
|||
}
|
||||
}
|
||||
template <class TYPE>
|
||||
void call_gemm(
|
||||
size_t M, size_t N, size_t K, TYPE alpha, TYPE beta, const TYPE *A, const TYPE *B, TYPE *C );
|
||||
void call_gemm(size_t M, size_t N, size_t K, TYPE alpha, TYPE beta,
|
||||
const TYPE *A, const TYPE *B, TYPE *C);
|
||||
template <>
|
||||
void call_gemm<double>( size_t M,
|
||||
size_t N,
|
||||
size_t K,
|
||||
double alpha,
|
||||
double beta,
|
||||
const double *A,
|
||||
const double *B,
|
||||
double *C );
|
||||
void call_gemm<double>(size_t M, size_t N, size_t K, double alpha, double beta,
|
||||
const double *A, const double *B, double *C);
|
||||
template <>
|
||||
void call_gemm<float>( size_t M,
|
||||
size_t N,
|
||||
size_t K,
|
||||
float alpha,
|
||||
float beta,
|
||||
const float *A,
|
||||
const float *B,
|
||||
float *C );
|
||||
void call_gemm<float>(size_t M, size_t N, size_t K, float alpha, float beta,
|
||||
const float *A, const float *B, float *C);
|
||||
template <class TYPE>
|
||||
void call_gemm(
|
||||
size_t M, size_t N, size_t K, TYPE alpha, TYPE beta, const TYPE *A, const TYPE *B, TYPE *C )
|
||||
{
|
||||
void call_gemm(size_t M, size_t N, size_t K, TYPE alpha, TYPE beta,
|
||||
const TYPE *A, const TYPE *B, TYPE *C) {
|
||||
for (size_t i = 0; i < K * M; i++)
|
||||
C[i] = beta * C[i];
|
||||
for (size_t k = 0; k < K; k++) {
|
||||
|
@ -160,50 +172,46 @@ void call_gemm(
|
|||
}
|
||||
}
|
||||
template <class TYPE, class FUN>
|
||||
void FunctionTable::gemm( const TYPE alpha,
|
||||
const Array<TYPE, FUN> &a,
|
||||
const Array<TYPE, FUN> &b,
|
||||
const TYPE beta,
|
||||
Array<TYPE, FUN> &c )
|
||||
{
|
||||
void FunctionTable::gemm(const TYPE alpha, const Array<TYPE, FUN> &a,
|
||||
const Array<TYPE, FUN> &b, const TYPE beta,
|
||||
Array<TYPE, FUN> &c) {
|
||||
if (a.size(1) != b.size(0))
|
||||
throw std::logic_error("Inner dimensions must match");
|
||||
if (a.ndim() == 2 && b.ndim() == 1) {
|
||||
call_gemv<TYPE>( a.size( 0 ), a.size( 1 ), alpha, beta, a.data(), b.data(), c.data() );
|
||||
call_gemv<TYPE>(a.size(0), a.size(1), alpha, beta, a.data(), b.data(),
|
||||
c.data());
|
||||
} else if (a.ndim() <= 2 && b.ndim() <= 2) {
|
||||
call_gemm<TYPE>(
|
||||
a.size( 0 ), a.size( 1 ), b.size( 1 ), alpha, beta, a.data(), b.data(), c.data() );
|
||||
call_gemm<TYPE>(a.size(0), a.size(1), b.size(1), alpha, beta, a.data(),
|
||||
b.data(), c.data());
|
||||
} else {
|
||||
throw std::logic_error("Not finished yet");
|
||||
}
|
||||
}
|
||||
template <class TYPE, class FUN>
|
||||
void FunctionTable::multiply(const Array<TYPE, FUN> &a,
|
||||
const Array<TYPE, FUN> &b,
|
||||
Array<TYPE, FUN> &c )
|
||||
{
|
||||
const Array<TYPE, FUN> &b, Array<TYPE, FUN> &c) {
|
||||
if (a.size(1) != b.size(0))
|
||||
throw std::logic_error("Inner dimensions must match");
|
||||
if (a.ndim() == 2 && b.ndim() == 1) {
|
||||
c.resize(a.size(0));
|
||||
call_gemv<TYPE>( a.size( 0 ), a.size( 1 ), 1, 0, a.data(), b.data(), c.data() );
|
||||
call_gemv<TYPE>(a.size(0), a.size(1), 1, 0, a.data(), b.data(),
|
||||
c.data());
|
||||
} else if (a.ndim() <= 2 && b.ndim() <= 2) {
|
||||
c.resize(a.size(0), b.size(1));
|
||||
call_gemm<TYPE>(
|
||||
a.size( 0 ), a.size( 1 ), b.size( 1 ), 1, 0, a.data(), b.data(), c.data() );
|
||||
call_gemm<TYPE>(a.size(0), a.size(1), b.size(1), 1, 0, a.data(),
|
||||
b.data(), c.data());
|
||||
} else {
|
||||
throw std::logic_error("Not finished yet");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Check if two arrays are equal *
|
||||
********************************************************/
|
||||
template <class TYPE, class FUN>
|
||||
inline typename std::enable_if<std::is_integral<TYPE>::value, bool>::type
|
||||
FunctionTableCompare( const Array<TYPE, FUN> &a, const Array<TYPE, FUN> &b, TYPE )
|
||||
{
|
||||
FunctionTableCompare(const Array<TYPE, FUN> &a, const Array<TYPE, FUN> &b,
|
||||
TYPE) {
|
||||
bool pass = true;
|
||||
if (a.size() != b.size())
|
||||
throw std::logic_error("Sizes of x and y do not match");
|
||||
|
@ -213,8 +221,8 @@ FunctionTableCompare( const Array<TYPE, FUN> &a, const Array<TYPE, FUN> &b, TYPE
|
|||
}
|
||||
template <class TYPE, class FUN>
|
||||
inline typename std::enable_if<std::is_floating_point<TYPE>::value, bool>::type
|
||||
FunctionTableCompare( const Array<TYPE, FUN> &a, const Array<TYPE, FUN> &b, TYPE tol )
|
||||
{
|
||||
FunctionTableCompare(const Array<TYPE, FUN> &a, const Array<TYPE, FUN> &b,
|
||||
TYPE tol) {
|
||||
bool pass = true;
|
||||
if (a.size() != b.size())
|
||||
throw std::logic_error("Sizes of x and y do not match");
|
||||
|
@ -223,32 +231,33 @@ FunctionTableCompare( const Array<TYPE, FUN> &a, const Array<TYPE, FUN> &b, TYPE
|
|||
return pass;
|
||||
}
|
||||
template <class TYPE, class FUN>
|
||||
bool FunctionTable::equals( const Array<TYPE, FUN> &a, const Array<TYPE, FUN> &b, TYPE tol )
|
||||
{
|
||||
bool FunctionTable::equals(const Array<TYPE, FUN> &a, const Array<TYPE, FUN> &b,
|
||||
TYPE tol) {
|
||||
return FunctionTableCompare(a, b, tol);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Specialized Functions *
|
||||
********************************************************/
|
||||
template <class TYPE, class FUN, class ALLOC>
|
||||
void FunctionTable::transformReLU( const Array<TYPE, FUN, ALLOC> &A, Array<TYPE, FUN, ALLOC> &B )
|
||||
{
|
||||
const auto &fun = []( const TYPE &a ) { return std::max( a, static_cast<TYPE>( 0 ) ); };
|
||||
void FunctionTable::transformReLU(const Array<TYPE, FUN, ALLOC> &A,
|
||||
Array<TYPE, FUN, ALLOC> &B) {
|
||||
const auto &fun = [](const TYPE &a) {
|
||||
return std::max(a, static_cast<TYPE>(0));
|
||||
};
|
||||
transform(fun, A, B);
|
||||
}
|
||||
|
||||
template <class TYPE, class FUN, class ALLOC>
|
||||
void FunctionTable::transformAbs( const Array<TYPE, FUN, ALLOC> &A, Array<TYPE, FUN, ALLOC> &B )
|
||||
{
|
||||
void FunctionTable::transformAbs(const Array<TYPE, FUN, ALLOC> &A,
|
||||
Array<TYPE, FUN, ALLOC> &B) {
|
||||
B.resize(A.size());
|
||||
const auto &fun = [](const TYPE &a) { return std::abs(a); };
|
||||
transform(fun, A, B);
|
||||
}
|
||||
template <class TYPE, class FUN, class ALLOC>
|
||||
void FunctionTable::transformTanh( const Array<TYPE, FUN, ALLOC> &A, Array<TYPE, FUN, ALLOC> &B )
|
||||
{
|
||||
void FunctionTable::transformTanh(const Array<TYPE, FUN, ALLOC> &A,
|
||||
Array<TYPE, FUN, ALLOC> &B) {
|
||||
B.resize(A.size());
|
||||
const auto &fun = [](const TYPE &a) { return tanh(a); };
|
||||
transform(fun, A, B);
|
||||
|
@ -256,18 +265,18 @@ void FunctionTable::transformTanh( const Array<TYPE, FUN, ALLOC> &A, Array<TYPE,
|
|||
|
||||
template <class TYPE, class FUN, class ALLOC>
|
||||
void FunctionTable::transformHardTanh(const Array<TYPE, FUN, ALLOC> &A,
|
||||
Array<TYPE, FUN, ALLOC> &B )
|
||||
{
|
||||
Array<TYPE, FUN, ALLOC> &B) {
|
||||
B.resize(A.size());
|
||||
const auto &fun = [](const TYPE &a) {
|
||||
return std::max( -static_cast<TYPE>( 1.0 ), std::min( static_cast<TYPE>( 1.0 ), a ) );
|
||||
return std::max(-static_cast<TYPE>(1.0),
|
||||
std::min(static_cast<TYPE>(1.0), a));
|
||||
};
|
||||
transform(fun, A, B);
|
||||
}
|
||||
|
||||
template <class TYPE, class FUN, class ALLOC>
|
||||
void FunctionTable::transformSigmoid( const Array<TYPE, FUN, ALLOC> &A, Array<TYPE, FUN, ALLOC> &B )
|
||||
{
|
||||
void FunctionTable::transformSigmoid(const Array<TYPE, FUN, ALLOC> &A,
|
||||
Array<TYPE, FUN, ALLOC> &B) {
|
||||
B.resize(A.size());
|
||||
const auto &fun = [](const TYPE &a) { return 1.0 / (1.0 + exp(-a)); };
|
||||
transform(fun, A, B);
|
||||
|
@ -275,37 +284,24 @@ void FunctionTable::transformSigmoid( const Array<TYPE, FUN, ALLOC> &A, Array<TY
|
|||
|
||||
template <class TYPE, class FUN, class ALLOC>
|
||||
void FunctionTable::transformSoftPlus(const Array<TYPE, FUN, ALLOC> &A,
|
||||
Array<TYPE, FUN, ALLOC> &B )
|
||||
{
|
||||
Array<TYPE, FUN, ALLOC> &B) {
|
||||
B.resize(A.size());
|
||||
const auto &fun = [](const TYPE &a) { return log1p(exp(a)); };
|
||||
transform(fun, A, B);
|
||||
}
|
||||
|
||||
template <class TYPE, class FUN, class ALLOC>
|
||||
TYPE FunctionTable::sum( const Array<TYPE, FUN, ALLOC> &A )
|
||||
{
|
||||
TYPE FunctionTable::sum(const Array<TYPE, FUN, ALLOC> &A) {
|
||||
const auto &fun = [](const TYPE &a, const TYPE &b) { return a + b; };
|
||||
return reduce(fun, A, (TYPE)0);
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline void FunctionTable::gemmWrapper( char TRANSA,
|
||||
char TRANSB,
|
||||
int M,
|
||||
int N,
|
||||
int K,
|
||||
TYPE alpha,
|
||||
const TYPE *A,
|
||||
int LDA,
|
||||
const TYPE *B,
|
||||
int LDB,
|
||||
TYPE beta,
|
||||
TYPE *C,
|
||||
int LDC )
|
||||
{
|
||||
inline void FunctionTable::gemmWrapper(char TRANSA, char TRANSB, int M, int N,
|
||||
int K, TYPE alpha, const TYPE *A,
|
||||
int LDA, const TYPE *B, int LDB,
|
||||
TYPE beta, TYPE *C, int LDC) {
|
||||
ERROR("Not finished");
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
1434
common/MPI.cpp
1434
common/MPI.cpp
File diff suppressed because it is too large
Load Diff
197
common/MPI.h
197
common/MPI.h
|
@ -22,7 +22,6 @@ redistribution is prohibited.
|
|||
#ifndef included_LBPM_MPI
|
||||
#define included_LBPM_MPI
|
||||
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <complex>
|
||||
|
@ -31,7 +30,6 @@ redistribution is prohibited.
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
// Include mpi.h (or define MPI objects)
|
||||
// clang-format off
|
||||
#ifdef USE_MPI
|
||||
|
@ -48,10 +46,8 @@ redistribution is prohibited.
|
|||
#endif
|
||||
// clang-format on
|
||||
|
||||
|
||||
namespace Utilities {
|
||||
|
||||
|
||||
/**
|
||||
* \class MPI
|
||||
*
|
||||
|
@ -69,8 +65,7 @@ namespace Utilities {
|
|||
* succeed provided that the size of the data type object is a fixed size on
|
||||
* all processors. sizeof(type) must be the same for all elements and processors.
|
||||
*/
|
||||
class MPI final
|
||||
{
|
||||
class MPI final {
|
||||
public:
|
||||
enum class ThreadSupport : int { SINGLE, FUNNELED, SERIALIZED, MULTIPLE };
|
||||
|
||||
|
@ -87,11 +82,9 @@ public: // Constructors
|
|||
*/
|
||||
MPI();
|
||||
|
||||
|
||||
//! Empty destructor
|
||||
~MPI();
|
||||
|
||||
|
||||
/**
|
||||
* \brief Constructor from existing MPI communicator
|
||||
* \details This constructor creates a new communicator from an existing MPI communicator.
|
||||
|
@ -106,7 +99,6 @@ public: // Constructors
|
|||
*/
|
||||
MPI(MPI_Comm comm, bool manage = false);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Constructor from existing communicator
|
||||
* \details This constructor creates a new communicator from an existing communicator.
|
||||
|
@ -115,14 +107,12 @@ public: // Constructors
|
|||
*/
|
||||
MPI(const MPI &comm);
|
||||
|
||||
|
||||
/*!
|
||||
* Move constructor
|
||||
* @param rhs Communicator to copy
|
||||
*/
|
||||
MPI(MPI &&rhs);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Assignment operator
|
||||
* \details This operator overloads the assignment to correctly copy an communicator
|
||||
|
@ -130,21 +120,18 @@ public: // Constructors
|
|||
*/
|
||||
MPI &operator=(const MPI &comm);
|
||||
|
||||
|
||||
/*!
|
||||
* Move assignment operator
|
||||
* @param rhs Communicator to copy
|
||||
*/
|
||||
MPI &operator=(MPI &&rhs);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Reset the object
|
||||
* \details This resets the object to the empty state without an MPI_Comm
|
||||
*/
|
||||
void reset();
|
||||
|
||||
|
||||
public: // Member functions
|
||||
/**
|
||||
* \brief Get the node name
|
||||
|
@ -153,19 +140,15 @@ public: // Member functions
|
|||
*/
|
||||
static std::string getNodeName();
|
||||
|
||||
|
||||
//! Function to return the number of processors available
|
||||
static int getNumberOfProcessors();
|
||||
|
||||
|
||||
//! Function to return the affinity of the current process
|
||||
static std::vector<int> getProcessAffinity();
|
||||
|
||||
|
||||
//! Function to set the affinity of the current process
|
||||
static void setProcessAffinity(const std::vector<int> &procs);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Load balance the processes within a node
|
||||
* \details This function will redistribute the processes within a node using the
|
||||
|
@ -189,22 +172,21 @@ public: // Member functions
|
|||
* processors).
|
||||
*
|
||||
*/
|
||||
static void balanceProcesses( const MPI &comm = MPI( MPI_COMM_WORLD ), const int method = 1,
|
||||
const std::vector<int> &procs = std::vector<int>(), const int N_min = 1,
|
||||
const int N_max = -1 );
|
||||
|
||||
static void
|
||||
balanceProcesses(const MPI &comm = MPI(MPI_COMM_WORLD),
|
||||
const int method = 1,
|
||||
const std::vector<int> &procs = std::vector<int>(),
|
||||
const int N_min = 1, const int N_max = -1);
|
||||
|
||||
//! Query the level of thread support
|
||||
static ThreadSupport queryThreadSupport();
|
||||
|
||||
|
||||
/**
|
||||
* \brief Generate a random number
|
||||
* \details This generates a random number that is consistent across the comm
|
||||
*/
|
||||
size_t rand() const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Split an existing communicator
|
||||
* \details This creates a new communicator by splitting an existing communicator.
|
||||
|
@ -224,7 +206,6 @@ public: // Member functions
|
|||
*/
|
||||
MPI split(int color, int key = -1) const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Split an existing communicator by node
|
||||
* \details This creates a new communicator by splitting an existing communicator
|
||||
|
@ -242,7 +223,6 @@ public: // Member functions
|
|||
*/
|
||||
MPI splitByNode(int key = -1) const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Duplicate an existing communicator
|
||||
* \details This creates a new communicator by duplicating an existing communicator.
|
||||
|
@ -253,7 +233,6 @@ public: // Member functions
|
|||
*/
|
||||
MPI dup() const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Create a communicator from the intersection of two communicators
|
||||
* \details This creates a new communicator by intersecting two existing communicators.
|
||||
|
@ -267,13 +246,11 @@ public: // Member functions
|
|||
*/
|
||||
static MPI intersect(const MPI &comm1, const MPI &comm2);
|
||||
|
||||
|
||||
/**
|
||||
* Check if the current communicator is NULL
|
||||
*/
|
||||
bool isNull() const { return d_isNull; }
|
||||
|
||||
|
||||
/**
|
||||
* \brief Return the global ranks for the comm
|
||||
* \details This returns a vector which contains the global ranks for each
|
||||
|
@ -283,7 +260,6 @@ public: // Member functions
|
|||
*/
|
||||
std::vector<int> globalRanks() const;
|
||||
|
||||
|
||||
/**
|
||||
* Get the current MPI communicator.
|
||||
* Note: The underlying MPI_Comm object may be free'd by the object when it is no
|
||||
|
@ -294,7 +270,6 @@ public: // Member functions
|
|||
*/
|
||||
const MPI_Comm &getCommunicator() const { return communicator; }
|
||||
|
||||
|
||||
/**
|
||||
* \brief Overload operator ==
|
||||
* \details Overload operator comm1 == comm2. Two MPI objects are == if they share the same
|
||||
|
@ -303,7 +278,6 @@ public: // Member functions
|
|||
*/
|
||||
bool operator==(const MPI &) const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Overload operator !=
|
||||
* \details Overload operator comm1 != comm2. Two MPI objects are != if they
|
||||
|
@ -312,7 +286,6 @@ public: // Member functions
|
|||
*/
|
||||
bool operator!=(const MPI &) const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Overload operator <
|
||||
* \details Overload operator comm1 < comm2. One MPI object is < another iff all the
|
||||
|
@ -326,7 +299,6 @@ public: // Member functions
|
|||
*/
|
||||
bool operator<(const MPI &) const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Overload operator <=
|
||||
* \details Overload operator comm1 <= comm2. One MPI object is <= another iff all the
|
||||
|
@ -339,7 +311,6 @@ public: // Member functions
|
|||
*/
|
||||
bool operator<=(const MPI &) const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Overload operator >
|
||||
* \details Overload operator comm1 > comm2. One MPI object is > another iff all the
|
||||
|
@ -353,7 +324,6 @@ public: // Member functions
|
|||
*/
|
||||
bool operator>(const MPI &) const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Overload operator >=
|
||||
* \details Overload operator comm1 >= comm2. One MPI object is > another iff all the
|
||||
|
@ -367,7 +337,6 @@ public: // Member functions
|
|||
*/
|
||||
bool operator>=(const MPI &) const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Compare to another communicator
|
||||
* \details This compares the current communicator to another communicator.
|
||||
|
@ -378,26 +347,22 @@ public: // Member functions
|
|||
*/
|
||||
int compare(const MPI &) const;
|
||||
|
||||
|
||||
/**
|
||||
* Return the processor rank (identifier) from 0 through the number of
|
||||
* processors minus one.
|
||||
*/
|
||||
int getRank() const { return comm_rank; }
|
||||
|
||||
|
||||
/**
|
||||
* Return the number of processors.
|
||||
*/
|
||||
int getSize() const { return comm_size; }
|
||||
|
||||
|
||||
/**
|
||||
* Return the maximum tag
|
||||
*/
|
||||
int maxTag() const { return d_maxTag; }
|
||||
|
||||
|
||||
/**
|
||||
* \brief Return a new tag
|
||||
* \details This routine will return an unused tag for communication.
|
||||
|
@ -406,7 +371,6 @@ public: // Member functions
|
|||
*/
|
||||
int newTag();
|
||||
|
||||
|
||||
/**
|
||||
* Call MPI_Abort or exit depending on whether running with one or more
|
||||
* processes and value set by function above, if called. The default is
|
||||
|
@ -416,7 +380,6 @@ public: // Member functions
|
|||
*/
|
||||
void abort() const;
|
||||
|
||||
|
||||
/**
|
||||
* Set boolean flag indicating whether exit or abort is called when running
|
||||
* with one processor. Calling this function influences the behavior of
|
||||
|
@ -425,7 +388,6 @@ public: // Member functions
|
|||
*/
|
||||
void setCallAbortInSerialInsteadOfExit(bool flag = true);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Boolean all reduce
|
||||
* \details This function performs a boolean all reduce across all processors.
|
||||
|
@ -434,7 +396,6 @@ public: // Member functions
|
|||
*/
|
||||
bool allReduce(const bool value) const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Boolean any reduce
|
||||
* \details This function performs a boolean any reduce across all processors.
|
||||
|
@ -443,16 +404,13 @@ public: // Member functions
|
|||
*/
|
||||
bool anyReduce(const bool value) const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Sum Reduce
|
||||
* \details This function performs a sum all reduce across all processor.
|
||||
* It returns the sum across all processors;
|
||||
* \param value The input value for the all reduce
|
||||
*/
|
||||
template<class type>
|
||||
type sumReduce( const type value ) const;
|
||||
|
||||
template <class type> type sumReduce(const type value) const;
|
||||
|
||||
/**
|
||||
* \brief Sum Reduce
|
||||
|
@ -462,9 +420,7 @@ public: // Member functions
|
|||
* \param x The input/output array for the reduce
|
||||
* \param n The number of values in the array (must match on all nodes)
|
||||
*/
|
||||
template<class type>
|
||||
void sumReduce( type *x, const int n = 1 ) const;
|
||||
|
||||
template <class type> void sumReduce(type *x, const int n = 1) const;
|
||||
|
||||
/**
|
||||
* \brief Sum Reduce
|
||||
|
@ -478,16 +434,13 @@ public: // Member functions
|
|||
template <class type>
|
||||
void sumReduce(const type *x, type *y, const int n = 1) const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Min Reduce
|
||||
* \details This function performs a min all reduce across all processor.
|
||||
* It returns the minimum value across all processors;
|
||||
* \param value The input value for the all reduce
|
||||
*/
|
||||
template<class type>
|
||||
type minReduce( const type value ) const;
|
||||
|
||||
template <class type> type minReduce(const type value) const;
|
||||
|
||||
/**
|
||||
* \brief Sum Reduce
|
||||
|
@ -506,7 +459,6 @@ public: // Member functions
|
|||
template <class type>
|
||||
void minReduce(type *x, const int n = 1, int *rank_of_min = nullptr) const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Sum Reduce
|
||||
* \details Perform an array min Reduce across all nodes. Each
|
||||
|
@ -523,8 +475,8 @@ public: // Member functions
|
|||
* minimum value
|
||||
*/
|
||||
template <class type>
|
||||
void minReduce( const type *x, type *y, const int n = 1, int *rank_of_min = nullptr ) const;
|
||||
|
||||
void minReduce(const type *x, type *y, const int n = 1,
|
||||
int *rank_of_min = nullptr) const;
|
||||
|
||||
/**
|
||||
* \brief Max Reduce
|
||||
|
@ -532,9 +484,7 @@ public: // Member functions
|
|||
* It returns the maximum value across all processors;
|
||||
* \param value The input value for the all reduce
|
||||
*/
|
||||
template<class type>
|
||||
type maxReduce( const type value ) const;
|
||||
|
||||
template <class type> type maxReduce(const type value) const;
|
||||
|
||||
/**
|
||||
* \brief Sum Reduce
|
||||
|
@ -553,7 +503,6 @@ public: // Member functions
|
|||
template <class type>
|
||||
void maxReduce(type *x, const int n = 1, int *rank_of_max = nullptr) const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Sum Reduce
|
||||
* \details Perform an array max Reduce across all nodes. Each
|
||||
|
@ -570,8 +519,8 @@ public: // Member functions
|
|||
* minimum value
|
||||
*/
|
||||
template <class type>
|
||||
void maxReduce( const type *x, type *y, const int n = 1, int *rank_of_max = nullptr ) const;
|
||||
|
||||
void maxReduce(const type *x, type *y, const int n = 1,
|
||||
int *rank_of_max = nullptr) const;
|
||||
|
||||
/**
|
||||
* \brief Scan Sum Reduce
|
||||
|
@ -584,7 +533,6 @@ public: // Member functions
|
|||
template <class type>
|
||||
void sumScan(const type *x, type *y, const int n = 1) const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Scan Min Reduce
|
||||
* \details Computes the min scan (partial reductions) of data on a collection of processes.
|
||||
|
@ -596,7 +544,6 @@ public: // Member functions
|
|||
template <class type>
|
||||
void minScan(const type *x, type *y, const int n = 1) const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Scan Max Reduce
|
||||
* \details Computes the max scan (partial reductions) of data on a collection of processes.
|
||||
|
@ -608,16 +555,13 @@ public: // Member functions
|
|||
template <class type>
|
||||
void maxScan(const type *x, type *y, const int n = 1) const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Broadcast
|
||||
* \details This function broadcasts a value from root to all processors
|
||||
* \param value The input value for the broadcast.
|
||||
* \param root The processor performing the broadcast
|
||||
*/
|
||||
template<class type>
|
||||
type bcast( const type &value, const int root ) const;
|
||||
|
||||
template <class type> type bcast(const type &value, const int root) const;
|
||||
|
||||
/**
|
||||
* \brief Broadcast
|
||||
|
@ -629,13 +573,11 @@ public: // Member functions
|
|||
template <class type>
|
||||
void bcast(type *value, const int n, const int root) const;
|
||||
|
||||
|
||||
/**
|
||||
* Perform a global barrier across all processors.
|
||||
*/
|
||||
void barrier() const;
|
||||
|
||||
|
||||
/*!
|
||||
* @brief This function sends an MPI message with an array to another processor.
|
||||
*
|
||||
|
@ -653,8 +595,8 @@ public: // Member functions
|
|||
* The matching recv must share this tag.
|
||||
*/
|
||||
template <class type>
|
||||
void send( const type *buf, const int length, const int recv, int tag = 0 ) const;
|
||||
|
||||
void send(const type *buf, const int length, const int recv,
|
||||
int tag = 0) const;
|
||||
|
||||
/*!
|
||||
* @brief This function sends an MPI message with an array of bytes
|
||||
|
@ -669,8 +611,8 @@ public: // Member functions
|
|||
* to be sent with this message. Default tag is 0.
|
||||
* The matching recv must share this tag.
|
||||
*/
|
||||
void sendBytes( const void *buf, const int N_bytes, const int recv, int tag = 0 ) const;
|
||||
|
||||
void sendBytes(const void *buf, const int N_bytes, const int recv,
|
||||
int tag = 0) const;
|
||||
|
||||
/*!
|
||||
* @brief This function sends an MPI message with an array
|
||||
|
@ -685,9 +627,8 @@ public: // Member functions
|
|||
* to be sent with this message.
|
||||
*/
|
||||
template <class type>
|
||||
MPI_Request Isend(
|
||||
const type *buf, const int length, const int recv_proc, const int tag ) const;
|
||||
|
||||
MPI_Request Isend(const type *buf, const int length, const int recv_proc,
|
||||
const int tag) const;
|
||||
|
||||
/*!
|
||||
* @brief This function sends an MPI message with an array of bytes
|
||||
|
@ -701,9 +642,8 @@ public: // Member functions
|
|||
* @param tag Integer argument specifying an integer tag
|
||||
* to be sent with this message.
|
||||
*/
|
||||
MPI_Request IsendBytes(
|
||||
const void *buf, const int N_bytes, const int recv_proc, const int tag ) const;
|
||||
|
||||
MPI_Request IsendBytes(const void *buf, const int N_bytes,
|
||||
const int recv_proc, const int tag) const;
|
||||
|
||||
/*!
|
||||
* @brief This function receives an MPI message with a data
|
||||
|
@ -722,13 +662,11 @@ public: // Member functions
|
|||
* by the tag of the incoming message. Default tag is 0.
|
||||
*/
|
||||
template <class type>
|
||||
inline void recv( type *buf, int length, const int send, int tag ) const
|
||||
{
|
||||
inline void recv(type *buf, int length, const int send, int tag) const {
|
||||
int length2 = length;
|
||||
recv(buf, length2, send, false, tag);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* @brief This function receives an MPI message with a data
|
||||
* array from another processor.
|
||||
|
@ -749,8 +687,8 @@ public: // Member functions
|
|||
* by the tag of the incoming message. Default tag is 0.
|
||||
*/
|
||||
template <class type>
|
||||
void recv( type *buf, int &length, const int send, const bool get_length, int tag ) const;
|
||||
|
||||
void recv(type *buf, int &length, const int send, const bool get_length,
|
||||
int tag) const;
|
||||
|
||||
/*!
|
||||
* @brief This function receives an MPI message with an array of
|
||||
|
@ -767,7 +705,6 @@ public: // Member functions
|
|||
*/
|
||||
void recvBytes(void *buf, int &N_bytes, const int send, int tag = 0) const;
|
||||
|
||||
|
||||
/*!
|
||||
* @brief This function receives an MPI message with a data
|
||||
* array from another processor using a non-blocking call.
|
||||
|
@ -779,8 +716,8 @@ public: // Member functions
|
|||
* be matched by the tag of the incoming message.
|
||||
*/
|
||||
template <class type>
|
||||
MPI_Request Irecv( type *buf, const int length, const int send_proc, const int tag ) const;
|
||||
|
||||
MPI_Request Irecv(type *buf, const int length, const int send_proc,
|
||||
const int tag) const;
|
||||
|
||||
/*!
|
||||
* @brief This function receives an MPI message with an array of
|
||||
|
@ -794,26 +731,22 @@ public: // Member functions
|
|||
* @param tag Integer argument specifying a tag which must
|
||||
* be matched by the tag of the incoming message.
|
||||
*/
|
||||
MPI_Request IrecvBytes(
|
||||
void *buf, const int N_bytes, const int send_proc, const int tag ) const;
|
||||
|
||||
MPI_Request IrecvBytes(void *buf, const int N_bytes, const int send_proc,
|
||||
const int tag) const;
|
||||
|
||||
/*!
|
||||
* @brief This function sends and recieves data using a blocking call
|
||||
*/
|
||||
template <class type>
|
||||
void sendrecv( const type *sendbuf, int sendcount, int dest, int sendtag, type *recvbuf,
|
||||
int recvcount, int source, int recvtag ) const;
|
||||
|
||||
void sendrecv(const type *sendbuf, int sendcount, int dest, int sendtag,
|
||||
type *recvbuf, int recvcount, int source, int recvtag) const;
|
||||
|
||||
/*!
|
||||
* Each processor sends every other processor a single value.
|
||||
* @param[in] x Input value for allGather
|
||||
* @return Output array for allGather
|
||||
*/
|
||||
template<class type>
|
||||
std::vector<type> allGather( const type &x ) const;
|
||||
|
||||
template <class type> std::vector<type> allGather(const type &x) const;
|
||||
|
||||
/*!
|
||||
* Each processor sends every other processor an array
|
||||
|
@ -823,7 +756,6 @@ public: // Member functions
|
|||
template <class type>
|
||||
std::vector<type> allGather(const std::vector<type> &x) const;
|
||||
|
||||
|
||||
/*!
|
||||
* Each processor sends every other processor a single value.
|
||||
* The x_out array should be preallocated to a length equal
|
||||
|
@ -832,9 +764,7 @@ public: // Member functions
|
|||
* @param x_out Output array for allGather (must be preallocated to the size of the
|
||||
* communicator)
|
||||
*/
|
||||
template<class type>
|
||||
void allGather( const type &x_in, type *x_out ) const;
|
||||
|
||||
template <class type> void allGather(const type &x_in, type *x_out) const;
|
||||
|
||||
/*!
|
||||
* Each processor sends an array of data to all other processors.
|
||||
|
@ -863,16 +793,14 @@ public: // Member functions
|
|||
*/
|
||||
template <class type>
|
||||
int allGather(const type *send_data, const int send_cnt, type *recv_data,
|
||||
int *recv_cnt = nullptr, int *recv_disp = nullptr, bool known_recv = false ) const;
|
||||
|
||||
int *recv_cnt = nullptr, int *recv_disp = nullptr,
|
||||
bool known_recv = false) const;
|
||||
|
||||
/*!
|
||||
* This function combines sets from different processors to create a single master set
|
||||
* @param set Input/Output std::set for the gather.
|
||||
*/
|
||||
template<class type>
|
||||
void setGather( std::set<type> &set ) const;
|
||||
|
||||
template <class type> void setGather(std::set<type> &set) const;
|
||||
|
||||
/*!
|
||||
* This function combines std::maps from different processors to create a single master std::map
|
||||
|
@ -882,7 +810,6 @@ public: // Member functions
|
|||
template <class KEY, class DATA>
|
||||
void mapGather(std::map<KEY, DATA> &map) const;
|
||||
|
||||
|
||||
/*!
|
||||
* Each processor sends an array of n values to each processor.
|
||||
* Each processor sends an array of n values to each processor.
|
||||
|
@ -897,7 +824,6 @@ public: // Member functions
|
|||
template <class type>
|
||||
void allToAll(const int n, const type *send_data, type *recv_data) const;
|
||||
|
||||
|
||||
/*!
|
||||
* Each processor sends an array of data to the different processors.
|
||||
* Each processor may send any size array to any processor. In the variable
|
||||
|
@ -927,11 +853,11 @@ public: // Member functions
|
|||
* and the sizes and displacements will be returned (if desired).
|
||||
*/
|
||||
template <class type>
|
||||
int allToAll( const type *send_data, const int send_cnt[], const int send_disp[],
|
||||
type *recv_data, int *recv_cnt = nullptr, int *recv_disp = nullptr,
|
||||
int allToAll(const type *send_data, const int send_cnt[],
|
||||
const int send_disp[], type *recv_data,
|
||||
int *recv_cnt = nullptr, int *recv_disp = nullptr,
|
||||
bool known_recv = false) const;
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Send a list of proccesor ids to communicate
|
||||
* \details This function communicates a list of proccesors to communicate.
|
||||
|
@ -944,7 +870,6 @@ public: // Member functions
|
|||
*/
|
||||
std::vector<int> commRanks(const std::vector<int> &ranks) const;
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Wait for a communication to finish
|
||||
* \details Wait for a communication to finish.
|
||||
|
@ -953,7 +878,6 @@ public: // Member functions
|
|||
*/
|
||||
static void wait(MPI_Request request);
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Wait for any communication to finish.
|
||||
* \details This function waits for any of the given communication requests to finish.
|
||||
|
@ -964,7 +888,6 @@ public: // Member functions
|
|||
*/
|
||||
static int waitAny(int count, MPI_Request *request);
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Wait for all communications to finish.
|
||||
* \details This function waits for all of the given communication requests to finish.
|
||||
|
@ -974,7 +897,6 @@ public: // Member functions
|
|||
*/
|
||||
static void waitAll(int count, MPI_Request *request);
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Wait for some communications to finish.
|
||||
* \details This function waits for one (or more) communications to finish.
|
||||
|
@ -985,7 +907,6 @@ public: // Member functions
|
|||
*/
|
||||
static std::vector<int> waitSome(int count, MPI_Request *request);
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Nonblocking test for a message
|
||||
* \details This function performs a non-blocking test for a message.
|
||||
|
@ -997,7 +918,6 @@ public: // Member functions
|
|||
*/
|
||||
int Iprobe(int source = -1, int tag = -1) const;
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Blocking test for a message
|
||||
* \details This function performs a blocking test for a message.
|
||||
|
@ -1008,7 +928,6 @@ public: // Member functions
|
|||
*/
|
||||
int probe(int source = -1, int tag = -1) const;
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Start a serial region
|
||||
* \details This function will serialize MPI processes so that they run
|
||||
|
@ -1018,14 +937,12 @@ public: // Member functions
|
|||
*/
|
||||
void serializeStart();
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Stop a serial region
|
||||
* \details Stop a serial region. See serializeStart for more information.
|
||||
*/
|
||||
void serializeStop();
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Elapsed time
|
||||
* \details This function returns the elapsed time on the calling processor
|
||||
|
@ -1036,14 +953,12 @@ public: // Member functions
|
|||
*/
|
||||
static double time();
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Timer resolution
|
||||
* \details This function returns the timer resolution used by "time"
|
||||
*/
|
||||
static double tick();
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Change the level of the internal timers
|
||||
* \details This function changes the level of the timers used to profile MPI
|
||||
|
@ -1051,7 +966,6 @@ public: // Member functions
|
|||
*/
|
||||
static void changeProfileLevel(int level) { profile_level = level; }
|
||||
|
||||
|
||||
//! Return the total number of MPI_Comm objects that have been created
|
||||
static size_t MPI_Comm_created() { return N_MPI_Comm_created; }
|
||||
|
||||
|
@ -1073,7 +987,6 @@ public: // Member functions
|
|||
//! Stop MPI
|
||||
static void stop_MPI();
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Load balance
|
||||
* \details This function will return a new communicator in which the ranks match
|
||||
|
@ -1082,27 +995,28 @@ public: // Member functions
|
|||
MPI loadBalance(double localPerformance, std::vector<double> work);
|
||||
|
||||
private: // Private helper functions for templated MPI operations;
|
||||
template<class type>
|
||||
void call_sumReduce( type *x, const int n = 1 ) const;
|
||||
template <class type> void call_sumReduce(type *x, const int n = 1) const;
|
||||
template <class type>
|
||||
void call_sumReduce(const type *x, type *y, const int n = 1) const;
|
||||
template <class type>
|
||||
void call_minReduce( type *x, const int n = 1, int *rank_of_min = nullptr ) const;
|
||||
void call_minReduce(type *x, const int n = 1,
|
||||
int *rank_of_min = nullptr) const;
|
||||
template <class type>
|
||||
void call_minReduce(
|
||||
const type *x, type *y, const int n = 1, int *rank_of_min = nullptr ) const;
|
||||
void call_minReduce(const type *x, type *y, const int n = 1,
|
||||
int *rank_of_min = nullptr) const;
|
||||
template <class type>
|
||||
void call_maxReduce( type *x, const int n = 1, int *rank_of_max = nullptr ) const;
|
||||
void call_maxReduce(type *x, const int n = 1,
|
||||
int *rank_of_max = nullptr) const;
|
||||
template <class type>
|
||||
void call_maxReduce(
|
||||
const type *x, type *y, const int n = 1, int *rank_of_max = nullptr ) const;
|
||||
void call_maxReduce(const type *x, type *y, const int n = 1,
|
||||
int *rank_of_max = nullptr) const;
|
||||
template <class type>
|
||||
void call_bcast(type *x, const int n, const int root) const;
|
||||
template <class type>
|
||||
void call_allGather(const type &x_in, type *x_out) const;
|
||||
template <class type>
|
||||
void call_allGather(
|
||||
const type *x_in, int size_in, type *x_out, int *size_out, int *disp_out ) const;
|
||||
void call_allGather(const type *x_in, int size_in, type *x_out,
|
||||
int *size_out, int *disp_out) const;
|
||||
template <class type>
|
||||
void call_sumScan(const type *x, type *y, int n = 1) const;
|
||||
template <class type>
|
||||
|
@ -1110,9 +1024,9 @@ private: // Private helper functions for templated MPI operations;
|
|||
template <class type>
|
||||
void call_maxScan(const type *x, type *y, int n = 1) const;
|
||||
template <class type>
|
||||
void call_allToAll( const type *send_data, const int send_cnt[], const int send_disp[],
|
||||
type *recv_data, const int *recv_cnt, const int *recv_disp ) const;
|
||||
|
||||
void call_allToAll(const type *send_data, const int send_cnt[],
|
||||
const int send_disp[], type *recv_data,
|
||||
const int *recv_cnt, const int *recv_disp) const;
|
||||
|
||||
private: // data members
|
||||
// The internal MPI communicator
|
||||
|
@ -1157,14 +1071,11 @@ private: // data members
|
|||
static volatile unsigned int N_MPI_Comm_destroyed;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Utilities
|
||||
|
||||
|
||||
// Include the default instantiations
|
||||
// \cond HIDDEN_SYMBOLS
|
||||
#include "common/MPI.I"
|
||||
// \endcond
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,10 +5,8 @@
|
|||
|
||||
#include <cstring>
|
||||
|
||||
|
||||
// Read a file into memory
|
||||
std::vector<char> readFile( const std::string& filename )
|
||||
{
|
||||
std::vector<char> readFile(const std::string &filename) {
|
||||
auto fid = fopen(filename.c_str(), "rb");
|
||||
INSIST(fid, "File does not exist: " + filename);
|
||||
fseek(fid, 0, SEEK_END);
|
||||
|
@ -21,10 +19,8 @@ std::vector<char> readFile( const std::string& filename )
|
|||
return data;
|
||||
}
|
||||
|
||||
|
||||
// Decompress a gzip buffer
|
||||
std::vector<char> gunzip( const std::vector<char>& in )
|
||||
{
|
||||
std::vector<char> gunzip(const std::vector<char> &in) {
|
||||
z_stream stream;
|
||||
std::vector<char> out(1000000);
|
||||
stream.next_in = (Bytef *)in.data();
|
||||
|
@ -50,10 +46,8 @@ std::vector<char> gunzip( const std::vector<char>& in )
|
|||
return out;
|
||||
}
|
||||
|
||||
|
||||
// Read the compressed micro CT data
|
||||
Array<uint8_t> readMicroCT( const std::string& filename )
|
||||
{
|
||||
Array<uint8_t> readMicroCT(const std::string &filename) {
|
||||
auto in = readFile(filename);
|
||||
auto out = gunzip(in);
|
||||
ASSERT(out.size() == 1024 * 1024 * 1024);
|
||||
|
@ -62,10 +56,8 @@ Array<uint8_t> readMicroCT( const std::string& filename )
|
|||
return data;
|
||||
}
|
||||
|
||||
|
||||
// Read the compressed micro CT data and distribute
|
||||
Array<uint8_t> readMicroCT( const Database& domain, const Utilities::MPI& comm )
|
||||
{
|
||||
Array<uint8_t> readMicroCT(const Database &domain, const Utilities::MPI &comm) {
|
||||
// Get the local problem info
|
||||
auto n = domain.getVector<int>("n");
|
||||
int rank = comm.getRank();
|
||||
|
@ -84,11 +76,15 @@ Array<uint8_t> readMicroCT( const Database& domain, const Utilities::MPI& comm )
|
|||
auto filename = domain.getScalar<std::string>("Filename");
|
||||
char tmp[100];
|
||||
if (filename.find("0x_0y_0z.gbd.gz") != std::string::npos) {
|
||||
sprintf( tmp, "%ix_%iy_%iz.gbd.gz", srcRankInfo.ix, srcRankInfo.jy, srcRankInfo.kz );
|
||||
filename = filename.replace( filename.find( "0x_0y_0z.gbd.gz" ), 15, std::string( tmp ) );
|
||||
sprintf(tmp, "%ix_%iy_%iz.gbd.gz", srcRankInfo.ix, srcRankInfo.jy,
|
||||
srcRankInfo.kz);
|
||||
filename = filename.replace(filename.find("0x_0y_0z.gbd.gz"), 15,
|
||||
std::string(tmp));
|
||||
} else if (filename.find("x0_y0_z0.gbd.gz") != std::string::npos) {
|
||||
sprintf( tmp, "x%i_y%i_z%i.gbd.gz", srcRankInfo.ix, srcRankInfo.jy, srcRankInfo.kz );
|
||||
filename = filename.replace( filename.find( "x0_y0_z0.gbd.gz" ), 15, std::string( tmp ) );
|
||||
sprintf(tmp, "x%i_y%i_z%i.gbd.gz", srcRankInfo.ix, srcRankInfo.jy,
|
||||
srcRankInfo.kz);
|
||||
filename = filename.replace(filename.find("x0_y0_z0.gbd.gz"), 15,
|
||||
std::string(tmp));
|
||||
} else {
|
||||
ERROR("Invalid name for first file");
|
||||
}
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
#ifndef READMICROCT_H
|
||||
#define READMICROCT_H
|
||||
|
||||
|
||||
#include "common/Array.h"
|
||||
#include "common/Communication.h"
|
||||
#include "common/Database.h"
|
||||
#include "common/MPI.h"
|
||||
|
||||
|
||||
Array<uint8_t> readMicroCT(const std::string &filename);
|
||||
|
||||
Array<uint8_t> readMicroCT(const Database &domain, const Utilities::MPI &comm);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "common/ScaLBL.h"
|
||||
|
||||
#include <chrono>
|
||||
|
@ -1356,6 +1372,14 @@ void ScaLBL_Communicator::SolidNeumannD3Q7(double *fq, double *BoundaryValue){
|
|||
ScaLBL_Solid_Neumann_D3Q7(fq,BoundaryValue,bb_dist,bb_interactions,n_bb_d3q7);
|
||||
}
|
||||
|
||||
void ScaLBL_Communicator::SolidDirichletAndNeumannD3Q7(double *fq, double *BoundaryValue, int *BoundaryLabel){
|
||||
// fq is a D3Q7 distribution
|
||||
// BoundaryValues is a list of values to assign at bounce-back solid sites
|
||||
// BoundaryLabel: is a list of integer labels indicating the type of BCs
|
||||
// 1-> Dirichlet BC; 2-> Neumann BC.
|
||||
ScaLBL_Solid_DirichletAndNeumann_D3Q7(fq,BoundaryValue,BoundaryLabel,bb_dist,bb_interactions,n_bb_d3q7);
|
||||
}
|
||||
|
||||
void ScaLBL_Communicator::SolidSlippingVelocityBCD3Q19(double *fq, double *zeta_potential, double *ElectricField, double *SolidGrad,
|
||||
double epsilon_LB, double tau, double rho0, double den_scale,double h, double time_conv){
|
||||
// fq is a D3Q19 distribution
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file ScaLBL.h */
|
||||
/* \details Header file for Scalable Lattice Boltzmann Library
|
||||
* Separate implementations for GPU and CPU must both follow the conventions defined in this header
|
||||
|
@ -593,6 +609,8 @@ extern "C" void ScaLBL_Solid_Dirichlet_D3Q7(double *dist,double *BoundaryValue,i
|
|||
|
||||
extern "C" void ScaLBL_Solid_Neumann_D3Q7(double *dist,double *BoundaryValue,int *BounceBackDist_list,int *BounceBackSolid_list,int N);
|
||||
|
||||
extern "C" void ScaLBL_Solid_DirichletAndNeumann_D3Q7(double *dist,double *BoundaryValue,int *BoundaryLabel,int *BounceBackDist_list,int *BounceBackSolid_list,int N);
|
||||
|
||||
extern "C" void ScaLBL_Solid_SlippingVelocityBC_D3Q19(double *dist, double *zeta_potential, double *ElectricField, double *SolidGrad,
|
||||
double epsilon_LB, double tau, double rho0,double den_scale, double h, double time_conv,
|
||||
int *BounceBackDist_list, int *BounceBackSolid_list, int *FluidBoundary_list,
|
||||
|
@ -700,6 +718,7 @@ public:
|
|||
void SetupBounceBackList(IntArray &Map, signed char *id, int Np, bool SlippingVelBC=false);
|
||||
void SolidDirichletD3Q7(double *fq, double *BoundaryValue);
|
||||
void SolidNeumannD3Q7(double *fq, double *BoundaryValue);
|
||||
void SolidDirichletAndNeumannD3Q7(double *fq, double *BoundaryValue, int *BoundaryLabel);
|
||||
void SolidSlippingVelocityBCD3Q19(double *fq, double *zeta_potential, double *ElectricField, double *SolidGrad,
|
||||
double epslion_LB, double tau, double rho0, double den_scale,double h, double time_conv);
|
||||
|
||||
|
@ -786,6 +805,4 @@ private:
|
|||
//......................................................................................
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,35 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
|
@ -15,14 +47,15 @@
|
|||
#include "common/SpherePack.h"
|
||||
|
||||
// Inline function to read line without a return argument
|
||||
static inline void fgetl( char * str, int num, FILE * stream )
|
||||
{
|
||||
static inline void fgetl(char *str, int num, FILE *stream) {
|
||||
char *ptr = fgets(str, num, stream);
|
||||
if ( 0 ) {char *temp = (char *)&ptr; temp++;}
|
||||
if (0) {
|
||||
char *temp = (char *)&ptr;
|
||||
temp++;
|
||||
}
|
||||
}
|
||||
|
||||
void WriteLocalSolidID(char *FILENAME, char *ID, int N)
|
||||
{
|
||||
void WriteLocalSolidID(char *FILENAME, char *ID, int N) {
|
||||
char value;
|
||||
ofstream File(FILENAME, ios::binary);
|
||||
for (int n = 0; n < N; n++) {
|
||||
|
@ -32,8 +65,7 @@ void WriteLocalSolidID(char *FILENAME, char *ID, int N)
|
|||
File.close();
|
||||
}
|
||||
|
||||
void WriteLocalSolidDistance(char *FILENAME, double *Distance, int N)
|
||||
{
|
||||
void WriteLocalSolidDistance(char *FILENAME, double *Distance, int N) {
|
||||
double value;
|
||||
ofstream File(FILENAME, ios::binary);
|
||||
for (int n = 0; n < N; n++) {
|
||||
|
@ -43,8 +75,8 @@ void WriteLocalSolidDistance(char *FILENAME, double *Distance, int N)
|
|||
File.close();
|
||||
}
|
||||
|
||||
void ReadSpherePacking(int nspheres, double *List_cx, double *List_cy, double *List_cz, double *List_rad)
|
||||
{
|
||||
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;
|
||||
|
@ -69,14 +101,16 @@ void ReadSpherePacking(int nspheres, double *List_cx, double *List_cy, double *L
|
|||
count++;
|
||||
}
|
||||
cout << "Number of spheres extracted is: " << count << endl;
|
||||
INSIST( count==nspheres, "Specified number of spheres is probably incorrect!" );
|
||||
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,
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
@ -131,18 +165,30 @@ void AssignLocalSolidID(char *ID, int nspheres, double *List_cx, double *List_cy
|
|||
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;
|
||||
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++) {
|
||||
|
@ -153,7 +199,9 @@ void AssignLocalSolidID(char *ID, int nspheres, double *List_cx, double *List_cy
|
|||
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){
|
||||
if ((cx - x) * (cx - x) + (cy - y) * (cy - y) +
|
||||
(cz - z) * (cz - z) <
|
||||
r * r) {
|
||||
value = 0;
|
||||
}
|
||||
// get the position in the list
|
||||
|
@ -167,10 +215,11 @@ void AssignLocalSolidID(char *ID, int nspheres, double *List_cx, double *List_cy
|
|||
}
|
||||
}
|
||||
|
||||
void SignedDistance(double *Distance, int nspheres, double *List_cx, double *List_cy, double *List_cz, double *List_rad,
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
@ -221,18 +270,30 @@ void SignedDistance(double *Distance, int nspheres, double *List_cx, double *Lis
|
|||
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;
|
||||
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++) {
|
||||
|
@ -245,15 +306,18 @@ void SignedDistance(double *Distance, int nspheres, double *List_cx, double *Lis
|
|||
// 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;
|
||||
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;
|
||||
|
||||
if (distance < Distance[n])
|
||||
Distance[n] = distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Map the distance to lattice units
|
||||
for (n=0; n<N; n++) Distance[n] = Distance[n]/hx;
|
||||
for (n = 0; n < N; n++)
|
||||
Distance[n] = Distance[n] / hx;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef SpherePack_INC
|
||||
#define SpherePack_INC
|
||||
|
||||
|
@ -24,14 +40,19 @@ void WriteLocalSolidID(char *FILENAME, char *ID, int N);
|
|||
|
||||
void WriteLocalSolidDistance(char *FILENAME, double *Distance, int N);
|
||||
|
||||
void ReadSpherePacking(int nspheres, double *List_cx, double *List_cy, double *List_cz, double *List_rad);
|
||||
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,
|
||||
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);
|
||||
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,
|
||||
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);
|
||||
int iproc, int jproc, int kproc, int nprocx, int nprocy,
|
||||
int nprocz);
|
||||
|
||||
#endif
|
||||
|
|
108
common/UnitTest.cpp
Executable file → Normal file
108
common/UnitTest.cpp
Executable file → Normal file
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "common/UnitTest.h"
|
||||
#include "common/Utilities.h"
|
||||
#include <cstring>
|
||||
|
@ -6,23 +22,19 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#define pout std::cout
|
||||
#define printp printf
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Constructor/Destructor *
|
||||
********************************************************************/
|
||||
UnitTest::UnitTest()
|
||||
{
|
||||
UnitTest::UnitTest() {
|
||||
#ifdef USE_MPI
|
||||
comm = MPI_COMM_WORLD;
|
||||
#endif
|
||||
}
|
||||
UnitTest::~UnitTest() { reset(); }
|
||||
void UnitTest::reset()
|
||||
{
|
||||
void UnitTest::reset() {
|
||||
mutex.lock();
|
||||
// Clear the data forcing a reallocation
|
||||
std::vector<std::string>().swap(pass_messages);
|
||||
|
@ -31,36 +43,30 @@ void UnitTest::reset()
|
|||
mutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Add a pass, fail, expected failure message in a thread-safe way *
|
||||
********************************************************************/
|
||||
void UnitTest::passes( const std::string &in )
|
||||
{
|
||||
void UnitTest::passes(const std::string &in) {
|
||||
mutex.lock();
|
||||
pass_messages.push_back(in);
|
||||
mutex.unlock();
|
||||
}
|
||||
void UnitTest::failure( const std::string &in )
|
||||
{
|
||||
void UnitTest::failure(const std::string &in) {
|
||||
mutex.lock();
|
||||
fail_messages.push_back(in);
|
||||
mutex.unlock();
|
||||
}
|
||||
void UnitTest::expected_failure( const std::string &in )
|
||||
{
|
||||
void UnitTest::expected_failure(const std::string &in) {
|
||||
mutex.lock();
|
||||
expected_fail_messages.push_back(in);
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Print a global report *
|
||||
* Note: only rank 0 will print, all messages will be aggregated *
|
||||
********************************************************************/
|
||||
inline std::vector<int> UnitTest::allGather( int value ) const
|
||||
{
|
||||
inline std::vector<int> UnitTest::allGather(int value) const {
|
||||
int size = getSize();
|
||||
std::vector<int> data(size, value);
|
||||
#ifdef USE_MPI
|
||||
|
@ -69,15 +75,14 @@ inline std::vector<int> UnitTest::allGather( int value ) const
|
|||
#endif
|
||||
return data;
|
||||
}
|
||||
inline void UnitTest::barrier() const
|
||||
{
|
||||
inline void UnitTest::barrier() const {
|
||||
#ifdef USE_MPI
|
||||
if (getSize() > 1)
|
||||
MPI_Barrier(comm);
|
||||
#endif
|
||||
}
|
||||
static inline void print_messages( const std::vector<std::vector<std::string>> &messages )
|
||||
{
|
||||
static inline void
|
||||
print_messages(const std::vector<std::vector<std::string>> &messages) {
|
||||
if (messages.size() > 1) {
|
||||
for (size_t i = 0; i < messages.size(); i++) {
|
||||
if (!messages[i].empty()) {
|
||||
|
@ -91,8 +96,7 @@ static inline void print_messages( const std::vector<std::vector<std::string>> &
|
|||
pout << " " << j << std::endl;
|
||||
}
|
||||
}
|
||||
void UnitTest::report( const int level0 ) const
|
||||
{
|
||||
void UnitTest::report(const int level0) const {
|
||||
mutex.lock();
|
||||
int size = getSize();
|
||||
int rank = getRank();
|
||||
|
@ -128,7 +132,8 @@ void UnitTest::report( const int level0 ) const
|
|||
fail_messages_rank = UnitTest::gatherMessages(fail_messages, 2);
|
||||
// Get the expected_fail messages
|
||||
if ((level == 1 && N_expected_fail_tot <= 50) || level == 2)
|
||||
expected_fail_rank = UnitTest::gatherMessages( expected_fail_messages, 2 );
|
||||
expected_fail_rank =
|
||||
UnitTest::gatherMessages(expected_fail_messages, 2);
|
||||
// Print the results of all messages (only rank 0 will print)
|
||||
if (rank == 0) {
|
||||
pout << std::endl;
|
||||
|
@ -138,11 +143,14 @@ void UnitTest::report( const int level0 ) const
|
|||
// We want to print a summary
|
||||
if (size > 8) {
|
||||
// Print 1 summary for all processors
|
||||
printp( " %i tests passed (use report level 2 for more detail)\n", N_pass_tot );
|
||||
printp(" %i tests passed (use report level 2 for more "
|
||||
"detail)\n",
|
||||
N_pass_tot);
|
||||
} else {
|
||||
// Print a summary for each processor
|
||||
for (int i = 0; i < size; i++)
|
||||
printp( " %i tests passed (proc %i) (use report level 2 for more detail)\n",
|
||||
printp(" %i tests passed (proc %i) (use report level 2 "
|
||||
"for more detail)\n",
|
||||
N_pass[i], i);
|
||||
}
|
||||
} else {
|
||||
|
@ -158,11 +166,14 @@ void UnitTest::report( const int level0 ) const
|
|||
// We want to print a summary
|
||||
if (size > 8) {
|
||||
// Print 1 summary for all processors
|
||||
printp( " %i tests failed (use report level 2 for more detail)\n", N_fail_tot );
|
||||
printp(" %i tests failed (use report level 2 for more "
|
||||
"detail)\n",
|
||||
N_fail_tot);
|
||||
} else {
|
||||
// Print a summary for each processor
|
||||
for (int i = 0; i < size; i++)
|
||||
printp( " %i tests failed (proc %i) (use report level 2 for more detail)\n",
|
||||
printp(" %i tests failed (proc %i) (use report level 2 "
|
||||
"for more detail)\n",
|
||||
N_fail[i], i);
|
||||
}
|
||||
} else {
|
||||
|
@ -178,12 +189,14 @@ void UnitTest::report( const int level0 ) const
|
|||
// We want to print a summary
|
||||
if (size > 8) {
|
||||
// Print 1 summary for all processors
|
||||
printp( " %i tests expected failed (use report level 2 for more detail)\n",
|
||||
printp(" %i tests expected failed (use report level 2 for "
|
||||
"more detail)\n",
|
||||
N_expected_fail_tot);
|
||||
} else {
|
||||
// Print a summary for each processor
|
||||
for (int i = 0; i < size; i++)
|
||||
printp( " %i tests expected failed (proc %i) (use report level 2 for more "
|
||||
printp(" %i tests expected failed (proc %i) (use "
|
||||
"report level 2 for more "
|
||||
"detail)\n",
|
||||
N_expected_fail[i], i);
|
||||
}
|
||||
|
@ -197,17 +210,17 @@ void UnitTest::report( const int level0 ) const
|
|||
}
|
||||
// Add a barrier to synchronize all processors (rank 0 is much slower)
|
||||
barrier();
|
||||
Utilities::sleep_ms( 10 ); // Need a brief pause to allow any printing to finish
|
||||
Utilities::sleep_ms(
|
||||
10); // Need a brief pause to allow any printing to finish
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Gather the messages to rank 0 *
|
||||
********************************************************************/
|
||||
std::vector<std::vector<std::string>> UnitTest::gatherMessages(
|
||||
const std::vector<std::string> &local_messages, int tag ) const
|
||||
{
|
||||
std::vector<std::vector<std::string>>
|
||||
UnitTest::gatherMessages(const std::vector<std::string> &local_messages,
|
||||
int tag) const {
|
||||
const int rank = getRank();
|
||||
const int size = getSize();
|
||||
std::vector<std::vector<std::string>> messages(size);
|
||||
|
@ -226,13 +239,11 @@ std::vector<std::vector<std::string>> UnitTest::gatherMessages(
|
|||
return messages;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Pack and send the given messages *
|
||||
********************************************************************/
|
||||
void UnitTest::pack_message_stream(
|
||||
const std::vector<std::string> &messages, const int rank, const int tag ) const
|
||||
{
|
||||
void UnitTest::pack_message_stream(const std::vector<std::string> &messages,
|
||||
const int rank, const int tag) const {
|
||||
#ifdef USE_MPI
|
||||
// Get the size of the messages
|
||||
auto N_messages = (int)messages.size();
|
||||
|
@ -268,12 +279,11 @@ void UnitTest::pack_message_stream(
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Receive and unpack a message stream *
|
||||
********************************************************************/
|
||||
std::vector<std::string> UnitTest::unpack_message_stream( const int rank, const int tag ) const
|
||||
{
|
||||
std::vector<std::string> UnitTest::unpack_message_stream(const int rank,
|
||||
const int tag) const {
|
||||
#ifdef USE_MPI
|
||||
// Probe the message to get the message size
|
||||
MPI_Status status;
|
||||
|
@ -312,12 +322,10 @@ std::vector<std::string> UnitTest::unpack_message_stream( const int rank, const
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Other functions *
|
||||
********************************************************************/
|
||||
int UnitTest::getRank() const
|
||||
{
|
||||
int UnitTest::getRank() const {
|
||||
int rank = 0;
|
||||
#ifdef USE_MPI
|
||||
int flag = 0;
|
||||
|
@ -327,8 +335,7 @@ int UnitTest::getRank() const
|
|||
#endif
|
||||
return rank;
|
||||
}
|
||||
int UnitTest::getSize() const
|
||||
{
|
||||
int UnitTest::getSize() const {
|
||||
int size = 1;
|
||||
#ifdef USE_MPI
|
||||
int flag = 0;
|
||||
|
@ -338,8 +345,7 @@ int UnitTest::getSize() const
|
|||
#endif
|
||||
return size;
|
||||
}
|
||||
size_t UnitTest::NumPassGlobal() const
|
||||
{
|
||||
size_t UnitTest::NumPassGlobal() const {
|
||||
size_t num = pass_messages.size();
|
||||
#ifdef USE_MPI
|
||||
if (getSize() > 1) {
|
||||
|
@ -351,8 +357,7 @@ size_t UnitTest::NumPassGlobal() const
|
|||
#endif
|
||||
return num;
|
||||
}
|
||||
size_t UnitTest::NumFailGlobal() const
|
||||
{
|
||||
size_t UnitTest::NumFailGlobal() const {
|
||||
size_t num = fail_messages.size();
|
||||
#ifdef USE_MPI
|
||||
if (getSize() > 1) {
|
||||
|
@ -364,8 +369,7 @@ size_t UnitTest::NumFailGlobal() const
|
|||
#endif
|
||||
return num;
|
||||
}
|
||||
size_t UnitTest::NumExpectedFailGlobal() const
|
||||
{
|
||||
size_t UnitTest::NumExpectedFailGlobal() const {
|
||||
size_t num = expected_fail_messages.size();
|
||||
#ifdef USE_MPI
|
||||
if (getSize() > 1) {
|
||||
|
|
37
common/UnitTest.h
Executable file → Normal file
37
common/UnitTest.h
Executable file → Normal file
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef included_UnitTest
|
||||
#define included_UnitTest
|
||||
|
||||
|
@ -9,7 +25,6 @@
|
|||
#include "mpi.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Class UnitTest is simple utility for running unit tests.
|
||||
* It provides basic routines for tracing success or failure of tests,
|
||||
|
@ -28,8 +43,7 @@
|
|||
* \endcode
|
||||
|
||||
*/
|
||||
class UnitTest
|
||||
{
|
||||
class UnitTest {
|
||||
public:
|
||||
//! Constructor
|
||||
UnitTest();
|
||||
|
@ -53,7 +67,9 @@ public:
|
|||
virtual size_t NumFailLocal() const { return fail_messages.size(); }
|
||||
|
||||
//! Return the number of expected failed tests locally
|
||||
virtual size_t NumExpectedFailLocal() const { return expected_fail_messages.size(); }
|
||||
virtual size_t NumExpectedFailLocal() const {
|
||||
return expected_fail_messages.size();
|
||||
}
|
||||
|
||||
//! Return the number of passed tests locally
|
||||
virtual size_t NumPassGlobal() const;
|
||||
|
@ -102,19 +118,20 @@ private:
|
|||
|
||||
// Function to pack the messages into a single data stream and send to the given processor
|
||||
// Note: This function does not return until the message stream has been sent
|
||||
void pack_message_stream(
|
||||
const std::vector<std::string> &messages, const int rank, const int tag ) const;
|
||||
void pack_message_stream(const std::vector<std::string> &messages,
|
||||
const int rank, const int tag) const;
|
||||
|
||||
// Function to unpack the messages from a single data stream
|
||||
// Note: This function does not return until the message stream has been received
|
||||
std::vector<std::string> unpack_message_stream( const int rank, const int tag ) const;
|
||||
std::vector<std::string> unpack_message_stream(const int rank,
|
||||
const int tag) const;
|
||||
|
||||
// Helper functions
|
||||
inline void barrier() const;
|
||||
inline std::vector<int> allGather(int value) const;
|
||||
inline std::vector<std::vector<std::string>> gatherMessages(
|
||||
const std::vector<std::string> &local_messages, int tag ) const;
|
||||
inline std::vector<std::vector<std::string>>
|
||||
gatherMessages(const std::vector<std::string> &local_messages,
|
||||
int tag) const;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "common/Units.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
|
@ -5,19 +21,16 @@
|
|||
#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 )
|
||||
{
|
||||
: 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());
|
||||
|
@ -36,7 +49,8 @@ Units::Units( const std::string& unit )
|
|||
} else {
|
||||
d_prefix = getUnitPrefix(tmp.substr(0, 1));
|
||||
d_unit = getUnitValue(tmp.substr(1));
|
||||
if ( d_prefix == UnitPrefix::unknown || d_unit == UnitValue::unknown ) {
|
||||
if (d_prefix == UnitPrefix::unknown ||
|
||||
d_unit == UnitValue::unknown) {
|
||||
d_prefix = UnitPrefix::none;
|
||||
d_unit = getUnitValue(tmp);
|
||||
}
|
||||
|
@ -44,12 +58,10 @@ Units::Units( const std::string& unit )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Get prefix *
|
||||
********************************************************************/
|
||||
Units::UnitPrefix Units::getUnitPrefix( const std::string& str ) noexcept
|
||||
{
|
||||
Units::UnitPrefix Units::getUnitPrefix(const std::string &str) noexcept {
|
||||
Units::UnitPrefix value = UnitPrefix::unknown;
|
||||
if (str.empty()) {
|
||||
value = UnitPrefix::none;
|
||||
|
@ -97,12 +109,10 @@ Units::UnitPrefix Units::getUnitPrefix( const std::string& str ) noexcept
|
|||
return value;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Get unit value *
|
||||
********************************************************************/
|
||||
Units::UnitValue Units::getUnitValue( const std::string& str ) noexcept
|
||||
{
|
||||
Units::UnitValue Units::getUnitValue(const std::string &str) noexcept {
|
||||
Units::UnitValue value = UnitValue::unknown;
|
||||
if (str == "meter" || str == "m") {
|
||||
value = UnitValue::meter;
|
||||
|
@ -126,12 +136,10 @@ Units::UnitValue Units::getUnitValue( const std::string& str ) noexcept
|
|||
return value;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Get unit type *
|
||||
********************************************************************/
|
||||
Units::UnitType Units::getUnitType( UnitValue u ) noexcept
|
||||
{
|
||||
Units::UnitType Units::getUnitType(UnitValue u) noexcept {
|
||||
switch (u) {
|
||||
case UnitValue::meter:
|
||||
return UnitType::length;
|
||||
|
@ -154,12 +162,10 @@ Units::UnitType Units::getUnitType( UnitValue u ) noexcept
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Convert to another unit system *
|
||||
********************************************************************/
|
||||
double Units::convert( const Units& rhs ) const noexcept
|
||||
{
|
||||
double Units::convert(const Units &rhs) const noexcept {
|
||||
if (this->operator==(rhs))
|
||||
return 1;
|
||||
// Convert the prefix
|
||||
|
@ -182,17 +188,14 @@ double Units::convert( const Units& rhs ) const noexcept
|
|||
return cp * cu;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Write a string for the units *
|
||||
********************************************************************/
|
||||
std::string Units::str() const
|
||||
{
|
||||
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> Units::str(UnitPrefix p) noexcept {
|
||||
std::array<char, 3> str;
|
||||
str[0] = d_prefixSymbol[static_cast<int8_t>(p)];
|
||||
str[1] = 0;
|
||||
|
@ -201,8 +204,7 @@ std::array<char, 3> Units::str( UnitPrefix p ) noexcept
|
|||
str[1] = 'a';
|
||||
return str;
|
||||
}
|
||||
std::string Units::str( UnitValue u )
|
||||
{
|
||||
std::string Units::str(UnitValue u) {
|
||||
if (u == UnitValue::meter) {
|
||||
return "m";
|
||||
} else if (u == UnitValue::gram) {
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef included_Units
|
||||
#define included_Units
|
||||
|
||||
|
@ -8,10 +24,8 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
//! Unit system class
|
||||
class Units final
|
||||
{
|
||||
class Units final {
|
||||
public:
|
||||
//! Enum to hold prefix
|
||||
enum class UnitPrefix : int8_t {
|
||||
|
@ -65,7 +79,6 @@ public:
|
|||
unknown
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
Units();
|
||||
|
@ -98,8 +111,7 @@ public:
|
|||
double convert(const Units &) const noexcept;
|
||||
|
||||
//! Convert a prefix to a scalar
|
||||
static inline double convert( UnitPrefix x ) noexcept
|
||||
{
|
||||
static inline double convert(UnitPrefix x) noexcept {
|
||||
return d_pow10[static_cast<int8_t>(x)];
|
||||
}
|
||||
|
||||
|
@ -113,27 +125,28 @@ public:
|
|||
static std::string str(UnitValue);
|
||||
|
||||
//! Operator ==
|
||||
inline bool operator==( const Units& rhs ) const noexcept
|
||||
{
|
||||
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
|
||||
{
|
||||
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; }
|
||||
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 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";
|
||||
};
|
||||
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "common/Utilities.h"
|
||||
#include "StackTrace/StackTrace.h"
|
||||
#include "StackTrace/ErrorHandlers.h"
|
||||
|
@ -15,7 +31,6 @@
|
|||
#include <math.h>
|
||||
#include <mutex>
|
||||
|
||||
|
||||
// OS specific includes / definitions
|
||||
// clang-format off
|
||||
#if defined( WIN32 ) || defined( _WIN32 ) || defined( WIN64 ) || defined( _WIN64 )
|
||||
|
@ -29,16 +44,13 @@
|
|||
#endif
|
||||
// clang-format on
|
||||
|
||||
|
||||
// Mutex for Utility functions
|
||||
static std::mutex Utilities_mutex;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Function to perform the default startup/shutdown sequences *
|
||||
****************************************************************************/
|
||||
void Utilities::startup( int argc, char **argv, bool multiple )
|
||||
{
|
||||
void Utilities::startup(int argc, char **argv, bool multiple) {
|
||||
NULL_USE(argc);
|
||||
NULL_USE(argv);
|
||||
// Disable OpenMP
|
||||
|
@ -53,7 +65,9 @@ void Utilities::startup( int argc, char **argv, bool multiple )
|
|||
int rank;
|
||||
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
|
||||
if (rank == 0)
|
||||
std::cerr << "Warning: Failed to start MPI with necessary thread support, thread support will be disabled" << std::endl;
|
||||
std::cerr << "Warning: Failed to start MPI with necessary "
|
||||
"thread support, thread support will be disabled"
|
||||
<< std::endl;
|
||||
}
|
||||
StackTrace::globalCallStackInitialize(MPI_COMM_WORLD);
|
||||
} else {
|
||||
|
@ -64,8 +78,7 @@ void Utilities::startup( int argc, char **argv, bool multiple )
|
|||
Utilities::setAbortBehavior(true, 3);
|
||||
Utilities::setErrorHandlers();
|
||||
}
|
||||
void Utilities::shutdown()
|
||||
{
|
||||
void Utilities::shutdown() {
|
||||
// Clear the error handlers
|
||||
Utilities::clearErrorHandlers();
|
||||
StackTrace::clearSignals();
|
||||
|
@ -85,12 +98,10 @@ void Utilities::shutdown()
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Function to set an environemental variable *
|
||||
****************************************************************************/
|
||||
void Utilities::setenv( const std::string &name, const std::string &value )
|
||||
{
|
||||
void Utilities::setenv(const std::string &name, const std::string &value) {
|
||||
Utilities_mutex.lock();
|
||||
#if defined(USE_LINUX) || defined(USE_MAC)
|
||||
bool pass = false;
|
||||
|
@ -107,15 +118,15 @@ void Utilities::setenv( const std::string &name, const std::string &value )
|
|||
if (!pass) {
|
||||
char msg[1024];
|
||||
if (!value.empty())
|
||||
sprintf(
|
||||
msg, "Error setting enviornmental variable: %s=%s\n", name.data(), value.data() );
|
||||
sprintf(msg, "Error setting enviornmental variable: %s=%s\n",
|
||||
name.data(), value.data());
|
||||
else
|
||||
sprintf( msg, "Error clearing enviornmental variable: %s\n", name.data() );
|
||||
sprintf(msg, "Error clearing enviornmental variable: %s\n",
|
||||
name.data());
|
||||
ERROR(msg);
|
||||
}
|
||||
}
|
||||
std::string Utilities::getenv( const std::string &name )
|
||||
{
|
||||
std::string Utilities::getenv(const std::string &name) {
|
||||
std::string var;
|
||||
Utilities_mutex.lock();
|
||||
auto tmp = std::getenv(name.data());
|
||||
|
@ -125,12 +136,10 @@ std::string Utilities::getenv( const std::string &name )
|
|||
return var;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Factor a number into it's prime factors *
|
||||
****************************************************************************/
|
||||
std::vector<int> Utilities::factor(size_t number)
|
||||
{
|
||||
std::vector<int> Utilities::factor(size_t number) {
|
||||
if (number <= 3)
|
||||
return std::vector<int>(1, (int)number);
|
||||
size_t i, n, n_max;
|
||||
|
@ -138,7 +147,8 @@ std::vector<int> Utilities::factor(size_t number)
|
|||
// Compute the maximum number of factors
|
||||
int N_primes_max = 1;
|
||||
n = number;
|
||||
while (n >>= 1) ++N_primes_max;
|
||||
while (n >>= 1)
|
||||
++N_primes_max;
|
||||
// Initialize n, factors
|
||||
n = number;
|
||||
std::vector<int> factors;
|
||||
|
@ -177,14 +187,7 @@ std::vector<int> Utilities::factor(size_t number)
|
|||
return factors;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Dummy function to prevent compiler from optimizing away variable *
|
||||
****************************************************************************/
|
||||
void Utilities::nullUse( void* data )
|
||||
{
|
||||
NULL_USE(data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Utilities::nullUse(void *data) { NULL_USE(data); }
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef included_Utilities
|
||||
#define included_Utilities
|
||||
|
||||
|
@ -6,10 +22,8 @@
|
|||
|
||||
#include "StackTrace/Utilities.h"
|
||||
|
||||
|
||||
namespace Utilities {
|
||||
|
||||
|
||||
// Functions inherited from StackTrace::Utilities
|
||||
using StackTrace::Utilities::abort;
|
||||
using StackTrace::Utilities::cause_segfault;
|
||||
|
@ -19,11 +33,10 @@ using StackTrace::Utilities::getMemoryUsage;
|
|||
using StackTrace::Utilities::getSystemMemory;
|
||||
using StackTrace::Utilities::setAbortBehavior;
|
||||
using StackTrace::Utilities::setErrorHandlers;
|
||||
using StackTrace::Utilities::tick;
|
||||
using StackTrace::Utilities::time;
|
||||
using StackTrace::Utilities::sleep_ms;
|
||||
using StackTrace::Utilities::sleep_s;
|
||||
|
||||
using StackTrace::Utilities::tick;
|
||||
using StackTrace::Utilities::time;
|
||||
|
||||
/*!
|
||||
* \brief Start MPI, error handlers
|
||||
|
@ -40,7 +53,6 @@ void startup( int argc, char **argv, bool multiple=true );
|
|||
*/
|
||||
void shutdown();
|
||||
|
||||
|
||||
/*!
|
||||
* Get an environmental variable
|
||||
* @param name The name of the environmental variable
|
||||
|
@ -48,7 +60,6 @@ void shutdown();
|
|||
*/
|
||||
std::string getenv(const std::string &name);
|
||||
|
||||
|
||||
/*!
|
||||
* Set an environmental variable
|
||||
* @param name The name of the environmental variable
|
||||
|
@ -56,28 +67,21 @@ std::string getenv( const std::string &name );
|
|||
*/
|
||||
void setenv(const std::string &name, const std::string &value);
|
||||
|
||||
|
||||
//! std::string version of sprintf
|
||||
inline std::string stringf(const char *format, ...);
|
||||
|
||||
|
||||
//! Factor a number into it's prime factors
|
||||
std::vector<int> factor(size_t number);
|
||||
|
||||
|
||||
//! Null use function
|
||||
void nullUse(void *);
|
||||
|
||||
|
||||
} // namespace Utilities
|
||||
|
||||
|
||||
#include "common/UtilityMacros.h"
|
||||
|
||||
|
||||
// stringf
|
||||
inline std::string Utilities::stringf( const char *format, ... )
|
||||
{
|
||||
inline std::string Utilities::stringf(const char *format, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
char tmp[4096];
|
||||
|
@ -86,5 +90,4 @@ inline std::string Utilities::stringf( const char *format, ... )
|
|||
return std::string(tmp);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,21 +1,16 @@
|
|||
#ifndef included_Utilities_hpp
|
||||
#define included_Utilities_hpp
|
||||
|
||||
|
||||
#include "Utilities.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace Utilities {
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* templated quicksort routines *
|
||||
************************************************************************/
|
||||
template<class T>
|
||||
void quicksort( std::vector<T> &x )
|
||||
{
|
||||
template <class T> void quicksort(std::vector<T> &x) {
|
||||
if (x.size() <= 1u)
|
||||
return;
|
||||
T *arr = &x[0];
|
||||
|
@ -45,11 +40,13 @@ void quicksort( std::vector<T> &x )
|
|||
}
|
||||
if (jstack == 0)
|
||||
return;
|
||||
ir = istack[jstack]; // Pop stack and begin a new round of partitioning.
|
||||
ir = istack
|
||||
[jstack]; // Pop stack and begin a new round of partitioning.
|
||||
l = istack[jstack - 1];
|
||||
jstack -= 2;
|
||||
} else {
|
||||
k = ( l + ir ) / 2; // Choose median of left, center and right elements as partitioning
|
||||
k = (l + ir) /
|
||||
2; // Choose median of left, center and right elements as partitioning
|
||||
// element a. Also rearrange so that a(l) < a(l+1) < a(ir).
|
||||
tmp_a = arr[k];
|
||||
arr[k] = arr[l + 1];
|
||||
|
@ -100,8 +97,7 @@ void quicksort( std::vector<T> &x )
|
|||
}
|
||||
}
|
||||
template <class T1, class T2>
|
||||
void quicksort( std::vector<T1> &x, std::vector<T2> &y )
|
||||
{
|
||||
void quicksort(std::vector<T1> &x, std::vector<T2> &y) {
|
||||
if (x.size() <= 1u)
|
||||
return;
|
||||
T1 *arr = &x[0];
|
||||
|
@ -137,11 +133,13 @@ void quicksort( std::vector<T1> &x, std::vector<T2> &y )
|
|||
}
|
||||
if (jstack == 0)
|
||||
return;
|
||||
ir = istack[jstack]; // Pop stack and begin a new round of partitioning.
|
||||
ir = istack
|
||||
[jstack]; // Pop stack and begin a new round of partitioning.
|
||||
l = istack[jstack - 1];
|
||||
jstack -= 2;
|
||||
} else {
|
||||
k = ( l + ir ) / 2; // Choose median of left, center and right elements as partitioning
|
||||
k = (l + ir) /
|
||||
2; // Choose median of left, center and right elements as partitioning
|
||||
// element a. Also rearrange so that a(l) ? a(l+1) ? a(ir).
|
||||
tmp_a = arr[k];
|
||||
arr[k] = arr[l + 1];
|
||||
|
@ -209,9 +207,7 @@ void quicksort( std::vector<T1> &x, std::vector<T2> &y )
|
|||
}
|
||||
}
|
||||
}
|
||||
template<class T>
|
||||
void unique( std::vector<T> &x )
|
||||
{
|
||||
template <class T> void unique(std::vector<T> &x) {
|
||||
if (x.size() <= 1)
|
||||
return;
|
||||
// First perform a quicksort
|
||||
|
@ -228,7 +224,6 @@ void unique( std::vector<T> &x )
|
|||
x.resize(pos);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
} // namespace Utilities
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// This file contains useful macros including ERROR, WARNING, INSIST, ASSERT, etc.
|
||||
#ifndef included_UtilityMacros
|
||||
#define included_UtilityMacros
|
||||
|
@ -8,7 +24,6 @@
|
|||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
/*! \defgroup Macros Set of utility macro functions
|
||||
* \details These functions are a list of C++ macros that are used
|
||||
* for common operations, including checking for errors.
|
||||
|
@ -16,7 +31,6 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/*! \def NULL_STATEMENT
|
||||
* \brief A null statement
|
||||
* \details A statement that does nothing, for insure++ make it something
|
||||
|
@ -34,7 +48,6 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*! \def NULL_USE(variable)
|
||||
* \brief A null use of a variable
|
||||
* \details A null use of a variable, use to avoid GNU compiler warnings about unused variables.
|
||||
|
@ -50,7 +63,6 @@
|
|||
} while (0)
|
||||
#endif
|
||||
|
||||
|
||||
/*! \def ERROR(MSG)
|
||||
* \brief Throw error
|
||||
* \details Throw an error exception from within any C++ source code. The
|
||||
|
@ -63,7 +75,6 @@
|
|||
::Utilities::abort(MSG, __FILE__, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*! \def WARNING(MSG)
|
||||
* \brief Print a warning
|
||||
* \details Print a warning without exit. Print file and line number of the warning.
|
||||
|
@ -77,7 +88,6 @@
|
|||
tboxos.str().c_str(), __FILE__, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*! \def ASSERT(EXP)
|
||||
* \brief Assert error
|
||||
* \details Throw an error exception from within any C++ source code if the
|
||||
|
@ -95,7 +105,6 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*! \def INSIST(EXP,MSG)
|
||||
* \brief Insist error
|
||||
* \details Throw an error exception from within any C++ source code if the
|
||||
|
@ -105,7 +114,8 @@
|
|||
* \param EXP Expression to evaluate
|
||||
* \param MSG Debug message to print
|
||||
*/
|
||||
#define INSIST(EXP,MSG) do { \
|
||||
#define INSIST(EXP, MSG) \
|
||||
do { \
|
||||
if (!(EXP)) { \
|
||||
std::stringstream tboxos; \
|
||||
tboxos << "Failed insist: " << #EXP << std::endl; \
|
||||
|
@ -114,7 +124,6 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/**
|
||||
* Macro for use when assertions are to be included
|
||||
* only when debugging.
|
||||
|
@ -132,7 +141,6 @@
|
|||
#define CHECK_ASSERT(EXP)
|
||||
#endif
|
||||
|
||||
|
||||
/*! \def DISABLE_WARNINGS
|
||||
* \brief Reenable warnings
|
||||
* \details This will re-enable warnings after a call to DIASABLE_WARNINGS
|
||||
|
@ -173,9 +181,6 @@
|
|||
#endif
|
||||
// clang-format on
|
||||
|
||||
|
||||
|
||||
/*! @} */
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,8 +3,8 @@ This class implements support for halo widths larger than 1
|
|||
*/
|
||||
#include "common/WideHalo.h"
|
||||
|
||||
ScaLBLWideHalo_Communicator::ScaLBLWideHalo_Communicator(std::shared_ptr <Domain> Dm, int width)
|
||||
{
|
||||
ScaLBLWideHalo_Communicator::ScaLBLWideHalo_Communicator(
|
||||
std::shared_ptr<Domain> Dm, int width) {
|
||||
//......................................................................................
|
||||
Lock = false; // unlock the communicator
|
||||
//......................................................................................
|
||||
|
@ -62,123 +62,283 @@ ScaLBLWideHalo_Communicator::ScaLBLWideHalo_Communicator(std::shared_ptr <Domain
|
|||
|
||||
/* Fill in communications patterns for the lists */
|
||||
/* Send lists */
|
||||
sendCount_x =getHaloBlock(width,2*width,width,Nyh-width,width,Nzh-width,dvcSendList_x);
|
||||
sendCount_X =getHaloBlock(Nxh-2*width,Nxh-width,width,Nyh-width,width,Nzh-width,dvcSendList_X);
|
||||
sendCount_y =getHaloBlock(width,Nxh-width,width,2*width,width,Nzh-width,dvcSendList_y);
|
||||
sendCount_Y =getHaloBlock(width,Nxh-width,Nyh-2*width,Nyh-width,width,Nzh-width,dvcSendList_Y);
|
||||
sendCount_z =getHaloBlock(width,Nxh-width,width,Nyh-width,width,2*width,dvcSendList_z);
|
||||
sendCount_Z =getHaloBlock(width,Nxh-width,width,Nyh-width,Nzh-2*width,Nzh-width,dvcSendList_Z);
|
||||
sendCount_x = getHaloBlock(width, 2 * width, width, Nyh - width, width,
|
||||
Nzh - width, dvcSendList_x);
|
||||
sendCount_X = getHaloBlock(Nxh - 2 * width, Nxh - width, width, Nyh - width,
|
||||
width, Nzh - width, dvcSendList_X);
|
||||
sendCount_y = getHaloBlock(width, Nxh - width, width, 2 * width, width,
|
||||
Nzh - width, dvcSendList_y);
|
||||
sendCount_Y = getHaloBlock(width, Nxh - width, Nyh - 2 * width, Nyh - width,
|
||||
width, Nzh - width, dvcSendList_Y);
|
||||
sendCount_z = getHaloBlock(width, Nxh - width, width, Nyh - width, width,
|
||||
2 * width, dvcSendList_z);
|
||||
sendCount_Z = getHaloBlock(width, Nxh - width, width, Nyh - width,
|
||||
Nzh - 2 * width, Nzh - width, dvcSendList_Z);
|
||||
// xy
|
||||
sendCount_xy =getHaloBlock(width,2*width,width,2*width,width,Nzh-width,dvcSendList_xy);
|
||||
sendCount_xY =getHaloBlock(width,2*width,Nyh-2*width,Nyh-width,width,Nzh-width,dvcSendList_xY);
|
||||
sendCount_Xy =getHaloBlock(Nxh-2*width,Nxh-width,width,2*width,width,Nzh-width,dvcSendList_Xy);
|
||||
sendCount_XY =getHaloBlock(Nxh-2*width,Nxh-width,Nyh-2*width,Nyh-width,width,Nzh-width,dvcSendList_XY);
|
||||
sendCount_xy = getHaloBlock(width, 2 * width, width, 2 * width, width,
|
||||
Nzh - width, dvcSendList_xy);
|
||||
sendCount_xY = getHaloBlock(width, 2 * width, Nyh - 2 * width, Nyh - width,
|
||||
width, Nzh - width, dvcSendList_xY);
|
||||
sendCount_Xy = getHaloBlock(Nxh - 2 * width, Nxh - width, width, 2 * width,
|
||||
width, Nzh - width, dvcSendList_Xy);
|
||||
sendCount_XY =
|
||||
getHaloBlock(Nxh - 2 * width, Nxh - width, Nyh - 2 * width, Nyh - width,
|
||||
width, Nzh - width, dvcSendList_XY);
|
||||
// xz
|
||||
sendCount_xz =getHaloBlock(width,2*width,width,Nyh-width,width,2*width,dvcSendList_xz);
|
||||
sendCount_xZ =getHaloBlock(width,2*width,width,Nyh-width,Nzh-2*width,Nzh-width,dvcSendList_xZ);
|
||||
sendCount_Xz =getHaloBlock(Nxh-2*width,Nxh-width,width,Nyh-width,width,2*width,dvcSendList_Xz);
|
||||
sendCount_XZ =getHaloBlock(Nxh-2*width,Nxh-width,width,Nyh-width,Nzh-2*width,Nzh-width,dvcSendList_XZ);
|
||||
sendCount_xz = getHaloBlock(width, 2 * width, width, Nyh - width, width,
|
||||
2 * width, dvcSendList_xz);
|
||||
sendCount_xZ = getHaloBlock(width, 2 * width, width, Nyh - width,
|
||||
Nzh - 2 * width, Nzh - width, dvcSendList_xZ);
|
||||
sendCount_Xz = getHaloBlock(Nxh - 2 * width, Nxh - width, width,
|
||||
Nyh - width, width, 2 * width, dvcSendList_Xz);
|
||||
sendCount_XZ =
|
||||
getHaloBlock(Nxh - 2 * width, Nxh - width, width, Nyh - width,
|
||||
Nzh - 2 * width, Nzh - width, dvcSendList_XZ);
|
||||
// yz
|
||||
sendCount_yz =getHaloBlock(width,Nxh-width,width,2*width,width,2*width,dvcSendList_yz);
|
||||
sendCount_yZ =getHaloBlock(width,Nxh-width,width,2*width,Nzh-2*width,Nzh-width,dvcSendList_yZ);
|
||||
sendCount_Yz =getHaloBlock(width,Nxh-width,Nyh-2*width,Nyh-width,width,2*width,dvcSendList_Yz);
|
||||
sendCount_YZ =getHaloBlock(width,Nxh-width,Nyh-2*width,Nyh-width,Nzh-2*width,Nzh-width,dvcSendList_YZ);
|
||||
sendCount_yz = getHaloBlock(width, Nxh - width, width, 2 * width, width,
|
||||
2 * width, dvcSendList_yz);
|
||||
sendCount_yZ = getHaloBlock(width, Nxh - width, width, 2 * width,
|
||||
Nzh - 2 * width, Nzh - width, dvcSendList_yZ);
|
||||
sendCount_Yz = getHaloBlock(width, Nxh - width, Nyh - 2 * width,
|
||||
Nyh - width, width, 2 * width, dvcSendList_Yz);
|
||||
sendCount_YZ =
|
||||
getHaloBlock(width, Nxh - width, Nyh - 2 * width, Nyh - width,
|
||||
Nzh - 2 * width, Nzh - width, dvcSendList_YZ);
|
||||
// xyz
|
||||
sendCount_xyz =getHaloBlock(width,2*width,width,2*width,width,2*width,dvcSendList_xyz);
|
||||
sendCount_xyZ =getHaloBlock(width,2*width,width,2*width,Nzh-2*width,Nzh-width,dvcSendList_xyZ);
|
||||
sendCount_xYz =getHaloBlock(width,2*width,Nyh-2*width,Nyh-width,width,2*width,dvcSendList_xYz);
|
||||
sendCount_xYZ =getHaloBlock(width,2*width,Nyh-2*width,Nyh-width,Nzh-2*width,Nzh-width,dvcSendList_xYZ);
|
||||
sendCount_Xyz =getHaloBlock(Nxh-2*width,Nxh-width,width,2*width,width,2*width,dvcSendList_Xyz);
|
||||
sendCount_XyZ =getHaloBlock(Nxh-2*width,Nxh-width,width,2*width,Nzh-2*width,Nzh-width,dvcSendList_XyZ);
|
||||
sendCount_XYz =getHaloBlock(Nxh-2*width,Nxh-width,Nyh-2*width,Nyh-width,width,2*width,dvcSendList_XYz);
|
||||
sendCount_XYZ =getHaloBlock(Nxh-2*width,Nxh-width,Nyh-2*width,Nyh-width,Nzh-2*width,Nzh-width,dvcSendList_XYZ);
|
||||
sendCount_xyz = getHaloBlock(width, 2 * width, width, 2 * width, width,
|
||||
2 * width, dvcSendList_xyz);
|
||||
sendCount_xyZ = getHaloBlock(width, 2 * width, width, 2 * width,
|
||||
Nzh - 2 * width, Nzh - width, dvcSendList_xyZ);
|
||||
sendCount_xYz = getHaloBlock(width, 2 * width, Nyh - 2 * width, Nyh - width,
|
||||
width, 2 * width, dvcSendList_xYz);
|
||||
sendCount_xYZ = getHaloBlock(width, 2 * width, Nyh - 2 * width, Nyh - width,
|
||||
Nzh - 2 * width, Nzh - width, dvcSendList_xYZ);
|
||||
sendCount_Xyz = getHaloBlock(Nxh - 2 * width, Nxh - width, width, 2 * width,
|
||||
width, 2 * width, dvcSendList_Xyz);
|
||||
sendCount_XyZ = getHaloBlock(Nxh - 2 * width, Nxh - width, width, 2 * width,
|
||||
Nzh - 2 * width, Nzh - width, dvcSendList_XyZ);
|
||||
sendCount_XYz =
|
||||
getHaloBlock(Nxh - 2 * width, Nxh - width, Nyh - 2 * width, Nyh - width,
|
||||
width, 2 * width, dvcSendList_XYz);
|
||||
sendCount_XYZ =
|
||||
getHaloBlock(Nxh - 2 * width, Nxh - width, Nyh - 2 * width, Nyh - width,
|
||||
Nzh - 2 * width, Nzh - width, dvcSendList_XYZ);
|
||||
|
||||
/* Recv lists */
|
||||
recvCount_x =getHaloBlock(0,width,width,Nyh-width,width,Nzh-width,dvcRecvList_x);
|
||||
recvCount_X =getHaloBlock(Nxh-width,Nxh,width,Nyh-width,width,Nzh-width,dvcRecvList_X);
|
||||
recvCount_y =getHaloBlock(width,Nxh-width,0,width,width,Nzh-width,dvcRecvList_y);
|
||||
recvCount_Y =getHaloBlock(width,Nxh-width,Nyh-width,Nyh,width,Nzh-width,dvcRecvList_Y);
|
||||
recvCount_z =getHaloBlock(width,Nxh-width,width,Nyh-width,0,width,dvcRecvList_z);
|
||||
recvCount_Z =getHaloBlock(width,Nxh-width,width,Nyh-width,Nzh-width,Nzh,dvcRecvList_Z);
|
||||
recvCount_x = getHaloBlock(0, width, width, Nyh - width, width, Nzh - width,
|
||||
dvcRecvList_x);
|
||||
recvCount_X = getHaloBlock(Nxh - width, Nxh, width, Nyh - width, width,
|
||||
Nzh - width, dvcRecvList_X);
|
||||
recvCount_y = getHaloBlock(width, Nxh - width, 0, width, width, Nzh - width,
|
||||
dvcRecvList_y);
|
||||
recvCount_Y = getHaloBlock(width, Nxh - width, Nyh - width, Nyh, width,
|
||||
Nzh - width, dvcRecvList_Y);
|
||||
recvCount_z = getHaloBlock(width, Nxh - width, width, Nyh - width, 0, width,
|
||||
dvcRecvList_z);
|
||||
recvCount_Z = getHaloBlock(width, Nxh - width, width, Nyh - width,
|
||||
Nzh - width, Nzh, dvcRecvList_Z);
|
||||
//xy
|
||||
recvCount_xy =getHaloBlock(0,width,0,width,width,Nzh-width,dvcRecvList_xy);
|
||||
recvCount_xY =getHaloBlock(0,width,Nyh-width,Nyh,width,Nzh-width,dvcRecvList_xY);
|
||||
recvCount_Xy =getHaloBlock(Nxh-width,Nxh,0,width,width,Nzh-width,dvcRecvList_Xy);
|
||||
recvCount_XY =getHaloBlock(Nxh-width,Nxh,Nyh-width,Nyh,width,Nzh-width,dvcRecvList_XY);
|
||||
recvCount_xy =
|
||||
getHaloBlock(0, width, 0, width, width, Nzh - width, dvcRecvList_xy);
|
||||
recvCount_xY = getHaloBlock(0, width, Nyh - width, Nyh, width, Nzh - width,
|
||||
dvcRecvList_xY);
|
||||
recvCount_Xy = getHaloBlock(Nxh - width, Nxh, 0, width, width, Nzh - width,
|
||||
dvcRecvList_Xy);
|
||||
recvCount_XY = getHaloBlock(Nxh - width, Nxh, Nyh - width, Nyh, width,
|
||||
Nzh - width, dvcRecvList_XY);
|
||||
//xz
|
||||
recvCount_xz =getHaloBlock(0,width,width,Nyh-width,0,width,dvcRecvList_xz);
|
||||
recvCount_xZ =getHaloBlock(0,width,width,Nyh-width,Nzh-width,Nzh,dvcRecvList_xZ);
|
||||
recvCount_Xz =getHaloBlock(Nxh-width,Nxh,width,Nyh-width,0,width,dvcRecvList_Xz);
|
||||
recvCount_XZ =getHaloBlock(Nxh-width,Nxh,width,Nyh-width,Nzh-width,Nzh,dvcRecvList_XZ);
|
||||
recvCount_xz =
|
||||
getHaloBlock(0, width, width, Nyh - width, 0, width, dvcRecvList_xz);
|
||||
recvCount_xZ = getHaloBlock(0, width, width, Nyh - width, Nzh - width, Nzh,
|
||||
dvcRecvList_xZ);
|
||||
recvCount_Xz = getHaloBlock(Nxh - width, Nxh, width, Nyh - width, 0, width,
|
||||
dvcRecvList_Xz);
|
||||
recvCount_XZ = getHaloBlock(Nxh - width, Nxh, width, Nyh - width,
|
||||
Nzh - width, Nzh, dvcRecvList_XZ);
|
||||
//yz
|
||||
recvCount_yz =getHaloBlock(width,Nxh-width,0,width,0,width,dvcRecvList_yz);
|
||||
recvCount_yZ =getHaloBlock(width,Nxh-width,0,width,Nzh-width,Nzh,dvcRecvList_yZ);
|
||||
recvCount_Yz =getHaloBlock(width,Nxh-width,Nyh-width,Nyh,0,width,dvcRecvList_Yz);
|
||||
recvCount_YZ =getHaloBlock(width,Nxh-width,Nyh-width,Nyh,Nzh-width,Nzh,dvcRecvList_YZ);
|
||||
recvCount_yz =
|
||||
getHaloBlock(width, Nxh - width, 0, width, 0, width, dvcRecvList_yz);
|
||||
recvCount_yZ = getHaloBlock(width, Nxh - width, 0, width, Nzh - width, Nzh,
|
||||
dvcRecvList_yZ);
|
||||
recvCount_Yz = getHaloBlock(width, Nxh - width, Nyh - width, Nyh, 0, width,
|
||||
dvcRecvList_Yz);
|
||||
recvCount_YZ = getHaloBlock(width, Nxh - width, Nyh - width, Nyh,
|
||||
Nzh - width, Nzh, dvcRecvList_YZ);
|
||||
//xyz
|
||||
recvCount_xyz = getHaloBlock(0, width, 0, width, 0, width, dvcRecvList_xyz);
|
||||
recvCount_xyZ =getHaloBlock(0,width,0,width,Nzh-width,Nzh,dvcRecvList_xyZ);
|
||||
recvCount_xYz =getHaloBlock(0,width,Nyh-width,Nyh,0,width,dvcRecvList_xYz);
|
||||
recvCount_xYZ =getHaloBlock(0,width,Nyh-width,Nyh,Nzh-width,Nzh,dvcRecvList_xYZ);
|
||||
recvCount_Xyz =getHaloBlock(Nxh-width,Nxh,0,width,0,width,dvcRecvList_Xyz);
|
||||
recvCount_XyZ =getHaloBlock(Nxh-width,Nxh,0,width,Nzh-width,Nzh,dvcRecvList_XyZ);
|
||||
recvCount_XYz =getHaloBlock(Nxh-width,Nxh,Nyh-width,Nyh,0,width,dvcRecvList_XYz);
|
||||
recvCount_XYZ =getHaloBlock(Nxh-width,Nxh,Nyh-width,Nyh,Nzh-width,Nzh,dvcRecvList_XYZ);
|
||||
recvCount_xyZ =
|
||||
getHaloBlock(0, width, 0, width, Nzh - width, Nzh, dvcRecvList_xyZ);
|
||||
recvCount_xYz =
|
||||
getHaloBlock(0, width, Nyh - width, Nyh, 0, width, dvcRecvList_xYz);
|
||||
recvCount_xYZ = getHaloBlock(0, width, Nyh - width, Nyh, Nzh - width, Nzh,
|
||||
dvcRecvList_xYZ);
|
||||
recvCount_Xyz =
|
||||
getHaloBlock(Nxh - width, Nxh, 0, width, 0, width, dvcRecvList_Xyz);
|
||||
recvCount_XyZ = getHaloBlock(Nxh - width, Nxh, 0, width, Nzh - width, Nzh,
|
||||
dvcRecvList_XyZ);
|
||||
recvCount_XYz = getHaloBlock(Nxh - width, Nxh, Nyh - width, Nyh, 0, width,
|
||||
dvcRecvList_XYz);
|
||||
recvCount_XYZ = getHaloBlock(Nxh - width, Nxh, Nyh - width, Nyh,
|
||||
Nzh - width, Nzh, dvcRecvList_XYZ);
|
||||
|
||||
//......................................................................................
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_x, sendCount_x*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_X, sendCount_X*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_y, sendCount_y*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_Y, sendCount_Y*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_z, sendCount_z*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_Z, sendCount_Z*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xy, sendCount_xy*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xY, sendCount_xY*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_Xy, sendCount_Xy*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_XY, sendCount_XY*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xz, sendCount_xz*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xZ, sendCount_xZ*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_Xz, sendCount_Xz*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_XZ, sendCount_XZ*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_yz, sendCount_yz*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_yZ, sendCount_yZ*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_Yz, sendCount_Yz*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_YZ, sendCount_YZ*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xyz, sendCount_xyz*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xYz, sendCount_xYz*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_Xyz, sendCount_Xyz*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_XYz, sendCount_XYz*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xyZ, sendCount_xyZ*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xYZ, sendCount_xYZ*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_XyZ, sendCount_XyZ*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &sendbuf_XYZ, sendCount_XYZ*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_x,
|
||||
sendCount_x *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_X,
|
||||
sendCount_X *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_y,
|
||||
sendCount_y *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_Y,
|
||||
sendCount_Y *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_z,
|
||||
sendCount_z *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_Z,
|
||||
sendCount_Z *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_xy,
|
||||
sendCount_xy *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_xY,
|
||||
sendCount_xY *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_Xy,
|
||||
sendCount_Xy *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_XY,
|
||||
sendCount_XY *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_xz,
|
||||
sendCount_xz *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_xZ,
|
||||
sendCount_xZ *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_Xz,
|
||||
sendCount_Xz *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_XZ,
|
||||
sendCount_XZ *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_yz,
|
||||
sendCount_yz *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_yZ,
|
||||
sendCount_yZ *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_Yz,
|
||||
sendCount_Yz *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_YZ,
|
||||
sendCount_YZ *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_xyz,
|
||||
sendCount_xyz *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_xYz,
|
||||
sendCount_xYz *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_Xyz,
|
||||
sendCount_Xyz *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_XYz,
|
||||
sendCount_XYz *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_xyZ,
|
||||
sendCount_xyZ *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_xYZ,
|
||||
sendCount_xYZ *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_XyZ,
|
||||
sendCount_XyZ *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&sendbuf_XYZ,
|
||||
sendCount_XYZ *
|
||||
sizeof(double)); // Allocate device memory
|
||||
//......................................................................................
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_x, recvCount_x*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_X, recvCount_X*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_y, recvCount_y*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_Y, recvCount_Y*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_z, recvCount_z*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_Z, recvCount_Z*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xy, recvCount_xy*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xY, recvCount_xY*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_Xy, recvCount_Xy*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_XY, recvCount_XY*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xz, recvCount_xz*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xZ, recvCount_xZ*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_Xz, recvCount_Xz*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_XZ, recvCount_XZ*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_yz, recvCount_yz*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_yZ, recvCount_yZ*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_Yz, recvCount_Yz*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_YZ, recvCount_YZ*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xyz, recvCount_xyz*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xYz, recvCount_xYz*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_Xyz, recvCount_Xyz*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_XYz, recvCount_XYz*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xyZ, recvCount_xyZ*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xYZ, recvCount_xYZ*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_XyZ, recvCount_XyZ*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **) &recvbuf_XYZ, recvCount_XYZ*sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_x,
|
||||
recvCount_x *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_X,
|
||||
recvCount_X *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_y,
|
||||
recvCount_y *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_Y,
|
||||
recvCount_Y *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_z,
|
||||
recvCount_z *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_Z,
|
||||
recvCount_Z *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_xy,
|
||||
recvCount_xy *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_xY,
|
||||
recvCount_xY *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_Xy,
|
||||
recvCount_Xy *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_XY,
|
||||
recvCount_XY *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_xz,
|
||||
recvCount_xz *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_xZ,
|
||||
recvCount_xZ *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_Xz,
|
||||
recvCount_Xz *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_XZ,
|
||||
recvCount_XZ *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_yz,
|
||||
recvCount_yz *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_yZ,
|
||||
recvCount_yZ *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_Yz,
|
||||
recvCount_Yz *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_YZ,
|
||||
recvCount_YZ *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_xyz,
|
||||
recvCount_xyz *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_xYz,
|
||||
recvCount_xYz *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_Xyz,
|
||||
recvCount_Xyz *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_XYz,
|
||||
recvCount_XYz *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_xyZ,
|
||||
recvCount_xyZ *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_xYZ,
|
||||
recvCount_xYZ *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_XyZ,
|
||||
recvCount_XyZ *
|
||||
sizeof(double)); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&recvbuf_XYZ,
|
||||
recvCount_XYZ *
|
||||
sizeof(double)); // Allocate device memory
|
||||
|
||||
/* Set up a map to the halo width=1 data structure */
|
||||
for (k = width; k < Nzh - width; k++) {
|
||||
|
@ -189,15 +349,14 @@ ScaLBLWideHalo_Communicator::ScaLBLWideHalo_Communicator(std::shared_ptr <Domain
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ScaLBLWideHalo_Communicator::Send(double *data) {
|
||||
//...................................................................................
|
||||
if (Lock == true) {
|
||||
ERROR("ScaLBL Error (SendHalo): ScaLBLWideHalo_Communicator is locked -- did you forget to match Send/Recv calls?");
|
||||
}
|
||||
else{
|
||||
ERROR("ScaLBL Error (SendHalo): ScaLBLWideHalo_Communicator is locked "
|
||||
"-- did you forget to match Send/Recv calls?");
|
||||
} else {
|
||||
Lock = true;
|
||||
}
|
||||
ScaLBL_DeviceBarrier();
|
||||
|
@ -234,67 +393,115 @@ void ScaLBLWideHalo_Communicator::Send(double *data){
|
|||
//...................................................................................
|
||||
// Send / Recv all the phase indcator field values
|
||||
//...................................................................................
|
||||
req1[0] = MPI_COMM_SCALBL.Isend(sendbuf_x,sendCount_x,rank_x,sendtag+0);
|
||||
req2[0] = MPI_COMM_SCALBL.Irecv(recvbuf_X,recvCount_X,rank_X,recvtag+0);
|
||||
req1[1] = MPI_COMM_SCALBL.Isend(sendbuf_X,sendCount_X,rank_X,sendtag+1);
|
||||
req2[1] = MPI_COMM_SCALBL.Irecv(recvbuf_x,recvCount_x,rank_x,recvtag+1);
|
||||
req1[2] = MPI_COMM_SCALBL.Isend(sendbuf_y,sendCount_y,rank_y,sendtag+2);
|
||||
req2[2] = MPI_COMM_SCALBL.Irecv(recvbuf_Y,recvCount_Y,rank_Y,recvtag+2);
|
||||
req1[3] = MPI_COMM_SCALBL.Isend(sendbuf_Y,sendCount_Y,rank_Y,sendtag+3);
|
||||
req2[3] = MPI_COMM_SCALBL.Irecv(recvbuf_y,recvCount_y,rank_y,recvtag+3);
|
||||
req1[4] = MPI_COMM_SCALBL.Isend(sendbuf_z,sendCount_z,rank_z,sendtag+4);
|
||||
req2[4] = MPI_COMM_SCALBL.Irecv(recvbuf_Z,recvCount_Z,rank_Z,recvtag+4);
|
||||
req1[5] = MPI_COMM_SCALBL.Isend(sendbuf_Z,sendCount_Z,rank_Z,sendtag+5);
|
||||
req2[5] = MPI_COMM_SCALBL.Irecv(recvbuf_z,recvCount_z,rank_z,recvtag+5);
|
||||
req1[6] = MPI_COMM_SCALBL.Isend(sendbuf_xy,sendCount_xy,rank_xy,sendtag+6);
|
||||
req2[6] = MPI_COMM_SCALBL.Irecv(recvbuf_XY,recvCount_XY,rank_XY,recvtag+6);
|
||||
req1[7] = MPI_COMM_SCALBL.Isend(sendbuf_XY,sendCount_XY,rank_XY,sendtag+7);
|
||||
req2[7] = MPI_COMM_SCALBL.Irecv(recvbuf_xy,recvCount_xy,rank_xy,recvtag+7);
|
||||
req1[8] = MPI_COMM_SCALBL.Isend(sendbuf_Xy,sendCount_Xy,rank_Xy,sendtag+8);
|
||||
req2[8] = MPI_COMM_SCALBL.Irecv(recvbuf_xY,recvCount_xY,rank_xY,recvtag+8);
|
||||
req1[9] = MPI_COMM_SCALBL.Isend(sendbuf_xY,sendCount_xY,rank_xY,sendtag+9);
|
||||
req2[9] = MPI_COMM_SCALBL.Irecv(recvbuf_Xy,recvCount_Xy,rank_Xy,recvtag+9);
|
||||
req1[10] = MPI_COMM_SCALBL.Isend(sendbuf_xz,sendCount_xz,rank_xz,sendtag+10);
|
||||
req2[10] = MPI_COMM_SCALBL.Irecv(recvbuf_XZ,recvCount_XZ,rank_XZ,recvtag+10);
|
||||
req1[11] = MPI_COMM_SCALBL.Isend(sendbuf_XZ,sendCount_XZ,rank_XZ,sendtag+11);
|
||||
req2[11] = MPI_COMM_SCALBL.Irecv(recvbuf_xz,recvCount_xz,rank_xz,recvtag+11);
|
||||
req1[12] = MPI_COMM_SCALBL.Isend(sendbuf_Xz,sendCount_Xz,rank_Xz,sendtag+12);
|
||||
req2[12] = MPI_COMM_SCALBL.Irecv(recvbuf_xZ,recvCount_xZ,rank_xZ,recvtag+12);
|
||||
req1[13] = MPI_COMM_SCALBL.Isend(sendbuf_xZ,sendCount_xZ,rank_xZ,sendtag+13);
|
||||
req2[13] = MPI_COMM_SCALBL.Irecv(recvbuf_Xz,recvCount_Xz,rank_Xz,recvtag+13);
|
||||
req1[14] = MPI_COMM_SCALBL.Isend(sendbuf_yz,sendCount_yz,rank_yz,sendtag+14);
|
||||
req2[14] = MPI_COMM_SCALBL.Irecv(recvbuf_YZ,recvCount_YZ,rank_YZ,recvtag+14);
|
||||
req1[15] = MPI_COMM_SCALBL.Isend(sendbuf_YZ,sendCount_YZ,rank_YZ,sendtag+15);
|
||||
req2[15] = MPI_COMM_SCALBL.Irecv(recvbuf_yz,recvCount_yz,rank_yz,recvtag+15);
|
||||
req1[16] = MPI_COMM_SCALBL.Isend(sendbuf_Yz,sendCount_Yz,rank_Yz,sendtag+16);
|
||||
req2[16] = MPI_COMM_SCALBL.Irecv(recvbuf_yZ,recvCount_yZ,rank_yZ,recvtag+16);
|
||||
req1[17] = MPI_COMM_SCALBL.Isend(sendbuf_yZ,sendCount_yZ,rank_yZ,sendtag+17);
|
||||
req2[17] = MPI_COMM_SCALBL.Irecv(recvbuf_Yz,recvCount_Yz,rank_Yz,recvtag+17);
|
||||
req1[0] =
|
||||
MPI_COMM_SCALBL.Isend(sendbuf_x, sendCount_x, rank_x, sendtag + 0);
|
||||
req2[0] =
|
||||
MPI_COMM_SCALBL.Irecv(recvbuf_X, recvCount_X, rank_X, recvtag + 0);
|
||||
req1[1] =
|
||||
MPI_COMM_SCALBL.Isend(sendbuf_X, sendCount_X, rank_X, sendtag + 1);
|
||||
req2[1] =
|
||||
MPI_COMM_SCALBL.Irecv(recvbuf_x, recvCount_x, rank_x, recvtag + 1);
|
||||
req1[2] =
|
||||
MPI_COMM_SCALBL.Isend(sendbuf_y, sendCount_y, rank_y, sendtag + 2);
|
||||
req2[2] =
|
||||
MPI_COMM_SCALBL.Irecv(recvbuf_Y, recvCount_Y, rank_Y, recvtag + 2);
|
||||
req1[3] =
|
||||
MPI_COMM_SCALBL.Isend(sendbuf_Y, sendCount_Y, rank_Y, sendtag + 3);
|
||||
req2[3] =
|
||||
MPI_COMM_SCALBL.Irecv(recvbuf_y, recvCount_y, rank_y, recvtag + 3);
|
||||
req1[4] =
|
||||
MPI_COMM_SCALBL.Isend(sendbuf_z, sendCount_z, rank_z, sendtag + 4);
|
||||
req2[4] =
|
||||
MPI_COMM_SCALBL.Irecv(recvbuf_Z, recvCount_Z, rank_Z, recvtag + 4);
|
||||
req1[5] =
|
||||
MPI_COMM_SCALBL.Isend(sendbuf_Z, sendCount_Z, rank_Z, sendtag + 5);
|
||||
req2[5] =
|
||||
MPI_COMM_SCALBL.Irecv(recvbuf_z, recvCount_z, rank_z, recvtag + 5);
|
||||
req1[6] =
|
||||
MPI_COMM_SCALBL.Isend(sendbuf_xy, sendCount_xy, rank_xy, sendtag + 6);
|
||||
req2[6] =
|
||||
MPI_COMM_SCALBL.Irecv(recvbuf_XY, recvCount_XY, rank_XY, recvtag + 6);
|
||||
req1[7] =
|
||||
MPI_COMM_SCALBL.Isend(sendbuf_XY, sendCount_XY, rank_XY, sendtag + 7);
|
||||
req2[7] =
|
||||
MPI_COMM_SCALBL.Irecv(recvbuf_xy, recvCount_xy, rank_xy, recvtag + 7);
|
||||
req1[8] =
|
||||
MPI_COMM_SCALBL.Isend(sendbuf_Xy, sendCount_Xy, rank_Xy, sendtag + 8);
|
||||
req2[8] =
|
||||
MPI_COMM_SCALBL.Irecv(recvbuf_xY, recvCount_xY, rank_xY, recvtag + 8);
|
||||
req1[9] =
|
||||
MPI_COMM_SCALBL.Isend(sendbuf_xY, sendCount_xY, rank_xY, sendtag + 9);
|
||||
req2[9] =
|
||||
MPI_COMM_SCALBL.Irecv(recvbuf_Xy, recvCount_Xy, rank_Xy, recvtag + 9);
|
||||
req1[10] =
|
||||
MPI_COMM_SCALBL.Isend(sendbuf_xz, sendCount_xz, rank_xz, sendtag + 10);
|
||||
req2[10] =
|
||||
MPI_COMM_SCALBL.Irecv(recvbuf_XZ, recvCount_XZ, rank_XZ, recvtag + 10);
|
||||
req1[11] =
|
||||
MPI_COMM_SCALBL.Isend(sendbuf_XZ, sendCount_XZ, rank_XZ, sendtag + 11);
|
||||
req2[11] =
|
||||
MPI_COMM_SCALBL.Irecv(recvbuf_xz, recvCount_xz, rank_xz, recvtag + 11);
|
||||
req1[12] =
|
||||
MPI_COMM_SCALBL.Isend(sendbuf_Xz, sendCount_Xz, rank_Xz, sendtag + 12);
|
||||
req2[12] =
|
||||
MPI_COMM_SCALBL.Irecv(recvbuf_xZ, recvCount_xZ, rank_xZ, recvtag + 12);
|
||||
req1[13] =
|
||||
MPI_COMM_SCALBL.Isend(sendbuf_xZ, sendCount_xZ, rank_xZ, sendtag + 13);
|
||||
req2[13] =
|
||||
MPI_COMM_SCALBL.Irecv(recvbuf_Xz, recvCount_Xz, rank_Xz, recvtag + 13);
|
||||
req1[14] =
|
||||
MPI_COMM_SCALBL.Isend(sendbuf_yz, sendCount_yz, rank_yz, sendtag + 14);
|
||||
req2[14] =
|
||||
MPI_COMM_SCALBL.Irecv(recvbuf_YZ, recvCount_YZ, rank_YZ, recvtag + 14);
|
||||
req1[15] =
|
||||
MPI_COMM_SCALBL.Isend(sendbuf_YZ, sendCount_YZ, rank_YZ, sendtag + 15);
|
||||
req2[15] =
|
||||
MPI_COMM_SCALBL.Irecv(recvbuf_yz, recvCount_yz, rank_yz, recvtag + 15);
|
||||
req1[16] =
|
||||
MPI_COMM_SCALBL.Isend(sendbuf_Yz, sendCount_Yz, rank_Yz, sendtag + 16);
|
||||
req2[16] =
|
||||
MPI_COMM_SCALBL.Irecv(recvbuf_yZ, recvCount_yZ, rank_yZ, recvtag + 16);
|
||||
req1[17] =
|
||||
MPI_COMM_SCALBL.Isend(sendbuf_yZ, sendCount_yZ, rank_yZ, sendtag + 17);
|
||||
req2[17] =
|
||||
MPI_COMM_SCALBL.Irecv(recvbuf_Yz, recvCount_Yz, rank_Yz, recvtag + 17);
|
||||
/* Corners */
|
||||
req1[18] = MPI_COMM_SCALBL.Isend(sendbuf_xyz,sendCount_xyz,rank_xyz,sendtag+18);
|
||||
req2[18] = MPI_COMM_SCALBL.Irecv(recvbuf_XYZ,recvCount_XYZ,rank_XYZ,recvtag+18);
|
||||
req1[19] = MPI_COMM_SCALBL.Isend(sendbuf_XYz,sendCount_XYz,rank_XYz,sendtag+19);
|
||||
req2[19] = MPI_COMM_SCALBL.Irecv(recvbuf_xyZ,recvCount_xyZ,rank_xyZ,recvtag+19);
|
||||
req1[20] = MPI_COMM_SCALBL.Isend(sendbuf_Xyz,sendCount_Xyz,rank_Xyz,sendtag+20);
|
||||
req2[20] = MPI_COMM_SCALBL.Irecv(recvbuf_xYZ,recvCount_xYZ,rank_xYZ,recvtag+20);
|
||||
req1[21] = MPI_COMM_SCALBL.Isend(sendbuf_xYz,sendCount_xYz,rank_xYz,sendtag+21);
|
||||
req2[21] = MPI_COMM_SCALBL.Irecv(recvbuf_XyZ,recvCount_XyZ,rank_XyZ,recvtag+21);
|
||||
req1[22] = MPI_COMM_SCALBL.Isend(sendbuf_xyZ,sendCount_xyZ,rank_xyZ,sendtag+22);
|
||||
req2[22] = MPI_COMM_SCALBL.Irecv(recvbuf_XYz,recvCount_XYz,rank_XYz,recvtag+22);
|
||||
req1[23] = MPI_COMM_SCALBL.Isend(sendbuf_XYZ,sendCount_XYZ,rank_XYZ,sendtag+23);
|
||||
req2[23] = MPI_COMM_SCALBL.Irecv(recvbuf_xyz,recvCount_xyz,rank_xyz,recvtag+23);
|
||||
req1[24] = MPI_COMM_SCALBL.Isend(sendbuf_XyZ,sendCount_XyZ,rank_XyZ,sendtag+24);
|
||||
req2[24] = MPI_COMM_SCALBL.Irecv(recvbuf_xYz,recvCount_xYz,rank_xYz,recvtag+24);
|
||||
req1[25] = MPI_COMM_SCALBL.Isend(sendbuf_xYZ,sendCount_xYZ,rank_xYZ,sendtag+25);
|
||||
req2[25] = MPI_COMM_SCALBL.Irecv(recvbuf_Xyz,recvCount_Xyz,rank_Xyz,recvtag+25);
|
||||
req1[18] = MPI_COMM_SCALBL.Isend(sendbuf_xyz, sendCount_xyz, rank_xyz,
|
||||
sendtag + 18);
|
||||
req2[18] = MPI_COMM_SCALBL.Irecv(recvbuf_XYZ, recvCount_XYZ, rank_XYZ,
|
||||
recvtag + 18);
|
||||
req1[19] = MPI_COMM_SCALBL.Isend(sendbuf_XYz, sendCount_XYz, rank_XYz,
|
||||
sendtag + 19);
|
||||
req2[19] = MPI_COMM_SCALBL.Irecv(recvbuf_xyZ, recvCount_xyZ, rank_xyZ,
|
||||
recvtag + 19);
|
||||
req1[20] = MPI_COMM_SCALBL.Isend(sendbuf_Xyz, sendCount_Xyz, rank_Xyz,
|
||||
sendtag + 20);
|
||||
req2[20] = MPI_COMM_SCALBL.Irecv(recvbuf_xYZ, recvCount_xYZ, rank_xYZ,
|
||||
recvtag + 20);
|
||||
req1[21] = MPI_COMM_SCALBL.Isend(sendbuf_xYz, sendCount_xYz, rank_xYz,
|
||||
sendtag + 21);
|
||||
req2[21] = MPI_COMM_SCALBL.Irecv(recvbuf_XyZ, recvCount_XyZ, rank_XyZ,
|
||||
recvtag + 21);
|
||||
req1[22] = MPI_COMM_SCALBL.Isend(sendbuf_xyZ, sendCount_xyZ, rank_xyZ,
|
||||
sendtag + 22);
|
||||
req2[22] = MPI_COMM_SCALBL.Irecv(recvbuf_XYz, recvCount_XYz, rank_XYz,
|
||||
recvtag + 22);
|
||||
req1[23] = MPI_COMM_SCALBL.Isend(sendbuf_XYZ, sendCount_XYZ, rank_XYZ,
|
||||
sendtag + 23);
|
||||
req2[23] = MPI_COMM_SCALBL.Irecv(recvbuf_xyz, recvCount_xyz, rank_xyz,
|
||||
recvtag + 23);
|
||||
req1[24] = MPI_COMM_SCALBL.Isend(sendbuf_XyZ, sendCount_XyZ, rank_XyZ,
|
||||
sendtag + 24);
|
||||
req2[24] = MPI_COMM_SCALBL.Irecv(recvbuf_xYz, recvCount_xYz, rank_xYz,
|
||||
recvtag + 24);
|
||||
req1[25] = MPI_COMM_SCALBL.Isend(sendbuf_xYZ, sendCount_xYZ, rank_xYZ,
|
||||
sendtag + 25);
|
||||
req2[25] = MPI_COMM_SCALBL.Irecv(recvbuf_Xyz, recvCount_Xyz, rank_Xyz,
|
||||
recvtag + 25);
|
||||
//...................................................................................
|
||||
|
||||
}
|
||||
|
||||
|
||||
ScaLBLWideHalo_Communicator::~ScaLBLWideHalo_Communicator()
|
||||
{
|
||||
}
|
||||
ScaLBLWideHalo_Communicator::~ScaLBLWideHalo_Communicator() {}
|
||||
void ScaLBLWideHalo_Communicator::Recv(double *data) {
|
||||
|
||||
//...................................................................................
|
||||
|
@ -335,6 +542,4 @@ void ScaLBLWideHalo_Communicator::Recv(double *data){
|
|||
//...................................................................................
|
||||
Lock = false; // unlock the communicator after communications complete
|
||||
//...................................................................................
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -23,14 +23,20 @@ public:
|
|||
// Set up for D3Q19 distributions -- all 27 neighbors are needed
|
||||
//......................................................................................
|
||||
// Buffers to store data sent and recieved by this MPI process
|
||||
double *sendbuf_x, *sendbuf_y, *sendbuf_z, *sendbuf_X, *sendbuf_Y, *sendbuf_Z;
|
||||
double *sendbuf_xy, *sendbuf_yz, *sendbuf_xz, *sendbuf_Xy, *sendbuf_Yz, *sendbuf_xZ;
|
||||
double *sendbuf_xY, *sendbuf_yZ, *sendbuf_Xz, *sendbuf_XY, *sendbuf_YZ, *sendbuf_XZ;
|
||||
double *sendbuf_x, *sendbuf_y, *sendbuf_z, *sendbuf_X, *sendbuf_Y,
|
||||
*sendbuf_Z;
|
||||
double *sendbuf_xy, *sendbuf_yz, *sendbuf_xz, *sendbuf_Xy, *sendbuf_Yz,
|
||||
*sendbuf_xZ;
|
||||
double *sendbuf_xY, *sendbuf_yZ, *sendbuf_Xz, *sendbuf_XY, *sendbuf_YZ,
|
||||
*sendbuf_XZ;
|
||||
double *sendbuf_xyz, *sendbuf_Xyz, *sendbuf_xYz, *sendbuf_XYz;
|
||||
double *sendbuf_xyZ, *sendbuf_XyZ, *sendbuf_xYZ, *sendbuf_XYZ;
|
||||
double *recvbuf_x, *recvbuf_y, *recvbuf_z, *recvbuf_X, *recvbuf_Y, *recvbuf_Z;
|
||||
double *recvbuf_xy, *recvbuf_yz, *recvbuf_xz, *recvbuf_Xy, *recvbuf_Yz, *recvbuf_xZ;
|
||||
double *recvbuf_xY, *recvbuf_yZ, *recvbuf_Xz, *recvbuf_XY, *recvbuf_YZ, *recvbuf_XZ;
|
||||
double *recvbuf_x, *recvbuf_y, *recvbuf_z, *recvbuf_X, *recvbuf_Y,
|
||||
*recvbuf_Z;
|
||||
double *recvbuf_xy, *recvbuf_yz, *recvbuf_xz, *recvbuf_Xy, *recvbuf_Yz,
|
||||
*recvbuf_xZ;
|
||||
double *recvbuf_xY, *recvbuf_yZ, *recvbuf_Xz, *recvbuf_XY, *recvbuf_YZ,
|
||||
*recvbuf_XZ;
|
||||
double *recvbuf_xyz, *recvbuf_Xyz, *recvbuf_xYz, *recvbuf_XYz;
|
||||
double *recvbuf_xyZ, *recvbuf_XyZ, *recvbuf_xYZ, *recvbuf_XYZ;
|
||||
//......................................................................................
|
||||
|
@ -45,7 +51,8 @@ public:
|
|||
void PrintDebug();
|
||||
|
||||
private:
|
||||
bool Lock; // use Lock to make sure only one call at a time to protect data in transit
|
||||
bool
|
||||
Lock; // use Lock to make sure only one call at a time to protect data in transit
|
||||
// only one set of Send requests can be active at any time (per instance)
|
||||
int i, j, k, n;
|
||||
int iproc, jproc, kproc;
|
||||
|
@ -68,33 +75,46 @@ private:
|
|||
int rank_xyZ, rank_XyZ, rank_xYZ, rank_XYZ;
|
||||
//......................................................................................
|
||||
//......................................................................................
|
||||
int sendCount_x, sendCount_y, sendCount_z, sendCount_X, sendCount_Y, sendCount_Z;
|
||||
int sendCount_xy, sendCount_yz, sendCount_xz, sendCount_Xy, sendCount_Yz, sendCount_xZ;
|
||||
int sendCount_xY, sendCount_yZ, sendCount_Xz, sendCount_XY, sendCount_YZ, sendCount_XZ;
|
||||
int sendCount_x, sendCount_y, sendCount_z, sendCount_X, sendCount_Y,
|
||||
sendCount_Z;
|
||||
int sendCount_xy, sendCount_yz, sendCount_xz, sendCount_Xy, sendCount_Yz,
|
||||
sendCount_xZ;
|
||||
int sendCount_xY, sendCount_yZ, sendCount_Xz, sendCount_XY, sendCount_YZ,
|
||||
sendCount_XZ;
|
||||
int sendCount_xyz, sendCount_Xyz, sendCount_xYz, sendCount_XYz;
|
||||
int sendCount_xyZ, sendCount_XyZ, sendCount_xYZ, sendCount_XYZ;
|
||||
//......................................................................................
|
||||
int recvCount_x, recvCount_y, recvCount_z, recvCount_X, recvCount_Y, recvCount_Z;
|
||||
int recvCount_xy, recvCount_yz, recvCount_xz, recvCount_Xy, recvCount_Yz, recvCount_xZ;
|
||||
int recvCount_xY, recvCount_yZ, recvCount_Xz, recvCount_XY, recvCount_YZ, recvCount_XZ;
|
||||
int recvCount_x, recvCount_y, recvCount_z, recvCount_X, recvCount_Y,
|
||||
recvCount_Z;
|
||||
int recvCount_xy, recvCount_yz, recvCount_xz, recvCount_Xy, recvCount_Yz,
|
||||
recvCount_xZ;
|
||||
int recvCount_xY, recvCount_yZ, recvCount_Xz, recvCount_XY, recvCount_YZ,
|
||||
recvCount_XZ;
|
||||
int recvCount_xyz, recvCount_Xyz, recvCount_xYz, recvCount_XYz;
|
||||
int recvCount_xyZ, recvCount_XyZ, recvCount_xYZ, recvCount_XYZ;
|
||||
//......................................................................................
|
||||
// Send buffers that reside on the compute device
|
||||
int *dvcSendList_x, *dvcSendList_y, *dvcSendList_z, *dvcSendList_X, *dvcSendList_Y, *dvcSendList_Z;
|
||||
int *dvcSendList_xy, *dvcSendList_yz, *dvcSendList_xz, *dvcSendList_Xy, *dvcSendList_Yz, *dvcSendList_xZ;
|
||||
int *dvcSendList_xY, *dvcSendList_yZ, *dvcSendList_Xz, *dvcSendList_XY, *dvcSendList_YZ, *dvcSendList_XZ;
|
||||
int *dvcSendList_x, *dvcSendList_y, *dvcSendList_z, *dvcSendList_X,
|
||||
*dvcSendList_Y, *dvcSendList_Z;
|
||||
int *dvcSendList_xy, *dvcSendList_yz, *dvcSendList_xz, *dvcSendList_Xy,
|
||||
*dvcSendList_Yz, *dvcSendList_xZ;
|
||||
int *dvcSendList_xY, *dvcSendList_yZ, *dvcSendList_Xz, *dvcSendList_XY,
|
||||
*dvcSendList_YZ, *dvcSendList_XZ;
|
||||
int *dvcSendList_xyz, *dvcSendList_Xyz, *dvcSendList_xYz, *dvcSendList_XYz;
|
||||
int *dvcSendList_xyZ, *dvcSendList_XyZ, *dvcSendList_xYZ, *dvcSendList_XYZ;
|
||||
// Recieve buffers that reside on the compute device
|
||||
int *dvcRecvList_x, *dvcRecvList_y, *dvcRecvList_z, *dvcRecvList_X, *dvcRecvList_Y, *dvcRecvList_Z;
|
||||
int *dvcRecvList_xy, *dvcRecvList_yz, *dvcRecvList_xz, *dvcRecvList_Xy, *dvcRecvList_Yz, *dvcRecvList_xZ;
|
||||
int *dvcRecvList_xY, *dvcRecvList_yZ, *dvcRecvList_Xz, *dvcRecvList_XY, *dvcRecvList_YZ, *dvcRecvList_XZ;
|
||||
int *dvcRecvList_x, *dvcRecvList_y, *dvcRecvList_z, *dvcRecvList_X,
|
||||
*dvcRecvList_Y, *dvcRecvList_Z;
|
||||
int *dvcRecvList_xy, *dvcRecvList_yz, *dvcRecvList_xz, *dvcRecvList_Xy,
|
||||
*dvcRecvList_Yz, *dvcRecvList_xZ;
|
||||
int *dvcRecvList_xY, *dvcRecvList_yZ, *dvcRecvList_Xz, *dvcRecvList_XY,
|
||||
*dvcRecvList_YZ, *dvcRecvList_XZ;
|
||||
int *dvcRecvList_xyz, *dvcRecvList_Xyz, *dvcRecvList_xYz, *dvcRecvList_XYz;
|
||||
int *dvcRecvList_xyZ, *dvcRecvList_XyZ, *dvcRecvList_xYZ, *dvcRecvList_XYZ;
|
||||
//......................................................................................
|
||||
|
||||
inline int getHaloBlock(int imin, int imax, int jmin, int jmax, int kmin, int kmax, int *& dvcList){
|
||||
inline int getHaloBlock(int imin, int imax, int jmin, int jmax, int kmin,
|
||||
int kmax, int *&dvcList) {
|
||||
int count = 0;
|
||||
int *List;
|
||||
List = new int[(imax - imin) * (jmax - jmin) * (kmax - kmin)];
|
||||
|
@ -106,10 +126,10 @@ private:
|
|||
}
|
||||
}
|
||||
size_t numbytes = count * sizeof(int);
|
||||
ScaLBL_AllocateZeroCopy((void **) &dvcList, numbytes); // Allocate device memory
|
||||
ScaLBL_AllocateZeroCopy((void **)&dvcList,
|
||||
numbytes); // Allocate device memory
|
||||
ScaLBL_CopyToZeroCopy(dvcList, List, numbytes);
|
||||
return count;
|
||||
}
|
||||
|
||||
};
|
||||
#endif
|
||||
|
|
277
cpu/BGK.cpp
277
cpu/BGK.cpp
|
@ -1,8 +1,27 @@
|
|||
extern "C" void ScaLBL_D3Q19_AAeven_BGK(double *dist, int start, int finish, int Np, double rlx, double Fx, double Fy, double Fz){
|
||||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
extern "C" void ScaLBL_D3Q19_AAeven_BGK(double *dist, int start, int finish,
|
||||
int Np, double rlx, double Fx,
|
||||
double Fy, double Fz) {
|
||||
// conserved momemnts
|
||||
double rho, ux, uy, uz, uu;
|
||||
// non-conserved moments
|
||||
double f0,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18;
|
||||
double f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
|
||||
f16, f17, f18;
|
||||
|
||||
for (int n = start; n < finish; n++) {
|
||||
// q=0
|
||||
|
@ -26,7 +45,8 @@ extern "C" void ScaLBL_D3Q19_AAeven_BGK(double *dist, int start, int finish, int
|
|||
f17 = dist[18 * Np + n];
|
||||
f18 = dist[17 * Np + n];
|
||||
|
||||
rho = f0+f2+f1+f4+f3+f6+f5+f8+f7+f10+f9+f12+f11+f14+f13+f16+f15+f18+f17;
|
||||
rho = f0 + f2 + f1 + f4 + f3 + f6 + f5 + f8 + f7 + f10 + f9 + f12 +
|
||||
f11 + f14 + f13 + f16 + f15 + f18 + f17;
|
||||
ux = f1 - f2 + f7 - f8 + f9 - f10 + f11 - f12 + f13 - f14;
|
||||
uy = f3 - f4 + f7 - f8 - f9 + f10 + f15 - f16 + f17 - f18;
|
||||
uz = f5 - f6 + f11 - f12 - f13 + f14 + f15 - f16 - f17 + f18;
|
||||
|
@ -36,85 +56,140 @@ extern "C" void ScaLBL_D3Q19_AAeven_BGK(double *dist, int start, int finish, int
|
|||
dist[n] = f0 * (1.0 - rlx) + rlx * 0.3333333333333333 * (1.0 - uu);
|
||||
|
||||
// q = 1
|
||||
dist[1*Np+n] = f1*(1.0-rlx) + rlx*0.05555555555555555*(rho + 3.0*ux + 4.5*ux*ux - uu) + 0.16666666*Fx;
|
||||
dist[1 * Np + n] =
|
||||
f1 * (1.0 - rlx) +
|
||||
rlx * 0.05555555555555555 * (rho + 3.0 * ux + 4.5 * ux * ux - uu) +
|
||||
0.16666666 * Fx;
|
||||
|
||||
// q=2
|
||||
dist[2*Np+n] = f2*(1.0-rlx) + rlx*0.05555555555555555*(rho - 3.0*ux + 4.5*ux*ux - uu)- 0.16666666*Fx;
|
||||
dist[2 * Np + n] =
|
||||
f2 * (1.0 - rlx) +
|
||||
rlx * 0.05555555555555555 * (rho - 3.0 * ux + 4.5 * ux * ux - uu) -
|
||||
0.16666666 * Fx;
|
||||
|
||||
// q = 3
|
||||
dist[3*Np+n] = f3*(1.0-rlx) +
|
||||
rlx*0.05555555555555555*(rho + 3.0*uy + 4.5*uy*uy - uu) + 0.16666666*Fy;
|
||||
dist[3 * Np + n] =
|
||||
f3 * (1.0 - rlx) +
|
||||
rlx * 0.05555555555555555 * (rho + 3.0 * uy + 4.5 * uy * uy - uu) +
|
||||
0.16666666 * Fy;
|
||||
|
||||
// q = 4
|
||||
dist[4*Np+n] = f4*(1.0-rlx) +
|
||||
rlx*0.05555555555555555*(rho - 3.0*uy + 4.5*uy*uy - uu)- 0.16666666*Fy;
|
||||
dist[4 * Np + n] =
|
||||
f4 * (1.0 - rlx) +
|
||||
rlx * 0.05555555555555555 * (rho - 3.0 * uy + 4.5 * uy * uy - uu) -
|
||||
0.16666666 * Fy;
|
||||
|
||||
// q = 5
|
||||
dist[5*Np+n] = f5*(1.0-rlx) +
|
||||
rlx*0.05555555555555555*(rho + 3.0*uz + 4.5*uz*uz - uu) + 0.16666666*Fz;
|
||||
dist[5 * Np + n] =
|
||||
f5 * (1.0 - rlx) +
|
||||
rlx * 0.05555555555555555 * (rho + 3.0 * uz + 4.5 * uz * uz - uu) +
|
||||
0.16666666 * Fz;
|
||||
|
||||
// q = 6
|
||||
dist[6*Np+n] = f6*(1.0-rlx) +
|
||||
rlx*0.05555555555555555*(rho - 3.0*uz + 4.5*uz*uz - uu) - 0.16666666*Fz;
|
||||
dist[6 * Np + n] =
|
||||
f6 * (1.0 - rlx) +
|
||||
rlx * 0.05555555555555555 * (rho - 3.0 * uz + 4.5 * uz * uz - uu) -
|
||||
0.16666666 * Fz;
|
||||
|
||||
// q = 7
|
||||
dist[7*Np+n] = f7*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho + 3.0*(ux+uy) + 4.5*(ux+uy)*(ux+uy) - uu) + 0.08333333333*(Fx+Fy);
|
||||
dist[7 * Np + n] =
|
||||
f7 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho + 3.0 * (ux + uy) + 4.5 * (ux + uy) * (ux + uy) - uu) +
|
||||
0.08333333333 * (Fx + Fy);
|
||||
|
||||
// q = 8
|
||||
dist[8*Np+n] = f8*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho - 3.0*(ux+uy) + 4.5*(ux+uy)*(ux+uy) - uu) - 0.08333333333*(Fx+Fy);
|
||||
dist[8 * Np + n] =
|
||||
f8 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho - 3.0 * (ux + uy) + 4.5 * (ux + uy) * (ux + uy) - uu) -
|
||||
0.08333333333 * (Fx + Fy);
|
||||
|
||||
// q = 9
|
||||
dist[9*Np+n] = f9*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho + 3.0*(ux-uy) + 4.5*(ux-uy)*(ux-uy) - uu) + 0.08333333333*(Fx-Fy);
|
||||
dist[9 * Np + n] =
|
||||
f9 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho + 3.0 * (ux - uy) + 4.5 * (ux - uy) * (ux - uy) - uu) +
|
||||
0.08333333333 * (Fx - Fy);
|
||||
|
||||
// q = 10
|
||||
dist[10*Np+n] = f10*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho - 3.0*(ux-uy) + 4.5*(ux-uy)*(ux-uy) - uu) - 0.08333333333*(Fx-Fy);
|
||||
dist[10 * Np + n] =
|
||||
f10 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho - 3.0 * (ux - uy) + 4.5 * (ux - uy) * (ux - uy) - uu) -
|
||||
0.08333333333 * (Fx - Fy);
|
||||
|
||||
// q = 11
|
||||
dist[11*Np+n] = f11*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho + 3.0*(ux+uz) + 4.5*(ux+uz)*(ux+uz) - uu) + 0.08333333333*(Fx+Fz);
|
||||
dist[11 * Np + n] =
|
||||
f11 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho + 3.0 * (ux + uz) + 4.5 * (ux + uz) * (ux + uz) - uu) +
|
||||
0.08333333333 * (Fx + Fz);
|
||||
|
||||
// q = 12
|
||||
dist[12*Np+n] = f12*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho - 3.0*(ux+uz) + 4.5*(ux+uz)*(ux+uz) - uu) - 0.08333333333*(Fx+Fz);
|
||||
dist[12 * Np + n] =
|
||||
f12 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho - 3.0 * (ux + uz) + 4.5 * (ux + uz) * (ux + uz) - uu) -
|
||||
0.08333333333 * (Fx + Fz);
|
||||
|
||||
// q = 13
|
||||
dist[13*Np+n] = f13*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho + 3.0*(ux-uz) + 4.5*(ux-uz)*(ux-uz) - uu) + 0.08333333333*(Fx-Fz);
|
||||
dist[13 * Np + n] =
|
||||
f13 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho + 3.0 * (ux - uz) + 4.5 * (ux - uz) * (ux - uz) - uu) +
|
||||
0.08333333333 * (Fx - Fz);
|
||||
|
||||
// q= 14
|
||||
dist[14*Np+n] = f14*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho - 3.0*(ux-uz) + 4.5*(ux-uz)*(ux-uz) - uu)- 0.08333333333*(Fx-Fz);
|
||||
dist[14 * Np + n] =
|
||||
f14 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho - 3.0 * (ux - uz) + 4.5 * (ux - uz) * (ux - uz) - uu) -
|
||||
0.08333333333 * (Fx - Fz);
|
||||
|
||||
// q = 15
|
||||
dist[15*Np+n] = f15*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho + 3.0*(uy+uz) + 4.5*(uy+uz)*(uy+uz) - uu) + 0.08333333333*(Fy+Fz);
|
||||
dist[15 * Np + n] =
|
||||
f15 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho + 3.0 * (uy + uz) + 4.5 * (uy + uz) * (uy + uz) - uu) +
|
||||
0.08333333333 * (Fy + Fz);
|
||||
|
||||
// q = 16
|
||||
dist[16*Np+n] = f16*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho - 3.0*(uy+uz) + 4.5*(uy+uz)*(uy+uz) - uu) - 0.08333333333*(Fy+Fz);
|
||||
dist[16 * Np + n] =
|
||||
f16 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho - 3.0 * (uy + uz) + 4.5 * (uy + uz) * (uy + uz) - uu) -
|
||||
0.08333333333 * (Fy + Fz);
|
||||
|
||||
// q = 17
|
||||
dist[17*Np+n] = f17*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho + 3.0*(uy-uz) + 4.5*(uy-uz)*(uy-uz) - uu) + 0.08333333333*(Fy-Fz);
|
||||
dist[17 * Np + n] =
|
||||
f17 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho + 3.0 * (uy - uz) + 4.5 * (uy - uz) * (uy - uz) - uu) +
|
||||
0.08333333333 * (Fy - Fz);
|
||||
|
||||
// q = 18
|
||||
dist[18*Np+n] = f18*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho - 3.0*(uy-uz) + 4.5*(uy-uz)*(uy-uz) - uu) - 0.08333333333*(Fy-Fz);
|
||||
dist[18 * Np + n] =
|
||||
f18 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho - 3.0 * (uy - uz) + 4.5 * (uy - uz) * (uy - uz) - uu) -
|
||||
0.08333333333 * (Fy - Fz);
|
||||
|
||||
//........................................................................
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_AAodd_BGK(int *neighborList, double *dist, int start, int finish, int Np, double rlx, double Fx, double Fy, double Fz){
|
||||
extern "C" void ScaLBL_D3Q19_AAodd_BGK(int *neighborList, double *dist,
|
||||
int start, int finish, int Np,
|
||||
double rlx, double Fx, double Fy,
|
||||
double Fz) {
|
||||
// conserved momemnts
|
||||
double rho, ux, uy, uz, uu;
|
||||
// non-conserved moments
|
||||
double f0,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18;
|
||||
int nr1,nr2,nr3,nr4,nr5,nr6,nr7,nr8,nr9,nr10,nr11,nr12,nr13,nr14,nr15,nr16,nr17,nr18;
|
||||
double f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
|
||||
f16, f17, f18;
|
||||
int nr1, nr2, nr3, nr4, nr5, nr6, nr7, nr8, nr9, nr10, nr11, nr12, nr13,
|
||||
nr14, nr15, nr16, nr17, nr18;
|
||||
|
||||
for (int n = start; n < finish; n++) {
|
||||
|
||||
|
@ -192,7 +267,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_BGK(int *neighborList, double *dist, int star
|
|||
nr18 = neighborList[n + 17 * Np];
|
||||
f18 = dist[nr18];
|
||||
|
||||
rho = f0+f2+f1+f4+f3+f6+f5+f8+f7+f10+f9+f12+f11+f14+f13+f16+f15+f18+f17;
|
||||
rho = f0 + f2 + f1 + f4 + f3 + f6 + f5 + f8 + f7 + f10 + f9 + f12 +
|
||||
f11 + f14 + f13 + f16 + f15 + f18 + f17;
|
||||
ux = f1 - f2 + f7 - f8 + f9 - f10 + f11 - f12 + f13 - f14;
|
||||
uy = f3 - f4 + f7 - f8 - f9 + f10 + f15 - f16 + f17 - f18;
|
||||
uz = f5 - f6 + f11 - f12 - f13 + f14 + f15 - f16 - f17 + f18;
|
||||
|
@ -202,74 +278,123 @@ extern "C" void ScaLBL_D3Q19_AAodd_BGK(int *neighborList, double *dist, int star
|
|||
dist[n] = f0 * (1.0 - rlx) + rlx * 0.3333333333333333 * (1.0 - uu);
|
||||
|
||||
// q = 1
|
||||
dist[nr2] = f1*(1.0-rlx) + rlx*0.05555555555555555*(rho + 3.0*ux + 4.5*ux*ux - uu) + 0.16666666*Fx;
|
||||
dist[nr2] =
|
||||
f1 * (1.0 - rlx) +
|
||||
rlx * 0.05555555555555555 * (rho + 3.0 * ux + 4.5 * ux * ux - uu) +
|
||||
0.16666666 * Fx;
|
||||
|
||||
// q=2
|
||||
dist[nr1] = f2*(1.0-rlx) + rlx*0.05555555555555555*(rho - 3.0*ux + 4.5*ux*ux - uu)- 0.16666666*Fx;
|
||||
dist[nr1] =
|
||||
f2 * (1.0 - rlx) +
|
||||
rlx * 0.05555555555555555 * (rho - 3.0 * ux + 4.5 * ux * ux - uu) -
|
||||
0.16666666 * Fx;
|
||||
|
||||
// q = 3
|
||||
dist[nr4] = f3*(1.0-rlx) +
|
||||
rlx*0.05555555555555555*(rho + 3.0*uy + 4.5*uy*uy - uu) + 0.16666666*Fy;
|
||||
dist[nr4] =
|
||||
f3 * (1.0 - rlx) +
|
||||
rlx * 0.05555555555555555 * (rho + 3.0 * uy + 4.5 * uy * uy - uu) +
|
||||
0.16666666 * Fy;
|
||||
|
||||
// q = 4
|
||||
dist[nr3] = f4*(1.0-rlx) +
|
||||
rlx*0.05555555555555555*(rho - 3.0*uy + 4.5*uy*uy - uu)- 0.16666666*Fy;
|
||||
dist[nr3] =
|
||||
f4 * (1.0 - rlx) +
|
||||
rlx * 0.05555555555555555 * (rho - 3.0 * uy + 4.5 * uy * uy - uu) -
|
||||
0.16666666 * Fy;
|
||||
|
||||
// q = 5
|
||||
dist[nr6] = f5*(1.0-rlx) +
|
||||
rlx*0.05555555555555555*(rho + 3.0*uz + 4.5*uz*uz - uu) + 0.16666666*Fz;
|
||||
dist[nr6] =
|
||||
f5 * (1.0 - rlx) +
|
||||
rlx * 0.05555555555555555 * (rho + 3.0 * uz + 4.5 * uz * uz - uu) +
|
||||
0.16666666 * Fz;
|
||||
|
||||
// q = 6
|
||||
dist[nr5] = f6*(1.0-rlx) +
|
||||
rlx*0.05555555555555555*(rho - 3.0*uz + 4.5*uz*uz - uu) - 0.16666666*Fz;
|
||||
dist[nr5] =
|
||||
f6 * (1.0 - rlx) +
|
||||
rlx * 0.05555555555555555 * (rho - 3.0 * uz + 4.5 * uz * uz - uu) -
|
||||
0.16666666 * Fz;
|
||||
|
||||
// q = 7
|
||||
dist[nr8] = f7*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho + 3.0*(ux+uy) + 4.5*(ux+uy)*(ux+uy) - uu) + 0.08333333333*(Fx+Fy);
|
||||
dist[nr8] =
|
||||
f7 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho + 3.0 * (ux + uy) + 4.5 * (ux + uy) * (ux + uy) - uu) +
|
||||
0.08333333333 * (Fx + Fy);
|
||||
|
||||
// q = 8
|
||||
dist[nr7] = f8*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho - 3.0*(ux+uy) + 4.5*(ux+uy)*(ux+uy) - uu) - 0.08333333333*(Fx+Fy);
|
||||
dist[nr7] =
|
||||
f8 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho - 3.0 * (ux + uy) + 4.5 * (ux + uy) * (ux + uy) - uu) -
|
||||
0.08333333333 * (Fx + Fy);
|
||||
|
||||
// q = 9
|
||||
dist[nr10] = f9*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho + 3.0*(ux-uy) + 4.5*(ux-uy)*(ux-uy) - uu) + 0.08333333333*(Fx-Fy);
|
||||
dist[nr10] =
|
||||
f9 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho + 3.0 * (ux - uy) + 4.5 * (ux - uy) * (ux - uy) - uu) +
|
||||
0.08333333333 * (Fx - Fy);
|
||||
|
||||
// q = 10
|
||||
dist[nr9] = f10*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho - 3.0*(ux-uy) + 4.5*(ux-uy)*(ux-uy) - uu) - 0.08333333333*(Fx-Fy);
|
||||
dist[nr9] =
|
||||
f10 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho - 3.0 * (ux - uy) + 4.5 * (ux - uy) * (ux - uy) - uu) -
|
||||
0.08333333333 * (Fx - Fy);
|
||||
|
||||
// q = 11
|
||||
dist[nr12] = f11*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho + 3.0*(ux+uz) + 4.5*(ux+uz)*(ux+uz) - uu) + 0.08333333333*(Fx+Fz);
|
||||
dist[nr12] =
|
||||
f11 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho + 3.0 * (ux + uz) + 4.5 * (ux + uz) * (ux + uz) - uu) +
|
||||
0.08333333333 * (Fx + Fz);
|
||||
|
||||
// q = 12
|
||||
dist[nr11] = f12*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho - 3.0*(ux+uz) + 4.5*(ux+uz)*(ux+uz) - uu) - 0.08333333333*(Fx+Fz);
|
||||
dist[nr11] =
|
||||
f12 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho - 3.0 * (ux + uz) + 4.5 * (ux + uz) * (ux + uz) - uu) -
|
||||
0.08333333333 * (Fx + Fz);
|
||||
|
||||
// q = 13
|
||||
dist[nr14] = f13*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho + 3.0*(ux-uz) + 4.5*(ux-uz)*(ux-uz) - uu) + 0.08333333333*(Fx-Fz);
|
||||
dist[nr14] =
|
||||
f13 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho + 3.0 * (ux - uz) + 4.5 * (ux - uz) * (ux - uz) - uu) +
|
||||
0.08333333333 * (Fx - Fz);
|
||||
|
||||
// q= 14
|
||||
dist[nr13] = f14*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho - 3.0*(ux-uz) + 4.5*(ux-uz)*(ux-uz) - uu)- 0.08333333333*(Fx-Fz);
|
||||
dist[nr13] =
|
||||
f14 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho - 3.0 * (ux - uz) + 4.5 * (ux - uz) * (ux - uz) - uu) -
|
||||
0.08333333333 * (Fx - Fz);
|
||||
|
||||
// q = 15
|
||||
dist[nr16] = f15*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho + 3.0*(uy+uz) + 4.5*(uy+uz)*(uy+uz) - uu) + 0.08333333333*(Fy+Fz);
|
||||
dist[nr16] =
|
||||
f15 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho + 3.0 * (uy + uz) + 4.5 * (uy + uz) * (uy + uz) - uu) +
|
||||
0.08333333333 * (Fy + Fz);
|
||||
|
||||
// q = 16
|
||||
dist[nr15] = f16*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho - 3.0*(uy+uz) + 4.5*(uy+uz)*(uy+uz) - uu) - 0.08333333333*(Fy+Fz);
|
||||
dist[nr15] =
|
||||
f16 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho - 3.0 * (uy + uz) + 4.5 * (uy + uz) * (uy + uz) - uu) -
|
||||
0.08333333333 * (Fy + Fz);
|
||||
|
||||
// q = 17
|
||||
dist[nr18] = f17*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho + 3.0*(uy-uz) + 4.5*(uy-uz)*(uy-uz) - uu) + 0.08333333333*(Fy-Fz);
|
||||
dist[nr18] =
|
||||
f17 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho + 3.0 * (uy - uz) + 4.5 * (uy - uz) * (uy - uz) - uu) +
|
||||
0.08333333333 * (Fy - Fz);
|
||||
|
||||
// q = 18
|
||||
dist[nr17] = f18*(1.0-rlx) +
|
||||
rlx*0.02777777777777778*(rho - 3.0*(uy-uz) + 4.5*(uy-uz)*(uy-uz) - uu) - 0.08333333333*(Fy-Fz);
|
||||
|
||||
dist[nr17] =
|
||||
f18 * (1.0 - rlx) +
|
||||
rlx * 0.02777777777777778 *
|
||||
(rho - 3.0 * (uy - uz) + 4.5 * (uy - uz) * (uy - uz) - uu) -
|
||||
0.08333333333 * (Fy - Fz);
|
||||
}
|
||||
}
|
||||
|
|
1156
cpu/Color.cpp
1156
cpu/Color.cpp
File diff suppressed because it is too large
Load Diff
458
cpu/D3Q19.cpp
458
cpu/D3Q19.cpp
|
@ -1,6 +1,23 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_Pack(int q, int *list, int start, int count, double *sendbuf, double *dist, int N){
|
||||
extern "C" void ScaLBL_D3Q19_Pack(int q, int *list, int start, int count,
|
||||
double *sendbuf, double *dist, int N) {
|
||||
//....................................................................................
|
||||
// Pack distribution q into the send buffer for the listed lattice sites
|
||||
// dist may be even or odd distributions stored by stream layout
|
||||
|
@ -25,14 +42,13 @@ extern "C" void ScaLBL_D3Q19_Unpack(int q, int *list, int start, int count,
|
|||
// Get the value from the list -- note that n is the index is from the send (non-local) process
|
||||
n = list[start + idx];
|
||||
// unpack the distribution to the proper location
|
||||
if (!(n<0)) dist[q*N+n] = recvbuf[start+idx];
|
||||
if (!(n < 0))
|
||||
dist[q * N + n] = recvbuf[start + idx];
|
||||
//dist[q*N+n] = recvbuf[start+idx];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_AA_Init(double *f_even, double *f_odd, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q19_AA_Init(double *f_even, double *f_odd, int Np) {
|
||||
int n;
|
||||
for (n = 0; n < Np; n++) {
|
||||
f_even[n] = 0.3333333333333333;
|
||||
|
@ -54,12 +70,10 @@ extern "C" void ScaLBL_D3Q19_AA_Init(double *f_even, double *f_odd, int Np)
|
|||
f_even[8 * Np + n] = 0.0277777777777778; //double(100*n)+16.f;
|
||||
f_odd[8 * Np + n] = 0.0277777777777778; //double(100*n)+17.f;
|
||||
f_even[9 * Np + n] = 0.0277777777777778; //double(100*n)+18.f;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_Init(double *dist, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q19_Init(double *dist, int Np) {
|
||||
int n;
|
||||
for (n = 0; n < Np; n++) {
|
||||
dist[n] = 0.3333333333333333;
|
||||
|
@ -85,8 +99,8 @@ extern "C" void ScaLBL_D3Q19_Init(double *dist, int Np)
|
|||
}
|
||||
|
||||
//*************************************************************************
|
||||
extern "C" void ScaLBL_D3Q19_Swap(char *ID, double *disteven, double *distodd, int Nx, int Ny, int Nz)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q19_Swap(char *ID, double *disteven, double *distodd,
|
||||
int Nx, int Ny, int Nz) {
|
||||
int i, j, k, n, nn, N;
|
||||
// distributions
|
||||
double f1, f2, f3, f4, f5, f6, f7, f8, f9;
|
||||
|
@ -119,7 +133,8 @@ extern "C" void ScaLBL_D3Q19_Swap(char *ID, double *disteven, double *distodd, i
|
|||
// Retrieve odd distributions from neighboring nodes (swap convention)
|
||||
//........................................................................
|
||||
nn = n + 1; // neighbor index (pull convention)
|
||||
if (!(i+1<Nx)) nn -= Nx; // periodic BC along the x-boundary
|
||||
if (!(i + 1 < Nx))
|
||||
nn -= Nx; // periodic BC along the x-boundary
|
||||
//if (i+1<Nx){
|
||||
f2 = disteven[N + nn]; // pull neighbor for distribution 2
|
||||
if (f2 > 0) {
|
||||
|
@ -129,7 +144,8 @@ extern "C" void ScaLBL_D3Q19_Swap(char *ID, double *disteven, double *distodd, i
|
|||
//}
|
||||
//........................................................................
|
||||
nn = n + Nx; // neighbor index (pull convention)
|
||||
if (!(j+1<Ny)) nn -= Nx*Ny; // Perioidic BC along the y-boundary
|
||||
if (!(j + 1 < Ny))
|
||||
nn -= Nx * Ny; // Perioidic BC along the y-boundary
|
||||
//if (j+1<Ny){
|
||||
f4 = disteven[2 * N + nn]; // pull neighbor for distribution 4
|
||||
if (f4 > 0) {
|
||||
|
@ -139,7 +155,8 @@ extern "C" void ScaLBL_D3Q19_Swap(char *ID, double *disteven, double *distodd, i
|
|||
}
|
||||
//........................................................................
|
||||
nn = n + Nx * Ny; // neighbor index (pull convention)
|
||||
if (!(k+1<Nz)) nn -= Nx*Ny*Nz; // Perioidic BC along the z-boundary
|
||||
if (!(k + 1 < Nz))
|
||||
nn -= Nx * Ny * Nz; // Perioidic BC along the z-boundary
|
||||
//if (k+1<Nz){
|
||||
f6 = disteven[3 * N + nn]; // pull neighbor for distribution 6
|
||||
if (f6 > 0) {
|
||||
|
@ -149,8 +166,10 @@ extern "C" void ScaLBL_D3Q19_Swap(char *ID, double *disteven, double *distodd, i
|
|||
}
|
||||
//........................................................................
|
||||
nn = n + Nx + 1; // neighbor index (pull convention)
|
||||
if (!(i+1<Nx)) nn -= Nx; // periodic BC along the x-boundary
|
||||
if (!(j+1<Ny)) nn -= Nx*Ny; // Perioidic BC along the y-boundary
|
||||
if (!(i + 1 < Nx))
|
||||
nn -= Nx; // periodic BC along the x-boundary
|
||||
if (!(j + 1 < Ny))
|
||||
nn -= Nx * Ny; // Perioidic BC along the y-boundary
|
||||
//if ((i+1<Nx) && (j+1<Ny)){
|
||||
f8 = disteven[4 * N + nn]; // pull neighbor for distribution 8
|
||||
if (f8 > 0) {
|
||||
|
@ -160,8 +179,10 @@ extern "C" void ScaLBL_D3Q19_Swap(char *ID, double *disteven, double *distodd, i
|
|||
}
|
||||
//........................................................................
|
||||
nn = n - Nx + 1; // neighbor index (pull convention)
|
||||
if (!(i+1<Nx)) nn -= Nx; // periodic BC along the x-boundary
|
||||
if (j-1<0) nn += Nx*Ny; // Perioidic BC along the y-boundary
|
||||
if (!(i + 1 < Nx))
|
||||
nn -= Nx; // periodic BC along the x-boundary
|
||||
if (j - 1 < 0)
|
||||
nn += Nx * Ny; // Perioidic BC along the y-boundary
|
||||
//if (!(i-1<0) && (j+1<Ny)){
|
||||
f10 = disteven[5 * N + nn]; // pull neighbor for distribution 9
|
||||
if (f10 > 0) {
|
||||
|
@ -171,8 +192,10 @@ extern "C" void ScaLBL_D3Q19_Swap(char *ID, double *disteven, double *distodd, i
|
|||
}
|
||||
//........................................................................
|
||||
nn = n + Nx * Ny + 1; // neighbor index (pull convention)
|
||||
if (!(i+1<Nx)) nn -= Nx; // periodic BC along the x-boundary
|
||||
if (!(k+1<Nz)) nn -= Nx*Ny*Nz; // Perioidic BC along the z-boundary
|
||||
if (!(i + 1 < Nx))
|
||||
nn -= Nx; // periodic BC along the x-boundary
|
||||
if (!(k + 1 < Nz))
|
||||
nn -= Nx * Ny * Nz; // Perioidic BC along the z-boundary
|
||||
//if ( !(i-1<0) && !(k-1<0)){
|
||||
f12 = disteven[6 * N + nn]; // pull distribution 11
|
||||
if (f12 > 0) {
|
||||
|
@ -182,8 +205,10 @@ extern "C" void ScaLBL_D3Q19_Swap(char *ID, double *disteven, double *distodd, i
|
|||
}
|
||||
//........................................................................
|
||||
nn = n - Nx * Ny + 1; // neighbor index (pull convention)
|
||||
if (!(i+1<Nx)) nn -= Nx; // periodic BC along the x-boundary
|
||||
if (k-1<0) nn += Nx*Ny*Nz; // Perioidic BC along the z-boundary
|
||||
if (!(i + 1 < Nx))
|
||||
nn -= Nx; // periodic BC along the x-boundary
|
||||
if (k - 1 < 0)
|
||||
nn += Nx * Ny * Nz; // Perioidic BC along the z-boundary
|
||||
//if (!(i-1<0) && (k+1<Nz)){
|
||||
f14 = disteven[7 * N + nn]; // pull neighbor for distribution 13
|
||||
if (f14 > 0) {
|
||||
|
@ -193,8 +218,10 @@ extern "C" void ScaLBL_D3Q19_Swap(char *ID, double *disteven, double *distodd, i
|
|||
}
|
||||
//........................................................................
|
||||
nn = n + Nx * Ny + Nx; // neighbor index (pull convention)
|
||||
if (!(j+1<Ny)) nn -= Nx*Ny; // Perioidic BC along the y-boundary
|
||||
if (!(k+1<Nz)) nn -= Nx*Ny*Nz; // Perioidic BC along the z-boundary
|
||||
if (!(j + 1 < Ny))
|
||||
nn -= Nx * Ny; // Perioidic BC along the y-boundary
|
||||
if (!(k + 1 < Nz))
|
||||
nn -= Nx * Ny * Nz; // Perioidic BC along the z-boundary
|
||||
//if (!(j-1<0) && !(k-1<0)){
|
||||
f16 = disteven[8 * N + nn]; // pull neighbor for distribution 15
|
||||
if (f16 > 0) {
|
||||
|
@ -204,8 +231,10 @@ extern "C" void ScaLBL_D3Q19_Swap(char *ID, double *disteven, double *distodd, i
|
|||
}
|
||||
//........................................................................
|
||||
nn = n - Nx * Ny + Nx; // neighbor index (pull convention)
|
||||
if (!(j+1<Ny)) nn -= Nx*Ny; // Perioidic BC along the y-boundary
|
||||
if (k-1<0) nn += Nx*Ny*Nz; // Perioidic BC along the z-boundary
|
||||
if (!(j + 1 < Ny))
|
||||
nn -= Nx * Ny; // Perioidic BC along the y-boundary
|
||||
if (k - 1 < 0)
|
||||
nn += Nx * Ny * Nz; // Perioidic BC along the z-boundary
|
||||
//if (!(j-1<0) && (k+1<Nz)){
|
||||
f18 = disteven[9 * N + nn]; // pull neighbor for distribution 17
|
||||
if (f18 > 0) {
|
||||
|
@ -214,13 +243,12 @@ extern "C" void ScaLBL_D3Q19_Swap(char *ID, double *disteven, double *distodd, i
|
|||
// }
|
||||
}
|
||||
//........................................................................
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_Swap_Compact(int *neighborList, double *disteven, double *distodd, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q19_Swap_Compact(int *neighborList, double *disteven,
|
||||
double *distodd, int Np) {
|
||||
int q, n, nn;
|
||||
double f1, f2;
|
||||
for (q = 0; q < 9; q++) {
|
||||
|
@ -236,9 +264,8 @@ extern "C" void ScaLBL_D3Q19_Swap_Compact(int *neighborList, double *disteven, d
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" double ScaLBL_D3Q19_Flux_BC_z(double *disteven, double *distodd, double flux,
|
||||
int Nx, int Ny, int Nz){
|
||||
extern "C" double ScaLBL_D3Q19_Flux_BC_z(double *disteven, double *distodd,
|
||||
double flux, int Nx, int Ny, int Nz) {
|
||||
// Note that this routine assumes the distributions are stored "opposite"
|
||||
// odd distributions in disteven and even distributions in distodd.
|
||||
int n, N;
|
||||
|
@ -279,15 +306,16 @@ extern "C" double ScaLBL_D3Q19_Flux_BC_z(double *disteven, double *distodd, doub
|
|||
// Determine the outlet flow velocity
|
||||
//sum += 1.0 - (f0+f4+f3+f2+f1+f8+f7+f9+ f10 + 2*(f5+ f15+f18+f11+f14))/din;
|
||||
//sum += (f0+f4+f3+f2+f1+f8+f7+f9+ f10 + 2*(f5+f15+f18+f11+f14));
|
||||
sum += (f0+f1+f2+f3+f4+f7+f8+f9+f10 + 2*(f6+f12+f13+f16+f17));
|
||||
sum += (f0 + f1 + f2 + f3 + f4 + f7 + f8 + f9 + f10 +
|
||||
2 * (f6 + f12 + f13 + f16 + f17));
|
||||
}
|
||||
din = sum / (A * (1.0 - flux));
|
||||
return din;
|
||||
}
|
||||
|
||||
extern "C" double ScaLBL_D3Q19_AAodd_Flux_BC_z(int *d_neighborList, int *list, double *dist, double flux,
|
||||
double area, int count, int Np)
|
||||
{
|
||||
extern "C" double ScaLBL_D3Q19_AAodd_Flux_BC_z(int *d_neighborList, int *list,
|
||||
double *dist, double flux,
|
||||
double area, int count, int Np) {
|
||||
int idx, n;
|
||||
int nread;
|
||||
|
||||
|
@ -339,15 +367,16 @@ extern "C" double ScaLBL_D3Q19_AAodd_Flux_BC_z(int *d_neighborList, int *list, d
|
|||
nread = d_neighborList[n + 15 * Np];
|
||||
double f16 = dist[nread];
|
||||
|
||||
sum += factor*(f0+f1+f2+f3+f4+f7+f8+f9+f10 + 2*(f6+f12+f13+f16+f17));
|
||||
sum += factor * (f0 + f1 + f2 + f3 + f4 + f7 + f8 + f9 + f10 +
|
||||
2 * (f6 + f12 + f13 + f16 + f17));
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
extern "C" double ScaLBL_D3Q19_AAeven_Flux_BC_z(int *list, double *dist, double flux, double area,
|
||||
int count, int Np)
|
||||
{
|
||||
extern "C" double ScaLBL_D3Q19_AAeven_Flux_BC_z(int *list, double *dist,
|
||||
double flux, double area,
|
||||
int count, int Np) {
|
||||
int idx, n;
|
||||
// distributions
|
||||
double factor = 1.f / (area);
|
||||
|
@ -369,14 +398,15 @@ extern "C" double ScaLBL_D3Q19_AAeven_Flux_BC_z(int *list, double *dist, double
|
|||
double f13 = dist[14 * Np + n];
|
||||
double f16 = dist[15 * Np + n];
|
||||
double f17 = dist[18 * Np + n];
|
||||
sum += factor*(f0+f1+f2+f3+f4+f7+f8+f9+f10 + 2*(f6+f12+f13+f16+f17));
|
||||
sum += factor * (f0 + f1 + f2 + f3 + f4 + f7 + f8 + f9 + f10 +
|
||||
2 * (f6 + f12 + f13 + f16 + f17));
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
extern "C" double ScaLBL_D3Q19_Flux_BC_Z(double *disteven, double *distodd, double flux,
|
||||
int Nx, int Ny, int Nz, int outlet){
|
||||
extern "C" double ScaLBL_D3Q19_Flux_BC_Z(double *disteven, double *distodd,
|
||||
double flux, int Nx, int Ny, int Nz,
|
||||
int outlet) {
|
||||
// Note that this routine assumes the distributions are stored "opposite"
|
||||
// odd distributions in disteven and even distributions in distodd.
|
||||
int n, N;
|
||||
|
@ -414,14 +444,15 @@ extern "C" double ScaLBL_D3Q19_Flux_BC_Z(double *disteven, double *distodd, doub
|
|||
//double f16 = disteven[8*N+n];
|
||||
double f18 = disteven[9 * N + n];
|
||||
|
||||
sum += (f0+f1+f2+f3+f4+f7+f8+f9+f10 + 2*(f5+f11+f14+f15+f18));
|
||||
|
||||
sum += (f0 + f1 + f2 + f3 + f4 + f7 + f8 + f9 + f10 +
|
||||
2 * (f5 + f11 + f14 + f15 + f18));
|
||||
}
|
||||
dout = sum / (A * (1.0 + flux));
|
||||
return dout;
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_Reflection_BC_z(int *list, double *dist, int count, int Np){
|
||||
extern "C" void ScaLBL_D3Q19_Reflection_BC_z(int *list, double *dist, int count,
|
||||
int Np) {
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
int n = list[idx];
|
||||
|
||||
|
@ -439,7 +470,8 @@ extern "C" void ScaLBL_D3Q19_Reflection_BC_z(int *list, double *dist, int count,
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_Reflection_BC_Z(int *list, double *dist, int count, int Np){
|
||||
extern "C" void ScaLBL_D3Q19_Reflection_BC_Z(int *list, double *dist, int count,
|
||||
int Np) {
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
int n = list[idx];
|
||||
|
||||
|
@ -457,8 +489,9 @@ extern "C" void ScaLBL_D3Q19_Reflection_BC_Z(int *list, double *dist, int count,
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_AAeven_Pressure_BC_z(int *list, double *dist, double din, int count, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q19_AAeven_Pressure_BC_z(int *list, double *dist,
|
||||
double din, int count,
|
||||
int Np) {
|
||||
// distributions
|
||||
double ux, uy, uz, Cyz, Cxz;
|
||||
ux = uy = 0.0;
|
||||
|
@ -482,7 +515,8 @@ extern "C" void ScaLBL_D3Q19_AAeven_Pressure_BC_z(int *list, double *dist, doubl
|
|||
// Determine the inlet flow velocity
|
||||
//ux = (f1-f2+f7-f8+f9-f10+f11-f12+f13-f14);
|
||||
//uy = (f3-f4+f7-f8-f9+f10+f15-f16+f17-f18);
|
||||
uz = din - (f0+f1+f2+f3+f4+f7+f8+f9+f10 + 2*(f6+f12+f13+f16+f17));
|
||||
uz = din - (f0 + f1 + f2 + f3 + f4 + f7 + f8 + f9 + f10 +
|
||||
2 * (f6 + f12 + f13 + f16 + f17));
|
||||
|
||||
Cxz = 0.5 * (f1 + f7 + f9 - f2 - f10 - f8) - 0.3333333333333333 * ux;
|
||||
Cyz = 0.5 * (f3 + f7 + f10 - f4 - f9 - f8) - 0.3333333333333333 * uy;
|
||||
|
@ -501,8 +535,9 @@ extern "C" void ScaLBL_D3Q19_AAeven_Pressure_BC_z(int *list, double *dist, doubl
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_AAeven_Pressure_BC_Z(int *list, double *dist, double dout, int count, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q19_AAeven_Pressure_BC_Z(int *list, double *dist,
|
||||
double dout, int count,
|
||||
int Np) {
|
||||
// distributions
|
||||
double ux, uy, uz, Cyz, Cxz;
|
||||
ux = uy = 0.0;
|
||||
|
@ -529,7 +564,8 @@ extern "C" void ScaLBL_D3Q19_AAeven_Pressure_BC_Z(int *list, double *dist, doubl
|
|||
// Determine the outlet flow velocity
|
||||
//ux = f1-f2+f7-f8+f9-f10+f11-f12+f13-f14;
|
||||
//uy = f3-f4+f7-f8-f9+f10+f15-f16+f17-f18;
|
||||
uz = -dout + (f0+f1+f2+f3+f4+f7+f8+f9+f10 + 2*(f5+f11+f14+f15+f18));
|
||||
uz = -dout + (f0 + f1 + f2 + f3 + f4 + f7 + f8 + f9 + f10 +
|
||||
2 * (f5 + f11 + f14 + f15 + f18));
|
||||
|
||||
Cxz = 0.5 * (f1 + f7 + f9 - f2 - f10 - f8) - 0.3333333333333333 * ux;
|
||||
Cyz = 0.5 * (f3 + f7 + f10 - f4 - f9 - f8) - 0.3333333333333333 * uy;
|
||||
|
@ -549,8 +585,9 @@ extern "C" void ScaLBL_D3Q19_AAeven_Pressure_BC_Z(int *list, double *dist, doubl
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_AAodd_Pressure_BC_z(int *d_neighborList, int *list, double *dist, double din, int count, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q19_AAodd_Pressure_BC_z(int *d_neighborList, int *list,
|
||||
double *dist, double din,
|
||||
int count, int Np) {
|
||||
int nread;
|
||||
int nr5, nr11, nr14, nr15, nr18;
|
||||
// distributions
|
||||
|
@ -611,7 +648,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_Pressure_BC_z(int *d_neighborList, int *list,
|
|||
// Determine the inlet flow velocity
|
||||
//ux = (f1-f2+f7-f8+f9-f10+f11-f12+f13-f14);
|
||||
//uy = (f3-f4+f7-f8-f9+f10+f15-f16+f17-f18);
|
||||
uz = din - (f0+f1+f2+f3+f4+f7+f8+f9+f10 + 2*(f6+f12+f13+f16+f17));
|
||||
uz = din - (f0 + f1 + f2 + f3 + f4 + f7 + f8 + f9 + f10 +
|
||||
2 * (f6 + f12 + f13 + f16 + f17));
|
||||
|
||||
Cxz = 0.5 * (f1 + f7 + f9 - f2 - f10 - f8) - 0.3333333333333333 * ux;
|
||||
Cyz = 0.5 * (f3 + f7 + f10 - f4 - f9 - f8) - 0.3333333333333333 * uy;
|
||||
|
@ -630,8 +668,9 @@ extern "C" void ScaLBL_D3Q19_AAodd_Pressure_BC_z(int *d_neighborList, int *list,
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_AAodd_Pressure_BC_Z(int *d_neighborList, int *list, double *dist, double dout, int count, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q19_AAodd_Pressure_BC_Z(int *d_neighborList, int *list,
|
||||
double *dist, double dout,
|
||||
int count, int Np) {
|
||||
int nread;
|
||||
int nr6, nr12, nr13, nr16, nr17;
|
||||
// distributions
|
||||
|
@ -666,7 +705,6 @@ extern "C" void ScaLBL_D3Q19_AAodd_Pressure_BC_Z(int *d_neighborList, int *list,
|
|||
nread = d_neighborList[n + 14 * Np];
|
||||
double f15 = dist[nread];
|
||||
|
||||
|
||||
nread = d_neighborList[n + Np];
|
||||
double f2 = dist[nread];
|
||||
|
||||
|
@ -695,7 +733,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_Pressure_BC_Z(int *d_neighborList, int *list,
|
|||
// Determine the inlet flow velocity
|
||||
//ux = f1-f2+f7-f8+f9-f10+f11-f12+f13-f14;
|
||||
//uy = f3-f4+f7-f8-f9+f10+f15-f16+f17-f18;
|
||||
uz = -dout + (f0+f1+f2+f3+f4+f7+f8+f9+f10 + 2*(f5+f11+f14+f15+f18));
|
||||
uz = -dout + (f0 + f1 + f2 + f3 + f4 + f7 + f8 + f9 + f10 +
|
||||
2 * (f5 + f11 + f14 + f15 + f18));
|
||||
|
||||
Cxz = 0.5 * (f1 + f7 + f9 - f2 - f10 - f8) - 0.3333333333333333 * ux;
|
||||
Cyz = 0.5 * (f3 + f7 + f10 - f4 - f9 - f8) - 0.3333333333333333 * uy;
|
||||
|
@ -716,9 +755,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_Pressure_BC_Z(int *d_neighborList, int *list,
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_Velocity_BC_z(double *disteven, double *distodd, double uz,
|
||||
int Nx, int Ny, int Nz)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q19_Velocity_BC_z(double *disteven, double *distodd,
|
||||
double uz, int Nx, int Ny, int Nz) {
|
||||
int n, N;
|
||||
// distributions
|
||||
double f0, f1, f2, f3, f4, f5, f6, f7, f8, f9;
|
||||
|
@ -758,12 +796,16 @@ extern "C" void ScaLBL_D3Q19_Velocity_BC_z(double *disteven, double *distodd, do
|
|||
// Determine the outlet flow velocity
|
||||
// uz = 1.0 - (f0+f4+f3+f2+f1+f8+f7+f9+f10 +
|
||||
// 2*(f5+f15+f18+f11+f14))/din;
|
||||
din = (f0+f4+f3+f2+f1+f8+f7+f9+f10+2*(f5+f15+f18+f11+f14))/(1.0-uz);
|
||||
din = (f0 + f4 + f3 + f2 + f1 + f8 + f7 + f9 + f10 +
|
||||
2 * (f5 + f15 + f18 + f11 + f14)) /
|
||||
(1.0 - uz);
|
||||
// Set the unknown distributions:
|
||||
f6 = f5 + 0.3333333333333333 * din * uz;
|
||||
f16 = f15 + 0.1666666666666667 * din * uz;
|
||||
f17 = f16 + f4 - f3 - f15 + f18 + f8 - f7 + f9 - f10;
|
||||
f12= (din*uz+f5+ f15+f18+f11+f14-f6-f16-f17-f2+f1-f14+f11-f8+f7+f9-f10)*0.5;
|
||||
f12 = (din * uz + f5 + f15 + f18 + f11 + f14 - f6 - f16 - f17 - f2 +
|
||||
f1 - f14 + f11 - f8 + f7 + f9 - f10) *
|
||||
0.5;
|
||||
f13 = din * uz + f5 + f15 + f18 + f11 + f14 - f6 - f16 - f17 - f12;
|
||||
|
||||
//........Store in "opposite" memory location..........
|
||||
|
@ -776,9 +818,9 @@ extern "C" void ScaLBL_D3Q19_Velocity_BC_z(double *disteven, double *distodd, do
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_Velocity_BC_Z(double *disteven, double *distodd, double uz,
|
||||
int Nx, int Ny, int Nz, int outlet)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q19_Velocity_BC_Z(double *disteven, double *distodd,
|
||||
double uz, int Nx, int Ny, int Nz,
|
||||
int outlet) {
|
||||
int n, N;
|
||||
// distributions
|
||||
double f0, f1, f2, f3, f4, f5, f6, f7, f8, f9;
|
||||
|
@ -813,11 +855,15 @@ extern "C" void ScaLBL_D3Q19_Velocity_BC_Z(double *disteven, double *distodd, do
|
|||
f16 = disteven[8 * N + n];
|
||||
f18 = disteven[9 * N + n];
|
||||
//uz = -1.0 + (f0+f4+f3+f2+f1+f8+f7+f9+f10 + 2*(f6+f16+f17+f12+f13))/dout;
|
||||
dout = (f0+f4+f3+f2+f1+f8+f7+f9+f10 + 2*(f6+f16+f17+f12+f13))/(1.0+uz);
|
||||
dout = (f0 + f4 + f3 + f2 + f1 + f8 + f7 + f9 + f10 +
|
||||
2 * (f6 + f16 + f17 + f12 + f13)) /
|
||||
(1.0 + uz);
|
||||
f5 = f6 - 0.33333333333333338 * dout * uz;
|
||||
f15 = f16 - 0.16666666666666678 * dout * uz;
|
||||
f18 = f15 - f4 + f3 - f16 + f17 - f8 + f7 - f9 + f10;
|
||||
f11 = (-dout*uz+f6+ f16+f17+f12+f13-f5-f15-f18+f2-f1-f13+f12+f8-f7-f9+f10)*0.5;
|
||||
f11 = (-dout * uz + f6 + f16 + f17 + f12 + f13 - f5 - f15 - f18 + f2 -
|
||||
f1 - f13 + f12 + f8 - f7 - f9 + f10) *
|
||||
0.5;
|
||||
f14 = -dout * uz + f6 + f16 + f17 + f12 + f13 - f5 - f15 - f18 - f11;
|
||||
//........Store in "opposite" memory location..........
|
||||
distodd[2 * N + n] = f5;
|
||||
|
@ -829,8 +875,7 @@ extern "C" void ScaLBL_D3Q19_Velocity_BC_Z(double *disteven, double *distodd, do
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_Momentum(double *dist, double *vel, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q19_Momentum(double *dist, double *vel, int Np) {
|
||||
int n;
|
||||
int N = Np;
|
||||
// distributions
|
||||
|
@ -873,8 +918,7 @@ extern "C" void ScaLBL_D3Q19_Momentum(double *dist, double *vel, int Np)
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_Pressure(double *dist, double *Pressure, int N)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q19_Pressure(double *dist, double *Pressure, int N) {
|
||||
for (int n = 0; n < N; n++) {
|
||||
//........................................................................
|
||||
// Registers to store the distributions
|
||||
|
@ -900,14 +944,16 @@ extern "C" void ScaLBL_D3Q19_Pressure(double *dist, double *Pressure, int N)
|
|||
double f15 = dist[15 * N + n];
|
||||
double f17 = dist[17 * N + n];
|
||||
//.................Compute the velocity...................................
|
||||
Pressure[n] = 0.3333333333333333*(f0+f2+f1+f4+f3+f6+f5+f8+f7+f10+
|
||||
f9+f12+f11+f14+f13+f16+f15+f18+f17);
|
||||
Pressure[n] = 0.3333333333333333 *
|
||||
(f0 + f2 + f1 + f4 + f3 + f6 + f5 + f8 + f7 + f10 + f9 +
|
||||
f12 + f11 + f14 + f13 + f16 + f15 + f18 + f17);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_AAeven_MRT(double *dist, int start, int finish, int Np, double rlx_setA, double rlx_setB, double Fx,
|
||||
double Fy, double Fz)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q19_AAeven_MRT(double *dist, int start, int finish,
|
||||
int Np, double rlx_setA,
|
||||
double rlx_setB, double Fx, double Fy,
|
||||
double Fz) {
|
||||
// conserved momemnts
|
||||
double rho, jx, jy, jz;
|
||||
// non-conserved moments
|
||||
|
@ -1197,8 +1243,6 @@ extern "C" void ScaLBL_D3Q19_AAeven_MRT(double *dist, int start, int finish, int
|
|||
m17 -= fq;
|
||||
m18 -= fq;
|
||||
|
||||
|
||||
|
||||
//........................................................................
|
||||
// READ THE DISTRIBUTIONS
|
||||
// (read from opposite array due to previous swap operation)
|
||||
|
@ -1206,13 +1250,19 @@ extern "C" void ScaLBL_D3Q19_AAeven_MRT(double *dist, int start, int finish, int
|
|||
|
||||
//..............incorporate external force................................................
|
||||
//..............carry out relaxation process...............................................
|
||||
m1 = m1 + rlx_setA*((19*(jx*jx+jy*jy+jz*jz)/rho - 11*rho) - m1);
|
||||
m2 = m2 + rlx_setA*((3*rho - 5.5*(jx*jx+jy*jy+jz*jz)/rho) - m2);
|
||||
m1 = m1 +
|
||||
rlx_setA *
|
||||
((19 * (jx * jx + jy * jy + jz * jz) / rho - 11 * rho) - m1);
|
||||
m2 = m2 +
|
||||
rlx_setA *
|
||||
((3 * rho - 5.5 * (jx * jx + jy * jy + jz * jz) / rho) - m2);
|
||||
m4 = m4 + rlx_setB * ((-0.6666666666666666 * jx) - m4);
|
||||
m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6);
|
||||
m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8);
|
||||
m9 = m9 + rlx_setA * (((2 * jx * jx - jy * jy - jz * jz) / rho) - m9);
|
||||
m10 = m10 + rlx_setA*(-0.5*((2*jx*jx-jy*jy-jz*jz)/rho) - m10);
|
||||
m10 =
|
||||
m10 +
|
||||
rlx_setA * (-0.5 * ((2 * jx * jx - jy * jy - jz * jz) / rho) - m10);
|
||||
m11 = m11 + rlx_setA * (((jy * jy - jz * jz) / rho) - m11);
|
||||
m12 = m12 + rlx_setA * (-0.5 * ((jy * jy - jz * jz) / rho) - m12);
|
||||
m13 = m13 + rlx_setA * ((jx * jy / rho) - m13);
|
||||
|
@ -1229,114 +1279,124 @@ extern "C" void ScaLBL_D3Q19_AAeven_MRT(double *dist, int start, int finish, int
|
|||
dist[n] = fq;
|
||||
|
||||
// q = 1
|
||||
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jx-m4)+mrt_V6*(m9-m10) + 0.16666666*Fx;
|
||||
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jx - m4) +
|
||||
mrt_V6 * (m9 - m10) + 0.16666666 * Fx;
|
||||
dist[1 * Np + n] = fq;
|
||||
|
||||
// q=2
|
||||
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m4-jx)+mrt_V6*(m9-m10) - 0.16666666*Fx;
|
||||
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m4 - jx) +
|
||||
mrt_V6 * (m9 - m10) - 0.16666666 * Fx;
|
||||
dist[2 * Np + n] = fq;
|
||||
|
||||
// q = 3
|
||||
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jy-m6)+mrt_V7*(m10-m9)+mrt_V8*(m11-m12) + 0.16666666*Fy;
|
||||
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jy - m6) +
|
||||
mrt_V7 * (m10 - m9) + mrt_V8 * (m11 - m12) + 0.16666666 * Fy;
|
||||
dist[3 * Np + n] = fq;
|
||||
|
||||
// q = 4
|
||||
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m6-jy)+mrt_V7*(m10-m9)+mrt_V8*(m11-m12) - 0.16666666*Fy;
|
||||
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m6 - jy) +
|
||||
mrt_V7 * (m10 - m9) + mrt_V8 * (m11 - m12) - 0.16666666 * Fy;
|
||||
dist[4 * Np + n] = fq;
|
||||
|
||||
// q = 5
|
||||
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jz-m8)+mrt_V7*(m10-m9)+mrt_V8*(m12-m11) + 0.16666666*Fz;
|
||||
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jz - m8) +
|
||||
mrt_V7 * (m10 - m9) + mrt_V8 * (m12 - m11) + 0.16666666 * Fz;
|
||||
dist[5 * Np + n] = fq;
|
||||
|
||||
// q = 6
|
||||
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m8-jz)+mrt_V7*(m10-m9)+mrt_V8*(m12-m11) - 0.16666666*Fz;
|
||||
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m8 - jz) +
|
||||
mrt_V7 * (m10 - m9) + mrt_V8 * (m12 - m11) - 0.16666666 * Fz;
|
||||
dist[6 * Np + n] = fq;
|
||||
|
||||
// q = 7
|
||||
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx+jy)+0.025*(m4+m6)
|
||||
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
|
||||
+mrt_V12*m12+0.25*m13+0.125*(m16-m17) + 0.08333333333*(Fx+Fy);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jy) +
|
||||
0.025 * (m4 + m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
|
||||
mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m16 - m17) +
|
||||
0.08333333333 * (Fx + Fy);
|
||||
dist[7 * Np + n] = fq;
|
||||
|
||||
|
||||
// q = 8
|
||||
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jy)-0.025*(m4+m6) +mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
|
||||
+mrt_V12*m12+0.25*m13+0.125*(m17-m16) - 0.08333333333*(Fx+Fy);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jy) -
|
||||
0.025 * (m4 + m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
|
||||
mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m17 - m16) -
|
||||
0.08333333333 * (Fx + Fy);
|
||||
dist[8 * Np + n] = fq;
|
||||
|
||||
// q = 9
|
||||
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx-jy)+0.025*(m4-m6)
|
||||
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
|
||||
+mrt_V12*m12-0.25*m13+0.125*(m16+m17) + 0.08333333333*(Fx-Fy);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jy) +
|
||||
0.025 * (m4 - m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
|
||||
mrt_V12 * m12 - 0.25 * m13 + 0.125 * (m16 + m17) +
|
||||
0.08333333333 * (Fx - Fy);
|
||||
dist[9 * Np + n] = fq;
|
||||
|
||||
// q = 10
|
||||
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jy-jx)+0.025*(m6-m4)
|
||||
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
|
||||
+mrt_V12*m12-0.25*m13-0.125*(m16+m17)- 0.08333333333*(Fx-Fy);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jx) +
|
||||
0.025 * (m6 - m4) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
|
||||
mrt_V12 * m12 - 0.25 * m13 - 0.125 * (m16 + m17) -
|
||||
0.08333333333 * (Fx - Fy);
|
||||
dist[10 * Np + n] = fq;
|
||||
|
||||
|
||||
// q = 11
|
||||
fq = mrt_V1*rho+mrt_V9*m1
|
||||
+mrt_V10*m2+0.1*(jx+jz)+0.025*(m4+m8)
|
||||
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
|
||||
-mrt_V12*m12+0.25*m15+0.125*(m18-m16) + 0.08333333333*(Fx+Fz);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jz) +
|
||||
0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
|
||||
mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m18 - m16) +
|
||||
0.08333333333 * (Fx + Fz);
|
||||
dist[11 * Np + n] = fq;
|
||||
|
||||
// q = 12
|
||||
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jz)-0.025*(m4+m8)
|
||||
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
|
||||
-mrt_V12*m12+0.25*m15+0.125*(m16-m18) - 0.08333333333*(Fx+Fz);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jz) -
|
||||
0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
|
||||
mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m16 - m18) -
|
||||
0.08333333333 * (Fx + Fz);
|
||||
dist[12 * Np + n] = fq;
|
||||
|
||||
// q = 13
|
||||
fq = mrt_V1*rho+mrt_V9*m1
|
||||
+mrt_V10*m2+0.1*(jx-jz)+0.025*(m4-m8)
|
||||
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
|
||||
-mrt_V12*m12-0.25*m15-0.125*(m16+m18) + 0.08333333333*(Fx-Fz);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jz) +
|
||||
0.025 * (m4 - m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
|
||||
mrt_V12 * m12 - 0.25 * m15 - 0.125 * (m16 + m18) +
|
||||
0.08333333333 * (Fx - Fz);
|
||||
dist[13 * Np + n] = fq;
|
||||
|
||||
// q= 14
|
||||
fq = mrt_V1*rho+mrt_V9*m1
|
||||
+mrt_V10*m2+0.1*(jz-jx)+0.025*(m8-m4)
|
||||
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
|
||||
-mrt_V12*m12-0.25*m15+0.125*(m16+m18) - 0.08333333333*(Fx-Fz);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jx) +
|
||||
0.025 * (m8 - m4) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
|
||||
mrt_V12 * m12 - 0.25 * m15 + 0.125 * (m16 + m18) -
|
||||
0.08333333333 * (Fx - Fz);
|
||||
|
||||
dist[14 * Np + n] = fq;
|
||||
|
||||
// q = 15
|
||||
fq = mrt_V1*rho+mrt_V9*m1
|
||||
+mrt_V10*m2+0.1*(jy+jz)+0.025*(m6+m8)
|
||||
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m17-m18) + 0.08333333333*(Fy+Fz);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy + jz) +
|
||||
0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
|
||||
0.125 * (m17 - m18) + 0.08333333333 * (Fy + Fz);
|
||||
dist[15 * Np + n] = fq;
|
||||
|
||||
// q = 16
|
||||
fq = mrt_V1*rho+mrt_V9*m1
|
||||
+mrt_V10*m2-0.1*(jy+jz)-0.025*(m6+m8)
|
||||
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m18-m17)- 0.08333333333*(Fy+Fz);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jy + jz) -
|
||||
0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
|
||||
0.125 * (m18 - m17) - 0.08333333333 * (Fy + Fz);
|
||||
dist[16 * Np + n] = fq;
|
||||
|
||||
|
||||
// q = 17
|
||||
fq = mrt_V1*rho+mrt_V9*m1
|
||||
+mrt_V10*m2+0.1*(jy-jz)+0.025*(m6-m8)
|
||||
-mrt_V6*m9-mrt_V7*m10-0.25*m14+0.125*(m17+m18) + 0.08333333333*(Fy-Fz);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jz) +
|
||||
0.025 * (m6 - m8) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 +
|
||||
0.125 * (m17 + m18) + 0.08333333333 * (Fy - Fz);
|
||||
dist[17 * Np + n] = fq;
|
||||
|
||||
// q = 18
|
||||
fq = mrt_V1*rho+mrt_V9*m1
|
||||
+mrt_V10*m2+0.1*(jz-jy)+0.025*(m8-m6)
|
||||
-mrt_V6*m9-mrt_V7*m10-0.25*m14-0.125*(m17+m18) - 0.08333333333*(Fy-Fz);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jy) +
|
||||
0.025 * (m8 - m6) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 -
|
||||
0.125 * (m17 + m18) - 0.08333333333 * (Fy - Fz);
|
||||
dist[18 * Np + n] = fq;
|
||||
|
||||
//........................................................................
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_AAodd_MRT(int *neighborList, double *dist, int start, int finish, int Np, double rlx_setA, double rlx_setB, double Fx,
|
||||
double Fy, double Fz)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q19_AAodd_MRT(int *neighborList, double *dist,
|
||||
int start, int finish, int Np,
|
||||
double rlx_setA, double rlx_setB,
|
||||
double Fx, double Fy, double Fz) {
|
||||
// conserved momemnts
|
||||
double rho, jx, jy, jz;
|
||||
// non-conserved moments
|
||||
|
@ -1354,7 +1414,6 @@ extern "C" void ScaLBL_D3Q19_AAodd_MRT(int *neighborList, double *dist, int star
|
|||
constexpr double mrt_V11 = 0.01388888888888889;
|
||||
constexpr double mrt_V12 = 0.04166666666666666;
|
||||
|
||||
|
||||
int nread;
|
||||
for (int n = start; n < finish; n++) {
|
||||
// q=0
|
||||
|
@ -1376,7 +1435,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_MRT(int *neighborList, double *dist, int star
|
|||
m10 = -4.0 * fq;
|
||||
|
||||
// f2 = dist[10*Np+n];
|
||||
nread = neighborList[n+Np]; // neighbor 1 ( < 10Np => even part of dist)
|
||||
nread =
|
||||
neighborList[n + Np]; // neighbor 1 ( < 10Np => even part of dist)
|
||||
fq = dist[nread]; // reading the f2 data into register fq
|
||||
//fq = dist[Np+n];
|
||||
rho += fq;
|
||||
|
@ -1429,7 +1489,6 @@ extern "C" void ScaLBL_D3Q19_AAodd_MRT(int *neighborList, double *dist, int star
|
|||
m11 -= fq;
|
||||
m12 += 2.0 * fq;
|
||||
|
||||
|
||||
// q = 6
|
||||
nread = neighborList[n + 5 * Np];
|
||||
fq = dist[nread];
|
||||
|
@ -1666,13 +1725,19 @@ extern "C" void ScaLBL_D3Q19_AAodd_MRT(int *neighborList, double *dist, int star
|
|||
|
||||
//..............incorporate external force................................................
|
||||
//..............carry out relaxation process...............................................
|
||||
m1 = m1 + rlx_setA*((19*(jx*jx+jy*jy+jz*jz)/rho - 11*rho) - m1);
|
||||
m2 = m2 + rlx_setA*((3*rho - 5.5*(jx*jx+jy*jy+jz*jz)/rho) - m2);
|
||||
m1 = m1 +
|
||||
rlx_setA *
|
||||
((19 * (jx * jx + jy * jy + jz * jz) / rho - 11 * rho) - m1);
|
||||
m2 = m2 +
|
||||
rlx_setA *
|
||||
((3 * rho - 5.5 * (jx * jx + jy * jy + jz * jz) / rho) - m2);
|
||||
m4 = m4 + rlx_setB * ((-0.6666666666666666 * jx) - m4);
|
||||
m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6);
|
||||
m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8);
|
||||
m9 = m9 + rlx_setA * (((2 * jx * jx - jy * jy - jz * jz) / rho) - m9);
|
||||
m10 = m10 + rlx_setA*(-0.5*((2*jx*jx-jy*jy-jz*jz)/rho) - m10);
|
||||
m10 =
|
||||
m10 +
|
||||
rlx_setA * (-0.5 * ((2 * jx * jx - jy * jy - jz * jz) / rho) - m10);
|
||||
m11 = m11 + rlx_setA * (((jy * jy - jz * jz) / rho) - m11);
|
||||
m12 = m12 + rlx_setA * (-0.5 * ((jy * jy - jz * jz) / rho) - m12);
|
||||
m13 = m13 + rlx_setA * ((jx * jy / rho) - m13);
|
||||
|
@ -1689,128 +1754,136 @@ extern "C" void ScaLBL_D3Q19_AAodd_MRT(int *neighborList, double *dist, int star
|
|||
dist[n] = fq;
|
||||
|
||||
// q = 1
|
||||
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jx-m4)+mrt_V6*(m9-m10)+0.16666666*Fx;
|
||||
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jx - m4) +
|
||||
mrt_V6 * (m9 - m10) + 0.16666666 * Fx;
|
||||
nread = neighborList[n + Np];
|
||||
dist[nread] = fq;
|
||||
|
||||
// q=2
|
||||
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m4-jx)+mrt_V6*(m9-m10) - 0.16666666*Fx;
|
||||
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m4 - jx) +
|
||||
mrt_V6 * (m9 - m10) - 0.16666666 * Fx;
|
||||
nread = neighborList[n];
|
||||
dist[nread] = fq;
|
||||
|
||||
// q = 3
|
||||
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jy-m6)+mrt_V7*(m10-m9)+mrt_V8*(m11-m12) + 0.16666666*Fy;
|
||||
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jy - m6) +
|
||||
mrt_V7 * (m10 - m9) + mrt_V8 * (m11 - m12) + 0.16666666 * Fy;
|
||||
nread = neighborList[n + 3 * Np];
|
||||
dist[nread] = fq;
|
||||
|
||||
// q = 4
|
||||
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m6-jy)+mrt_V7*(m10-m9)+mrt_V8*(m11-m12) - 0.16666666*Fy;
|
||||
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m6 - jy) +
|
||||
mrt_V7 * (m10 - m9) + mrt_V8 * (m11 - m12) - 0.16666666 * Fy;
|
||||
nread = neighborList[n + 2 * Np];
|
||||
dist[nread] = fq;
|
||||
|
||||
// q = 5
|
||||
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jz-m8)+mrt_V7*(m10-m9)+mrt_V8*(m12-m11) + 0.16666666*Fz;
|
||||
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jz - m8) +
|
||||
mrt_V7 * (m10 - m9) + mrt_V8 * (m12 - m11) + 0.16666666 * Fz;
|
||||
nread = neighborList[n + 5 * Np];
|
||||
dist[nread] = fq;
|
||||
|
||||
// q = 6
|
||||
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m8-jz)+mrt_V7*(m10-m9)+mrt_V8*(m12-m11) - 0.16666666*Fz;
|
||||
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m8 - jz) +
|
||||
mrt_V7 * (m10 - m9) + mrt_V8 * (m12 - m11) - 0.16666666 * Fz;
|
||||
nread = neighborList[n + 4 * Np];
|
||||
dist[nread] = fq;
|
||||
|
||||
// q = 7
|
||||
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx+jy)+0.025*(m4+m6)
|
||||
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
|
||||
+mrt_V12*m12+0.25*m13+0.125*(m16-m17) + 0.08333333333*(Fx+Fy);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jy) +
|
||||
0.025 * (m4 + m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
|
||||
mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m16 - m17) +
|
||||
0.08333333333 * (Fx + Fy);
|
||||
nread = neighborList[n + 7 * Np];
|
||||
dist[nread] = fq;
|
||||
|
||||
// q = 8
|
||||
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jy)-0.025*(m4+m6) +mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
|
||||
+mrt_V12*m12+0.25*m13+0.125*(m17-m16) - 0.08333333333*(Fx+Fy);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jy) -
|
||||
0.025 * (m4 + m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
|
||||
mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m17 - m16) -
|
||||
0.08333333333 * (Fx + Fy);
|
||||
nread = neighborList[n + 6 * Np];
|
||||
dist[nread] = fq;
|
||||
|
||||
// q = 9
|
||||
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx-jy)+0.025*(m4-m6)
|
||||
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
|
||||
+mrt_V12*m12-0.25*m13+0.125*(m16+m17) + 0.08333333333*(Fx-Fy);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jy) +
|
||||
0.025 * (m4 - m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
|
||||
mrt_V12 * m12 - 0.25 * m13 + 0.125 * (m16 + m17) +
|
||||
0.08333333333 * (Fx - Fy);
|
||||
nread = neighborList[n + 9 * Np];
|
||||
dist[nread] = fq;
|
||||
|
||||
// q = 10
|
||||
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jy-jx)+0.025*(m6-m4)
|
||||
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
|
||||
+mrt_V12*m12-0.25*m13-0.125*(m16+m17)- 0.08333333333*(Fx-Fy);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jx) +
|
||||
0.025 * (m6 - m4) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
|
||||
mrt_V12 * m12 - 0.25 * m13 - 0.125 * (m16 + m17) -
|
||||
0.08333333333 * (Fx - Fy);
|
||||
nread = neighborList[n + 8 * Np];
|
||||
dist[nread] = fq;
|
||||
|
||||
// q = 11
|
||||
fq = mrt_V1*rho+mrt_V9*m1
|
||||
+mrt_V10*m2+0.1*(jx+jz)+0.025*(m4+m8)
|
||||
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
|
||||
-mrt_V12*m12+0.25*m15+0.125*(m18-m16) + 0.08333333333*(Fx+Fz);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jz) +
|
||||
0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
|
||||
mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m18 - m16) +
|
||||
0.08333333333 * (Fx + Fz);
|
||||
nread = neighborList[n + 11 * Np];
|
||||
dist[nread] = fq;
|
||||
|
||||
// q = 12
|
||||
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jz)-0.025*(m4+m8)
|
||||
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
|
||||
-mrt_V12*m12+0.25*m15+0.125*(m16-m18) - 0.08333333333*(Fx+Fz);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jz) -
|
||||
0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
|
||||
mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m16 - m18) -
|
||||
0.08333333333 * (Fx + Fz);
|
||||
nread = neighborList[n + 10 * Np];
|
||||
dist[nread] = fq;
|
||||
|
||||
// q = 13
|
||||
fq = mrt_V1*rho+mrt_V9*m1
|
||||
+mrt_V10*m2+0.1*(jx-jz)+0.025*(m4-m8)
|
||||
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
|
||||
-mrt_V12*m12-0.25*m15-0.125*(m16+m18) + 0.08333333333*(Fx-Fz);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jz) +
|
||||
0.025 * (m4 - m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
|
||||
mrt_V12 * m12 - 0.25 * m15 - 0.125 * (m16 + m18) +
|
||||
0.08333333333 * (Fx - Fz);
|
||||
nread = neighborList[n + 13 * Np];
|
||||
dist[nread] = fq;
|
||||
|
||||
// q= 14
|
||||
fq = mrt_V1*rho+mrt_V9*m1
|
||||
+mrt_V10*m2+0.1*(jz-jx)+0.025*(m8-m4)
|
||||
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
|
||||
-mrt_V12*m12-0.25*m15+0.125*(m16+m18) - 0.08333333333*(Fx-Fz);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jx) +
|
||||
0.025 * (m8 - m4) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
|
||||
mrt_V12 * m12 - 0.25 * m15 + 0.125 * (m16 + m18) -
|
||||
0.08333333333 * (Fx - Fz);
|
||||
nread = neighborList[n + 12 * Np];
|
||||
dist[nread] = fq;
|
||||
|
||||
|
||||
// q = 15
|
||||
fq = mrt_V1*rho+mrt_V9*m1
|
||||
+mrt_V10*m2+0.1*(jy+jz)+0.025*(m6+m8)
|
||||
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m17-m18) + 0.08333333333*(Fy+Fz);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy + jz) +
|
||||
0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
|
||||
0.125 * (m17 - m18) + 0.08333333333 * (Fy + Fz);
|
||||
nread = neighborList[n + 15 * Np];
|
||||
dist[nread] = fq;
|
||||
|
||||
// q = 16
|
||||
fq = mrt_V1*rho+mrt_V9*m1
|
||||
+mrt_V10*m2-0.1*(jy+jz)-0.025*(m6+m8)
|
||||
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m18-m17)- 0.08333333333*(Fy+Fz);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jy + jz) -
|
||||
0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
|
||||
0.125 * (m18 - m17) - 0.08333333333 * (Fy + Fz);
|
||||
nread = neighborList[n + 14 * Np];
|
||||
dist[nread] = fq;
|
||||
|
||||
|
||||
// q = 17
|
||||
fq = mrt_V1*rho+mrt_V9*m1
|
||||
+mrt_V10*m2+0.1*(jy-jz)+0.025*(m6-m8)
|
||||
-mrt_V6*m9-mrt_V7*m10-0.25*m14+0.125*(m17+m18) + 0.08333333333*(Fy-Fz);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jz) +
|
||||
0.025 * (m6 - m8) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 +
|
||||
0.125 * (m17 + m18) + 0.08333333333 * (Fy - Fz);
|
||||
nread = neighborList[n + 17 * Np];
|
||||
dist[nread] = fq;
|
||||
|
||||
// q = 18
|
||||
fq = mrt_V1*rho+mrt_V9*m1
|
||||
+mrt_V10*m2+0.1*(jz-jy)+0.025*(m8-m6)
|
||||
-mrt_V6*m9-mrt_V7*m10-0.25*m14-0.125*(m17+m18) - 0.08333333333*(Fy-Fz);
|
||||
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jy) +
|
||||
0.025 * (m8 - m6) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 -
|
||||
0.125 * (m17 + m18) - 0.08333333333 * (Fy - Fz);
|
||||
nread = neighborList[n + 16 * Np];
|
||||
dist[nread] = fq;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_AAeven_Compact(char * ID, double *dist, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q19_AAeven_Compact(char *ID, double *dist, int Np) {
|
||||
|
||||
for (int n = 0; n < Np; n++) {
|
||||
|
||||
|
@ -1868,8 +1941,8 @@ extern "C" void ScaLBL_D3Q19_AAeven_Compact(char * ID, double *dist, int Np)
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_AAodd_Compact(char * ID, int *neighborList, double *dist, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q19_AAodd_Compact(char *ID, int *neighborList,
|
||||
double *dist, int Np) {
|
||||
int nread;
|
||||
|
||||
for (int n = 0; n < Np; n++) {
|
||||
|
@ -1904,7 +1977,6 @@ extern "C" void ScaLBL_D3Q19_AAodd_Compact(char * ID, int *neighborList, double
|
|||
nread = neighborList[n + 16 * Np];
|
||||
double f18 = dist[nread];
|
||||
|
||||
|
||||
nread = neighborList[n + Np];
|
||||
double f1 = dist[nread];
|
||||
|
||||
|
@ -1932,7 +2004,6 @@ extern "C" void ScaLBL_D3Q19_AAodd_Compact(char * ID, int *neighborList, double
|
|||
nread = neighborList[n + 17 * Np];
|
||||
double f17 = dist[nread];
|
||||
|
||||
|
||||
nread = neighborList[n];
|
||||
dist[nread] = f1;
|
||||
|
||||
|
@ -1960,7 +2031,6 @@ extern "C" void ScaLBL_D3Q19_AAodd_Compact(char * ID, int *neighborList, double
|
|||
nread = neighborList[n + 16 * Np];
|
||||
dist[nread] = f17;
|
||||
|
||||
|
||||
nread = neighborList[n + Np];
|
||||
dist[nread] = f2;
|
||||
|
||||
|
|
68
cpu/D3Q7.cpp
68
cpu/D3Q7.cpp
|
@ -1,6 +1,23 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
Copyright Equnior ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// CPU Functions for D3Q7 Lattice Boltzmann Methods
|
||||
|
||||
extern "C" void ScaLBL_Scalar_Pack(int *list, int count, double *sendbuf, double *Data, int N){
|
||||
extern "C" void ScaLBL_Scalar_Pack(int *list, int count, double *sendbuf,
|
||||
double *Data, int N) {
|
||||
//....................................................................................
|
||||
// Pack distribution q into the send buffer for the listed lattice sites
|
||||
// dist may be even or odd distributions stored by stream layout
|
||||
|
@ -11,7 +28,8 @@ extern "C" void ScaLBL_Scalar_Pack(int *list, int count, double *sendbuf, double
|
|||
sendbuf[idx] = Data[n];
|
||||
}
|
||||
}
|
||||
extern "C" void ScaLBL_Scalar_Unpack(int *list, int count, double *recvbuf, double *Data, int N){
|
||||
extern "C" void ScaLBL_Scalar_Unpack(int *list, int count, double *recvbuf,
|
||||
double *Data, int N) {
|
||||
//....................................................................................
|
||||
// Pack distribution q into the send buffer for the listed lattice sites
|
||||
// dist may be even or odd distributions stored by stream layout
|
||||
|
@ -36,14 +54,14 @@ extern "C" void ScaLBL_D3Q7_Unpack(int q, int *list, int start, int count,
|
|||
// Get the value from the list -- note that n is the index is from the send (non-local) process
|
||||
n = list[idx];
|
||||
// unpack the distribution to the proper location
|
||||
if (!(n<0)) dist[q*N+n] = recvbuf[start+idx];
|
||||
if (!(n < 0))
|
||||
dist[q * N + n] = recvbuf[start + idx];
|
||||
//dist[q*N+n] = recvbuf[start+idx];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" void ScaLBL_PackDenD3Q7(int *list, int count, double *sendbuf, int number, double *Data, int N){
|
||||
extern "C" void ScaLBL_PackDenD3Q7(int *list, int count, double *sendbuf,
|
||||
int number, double *Data, int N) {
|
||||
//....................................................................................
|
||||
// Pack distribution into the send buffer for the listed lattice sites
|
||||
//....................................................................................
|
||||
|
@ -52,13 +70,14 @@ extern "C" void ScaLBL_PackDenD3Q7(int *list, int count, double *sendbuf, int nu
|
|||
for (component = 0; component < number; component++) {
|
||||
n = list[idx];
|
||||
sendbuf[idx * number + component] = Data[number * n + component];
|
||||
Data[number*n+component] = 0.0; // Set the data value to zero once it's in the buffer!
|
||||
Data[number * n + component] =
|
||||
0.0; // Set the data value to zero once it's in the buffer!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" void ScaLBL_UnpackDenD3Q7(int *list, int count, double *recvbuf, int number, double *Data, int N){
|
||||
extern "C" void ScaLBL_UnpackDenD3Q7(int *list, int count, double *recvbuf,
|
||||
int number, double *Data, int N) {
|
||||
//....................................................................................
|
||||
// Unack distribution from the recv buffer
|
||||
// Sum to the existing density value
|
||||
|
@ -72,7 +91,8 @@ extern "C" void ScaLBL_UnpackDenD3Q7(int *list, int count, double *recvbuf, int
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_Reflection_BC_z(int *list, double *dist, int count, int Np){
|
||||
extern "C" void ScaLBL_D3Q7_Reflection_BC_z(int *list, double *dist, int count,
|
||||
int Np) {
|
||||
int n;
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
n = list[idx];
|
||||
|
@ -81,7 +101,8 @@ extern "C" void ScaLBL_D3Q7_Reflection_BC_z(int *list, double *dist, int count,
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_Reflection_BC_Z(int *list, double *dist, int count, int Np){
|
||||
extern "C" void ScaLBL_D3Q7_Reflection_BC_Z(int *list, double *dist, int count,
|
||||
int Np) {
|
||||
int n;
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
n = list[idx];
|
||||
|
@ -89,8 +110,8 @@ extern "C" void ScaLBL_D3Q7_Reflection_BC_Z(int *list, double *dist, int count,
|
|||
dist[5 * Np + n] = f6;
|
||||
}
|
||||
}
|
||||
extern "C" void ScaLBL_D3Q7_Init(char *ID, double *f_even, double *f_odd, double *Den, int Nx, int Ny, int Nz)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q7_Init(char *ID, double *f_even, double *f_odd,
|
||||
double *Den, int Nx, int Ny, int Nz) {
|
||||
int n, N;
|
||||
N = Nx * Ny * Nz;
|
||||
double value;
|
||||
|
@ -106,8 +127,7 @@ extern "C" void ScaLBL_D3Q7_Init(char *ID, double *f_even, double *f_odd, double
|
|||
f_even[2 * N + n] = 0.1111111111111111 * value; //double(100*n)+4.f;
|
||||
f_odd[2 * N + n] = 0.1111111111111111 * value; //double(100*n)+5.f;
|
||||
f_even[3 * N + n] = 0.1111111111111111 * value; //double(100*n)+6.f;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
for (int q = 0; q < 3; q++) {
|
||||
f_even[q * N + n] = -1.0;
|
||||
f_odd[q * N + n] = -1.0;
|
||||
|
@ -118,8 +138,8 @@ extern "C" void ScaLBL_D3Q7_Init(char *ID, double *f_even, double *f_odd, double
|
|||
}
|
||||
|
||||
//*************************************************************************
|
||||
extern "C" void ScaLBL_D3Q7_Swap(char *ID, double *disteven, double *distodd, int Nx, int Ny, int Nz)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q7_Swap(char *ID, double *disteven, double *distodd,
|
||||
int Nx, int Ny, int Nz) {
|
||||
int i, j, k, n, nn, N;
|
||||
// distributions
|
||||
double f1, f2, f3, f4, f5, f6;
|
||||
|
@ -145,7 +165,8 @@ extern "C" void ScaLBL_D3Q7_Swap(char *ID, double *disteven, double *distodd, in
|
|||
// Retrieve odd distributions from neighboring nodes (swap convention)
|
||||
//........................................................................
|
||||
nn = n + 1; // neighbor index (pull convention)
|
||||
if (!(i+1<Nx)) nn -= Nx; // periodic BC along the x-boundary
|
||||
if (!(i + 1 < Nx))
|
||||
nn -= Nx; // periodic BC along the x-boundary
|
||||
//if (i+1<Nx){
|
||||
f2 = disteven[N + nn]; // pull neighbor for distribution 2
|
||||
if (!(f2 < 0.0)) {
|
||||
|
@ -155,7 +176,8 @@ extern "C" void ScaLBL_D3Q7_Swap(char *ID, double *disteven, double *distodd, in
|
|||
//}
|
||||
//........................................................................
|
||||
nn = n + Nx; // neighbor index (pull convention)
|
||||
if (!(j+1<Ny)) nn -= Nx*Ny; // Perioidic BC along the y-boundary
|
||||
if (!(j + 1 < Ny))
|
||||
nn -= Nx * Ny; // Perioidic BC along the y-boundary
|
||||
//if (j+1<Ny){
|
||||
f4 = disteven[2 * N + nn]; // pull neighbor for distribution 4
|
||||
if (!(f4 < 0.0)) {
|
||||
|
@ -165,7 +187,8 @@ extern "C" void ScaLBL_D3Q7_Swap(char *ID, double *disteven, double *distodd, in
|
|||
}
|
||||
//........................................................................
|
||||
nn = n + Nx * Ny; // neighbor index (pull convention)
|
||||
if (!(k+1<Nz)) nn -= Nx*Ny*Nz; // Perioidic BC along the z-boundary
|
||||
if (!(k + 1 < Nz))
|
||||
nn -= Nx * Ny * Nz; // Perioidic BC along the z-boundary
|
||||
//if (k+1<Nz){
|
||||
f6 = disteven[3 * N + nn]; // pull neighbor for distribution 6
|
||||
if (!(f6 < 0.0)) {
|
||||
|
@ -178,9 +201,8 @@ extern "C" void ScaLBL_D3Q7_Swap(char *ID, double *disteven, double *distodd, in
|
|||
}
|
||||
|
||||
//*************************************************************************
|
||||
extern "C" void ScaLBL_D3Q7_Density(char *ID, double *disteven, double *distodd, double *Den,
|
||||
int Nx, int Ny, int Nz)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q7_Density(char *ID, double *disteven, double *distodd,
|
||||
double *Den, int Nx, int Ny, int Nz) {
|
||||
char id;
|
||||
int n;
|
||||
double f0, f1, f2, f3, f4, f5, f6;
|
||||
|
|
264
cpu/D3Q7BC.cpp
264
cpu/D3Q7BC.cpp
|
@ -1,7 +1,9 @@
|
|||
// CPU Functions for D3Q7 Lattice Boltzmann Methods
|
||||
// Boundary Conditions
|
||||
|
||||
extern "C" void ScaLBL_Solid_Dirichlet_D3Q7(double *dist,double *BoundaryValue,int *BounceBackDist_list,int *BounceBackSolid_list,int N){
|
||||
extern "C" void ScaLBL_Solid_Dirichlet_D3Q7(double *dist, double *BoundaryValue,
|
||||
int *BounceBackDist_list,
|
||||
int *BounceBackSolid_list, int N) {
|
||||
|
||||
int idx;
|
||||
int iq, ib;
|
||||
|
@ -11,12 +13,15 @@ extern "C" void ScaLBL_Solid_Dirichlet_D3Q7(double *dist,double *BoundaryValue,i
|
|||
ib = BounceBackSolid_list[idx];
|
||||
value_b = BoundaryValue[ib]; //get boundary value from a solid site
|
||||
value_q = dist[iq];
|
||||
dist[iq] = -1.0*value_q + value_b*0.25;//NOTE 0.25 is the speed of sound for D3Q7 lattice
|
||||
dist[iq] =
|
||||
-1.0 * value_q +
|
||||
value_b * 0.25; //NOTE 0.25 is the speed of sound for D3Q7 lattice
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" void ScaLBL_Solid_Neumann_D3Q7(double *dist,double *BoundaryValue,int *BounceBackDist_list,int *BounceBackSolid_list,int N){
|
||||
extern "C" void ScaLBL_Solid_Neumann_D3Q7(double *dist, double *BoundaryValue,
|
||||
int *BounceBackDist_list,
|
||||
int *BounceBackSolid_list, int N) {
|
||||
|
||||
int idx;
|
||||
int iq, ib;
|
||||
|
@ -30,6 +35,26 @@ extern "C" void ScaLBL_Solid_Neumann_D3Q7(double *dist,double *BoundaryValue,int
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_Solid_DirichletAndNeumann_D3Q7(double *dist,double *BoundaryValue,int* BoundaryLabel,int *BounceBackDist_list,int *BounceBackSolid_list,int N){
|
||||
|
||||
int idx;
|
||||
int iq,ib;
|
||||
double value_b,value_b_label,value_q;
|
||||
for (idx=0; idx<N; idx++){
|
||||
iq = BounceBackDist_list[idx];
|
||||
ib = BounceBackSolid_list[idx];
|
||||
value_b = BoundaryValue[ib];//get boundary value from a solid site
|
||||
value_b_label = BoundaryLabel[ib];//get boundary label (i.e. type of BC) from a solid site
|
||||
value_q = dist[iq];
|
||||
if (value_b_label==1){//Dirichlet BC
|
||||
dist[iq] = -1.0*value_q + value_b*0.25;//NOTE 0.25 is the speed of sound for D3Q7 lattice
|
||||
}
|
||||
if (value_b_label==2){//Neumann BC
|
||||
dist[iq] = value_q + value_b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_Solid_SlippingVelocityBC_D3Q19(double *dist, double *zeta_potential, double *ElectricField, double *SolidGrad,
|
||||
double epsilon_LB, double tau, double rho0,double den_scale, double h, double time_conv,
|
||||
int *BounceBackDist_list, int *BounceBackSolid_list, int *FluidBoundary_list,
|
||||
|
@ -63,25 +88,35 @@ extern "C" void ScaLBL_Solid_SlippingVelocityBC_D3Q19(double *dist, double *zeta
|
|||
nsx = SolidGrad[ifluidBC + 0 * Np];
|
||||
nsy = SolidGrad[ifluidBC + 1 * Np];
|
||||
nsz = SolidGrad[ifluidBC + 2 * Np];
|
||||
E_mag_normal = Ex*nsx+Ey*nsy+Ez*nsz;//magnitude of electric field in the direction normal to solid nodes
|
||||
E_mag_normal =
|
||||
Ex * nsx + Ey * nsy +
|
||||
Ez *
|
||||
nsz; //magnitude of electric field in the direction normal to solid nodes
|
||||
//compute tangential electric field
|
||||
Etx = Ex - E_mag_normal * nsx;
|
||||
Ety = Ey - E_mag_normal * nsy;
|
||||
Etz = Ez - E_mag_normal * nsz;
|
||||
ubx = -epsilon_LB*value_b*Etx/(nu_LB*rho0)*time_conv*time_conv/(h*h*1.0e-12)/den_scale;
|
||||
uby = -epsilon_LB*value_b*Ety/(nu_LB*rho0)*time_conv*time_conv/(h*h*1.0e-12)/den_scale;
|
||||
ubz = -epsilon_LB*value_b*Etz/(nu_LB*rho0)*time_conv*time_conv/(h*h*1.0e-12)/den_scale;
|
||||
ubx = -epsilon_LB * value_b * Etx / (nu_LB * rho0) * time_conv *
|
||||
time_conv / (h * h * 1.0e-12) / den_scale;
|
||||
uby = -epsilon_LB * value_b * Ety / (nu_LB * rho0) * time_conv *
|
||||
time_conv / (h * h * 1.0e-12) / den_scale;
|
||||
ubz = -epsilon_LB * value_b * Etz / (nu_LB * rho0) * time_conv *
|
||||
time_conv / (h * h * 1.0e-12) / den_scale;
|
||||
|
||||
//compute bounce-back distribution
|
||||
LB_weight = lattice_weight[idx];
|
||||
cx = lattice_cx[idx];
|
||||
cy = lattice_cy[idx];
|
||||
cz = lattice_cz[idx];
|
||||
dist[iq] = value_q - 2.0*LB_weight*rho0*cs2_inv*(cx*ubx+cy*uby+cz*ubz);
|
||||
dist[iq] = value_q - 2.0 * LB_weight * rho0 * cs2_inv *
|
||||
(cx * ubx + cy * uby + cz * ubz);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Poisson_Potential_BC_z(int *list, double *dist, double Vin, int count, int Np){
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Poisson_Potential_BC_z(int *list,
|
||||
double *dist,
|
||||
double Vin, int count,
|
||||
int Np) {
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
int n = list[idx];
|
||||
double f0 = dist[n];
|
||||
|
@ -96,7 +131,10 @@ extern "C" void ScaLBL_D3Q7_AAeven_Poisson_Potential_BC_z(int *list, double *dis
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Poisson_Potential_BC_Z(int *list, double *dist, double Vout, int count, int Np){
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Poisson_Potential_BC_Z(int *list,
|
||||
double *dist,
|
||||
double Vout,
|
||||
int count, int Np) {
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
int n = list[idx];
|
||||
double f0 = dist[n];
|
||||
|
@ -111,7 +149,11 @@ extern "C" void ScaLBL_D3Q7_AAeven_Poisson_Potential_BC_Z(int *list, double *dis
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Poisson_Potential_BC_z(int *d_neighborList, int *list, double *dist, double Vin, int count, int Np){
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Poisson_Potential_BC_z(int *d_neighborList,
|
||||
int *list,
|
||||
double *dist,
|
||||
double Vin, int count,
|
||||
int Np) {
|
||||
int nread, nr5;
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
int n = list[idx];
|
||||
|
@ -139,7 +181,11 @@ extern "C" void ScaLBL_D3Q7_AAodd_Poisson_Potential_BC_z(int *d_neighborList, in
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Poisson_Potential_BC_Z(int *d_neighborList, int *list, double *dist, double Vout, int count, int Np){
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Poisson_Potential_BC_Z(int *d_neighborList,
|
||||
int *list,
|
||||
double *dist,
|
||||
double Vout, int count,
|
||||
int Np) {
|
||||
int nread, nr6;
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
int n = list[idx];
|
||||
|
@ -167,8 +213,8 @@ extern "C" void ScaLBL_D3Q7_AAodd_Poisson_Potential_BC_Z(int *d_neighborList, in
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_Poisson_D3Q7_BC_z(int *list, int *Map, double *Psi, double Vin, int count)
|
||||
{
|
||||
extern "C" void ScaLBL_Poisson_D3Q7_BC_z(int *list, int *Map, double *Psi,
|
||||
double Vin, int count) {
|
||||
int idx, n, nm;
|
||||
|
||||
for (idx = 0; idx < count; idx++) {
|
||||
|
@ -178,8 +224,8 @@ extern "C" void ScaLBL_Poisson_D3Q7_BC_z(int *list, int *Map, double *Psi, doubl
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_Poisson_D3Q7_BC_Z(int *list, int *Map, double *Psi, double Vout, int count)
|
||||
{
|
||||
extern "C" void ScaLBL_Poisson_D3Q7_BC_Z(int *list, int *Map, double *Psi,
|
||||
double Vout, int count) {
|
||||
int idx, n, nm;
|
||||
|
||||
for (idx = 0; idx < count; idx++) {
|
||||
|
@ -189,7 +235,10 @@ extern "C" void ScaLBL_Poisson_D3Q7_BC_Z(int *list, int *Map, double *Psi, doubl
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Concentration_BC_z(int *list, double *dist, double Cin, int count, int Np){
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Concentration_BC_z(int *list,
|
||||
double *dist,
|
||||
double Cin, int count,
|
||||
int Np) {
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
int n = list[idx];
|
||||
double f0 = dist[n];
|
||||
|
@ -204,7 +253,10 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion_Concentration_BC_z(int *list, double *dis
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Concentration_BC_Z(int *list, double *dist, double Cout, int count, int Np){
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Concentration_BC_Z(int *list,
|
||||
double *dist,
|
||||
double Cout,
|
||||
int count, int Np) {
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
int n = list[idx];
|
||||
double f0 = dist[n];
|
||||
|
@ -219,7 +271,11 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion_Concentration_BC_Z(int *list, double *dis
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Concentration_BC_z(int *d_neighborList, int *list, double *dist, double Cin, int count, int Np){
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Concentration_BC_z(int *d_neighborList,
|
||||
int *list,
|
||||
double *dist,
|
||||
double Cin, int count,
|
||||
int Np) {
|
||||
int nread, nr5;
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
int n = list[idx];
|
||||
|
@ -247,7 +303,11 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Concentration_BC_z(int *d_neighborList, in
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Concentration_BC_Z(int *d_neighborList, int *list, double *dist, double Cout, int count, int Np){
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Concentration_BC_Z(int *d_neighborList,
|
||||
int *list,
|
||||
double *dist,
|
||||
double Cout, int count,
|
||||
int Np) {
|
||||
int nread, nr6;
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
int n = list[idx];
|
||||
|
@ -275,7 +335,10 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Concentration_BC_Z(int *d_neighborList, in
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_BC_z(int *list, double *dist, double FluxIn, double tau, double *VelocityZ, int count, int Np){
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_BC_z(int *list, double *dist,
|
||||
double FluxIn, double tau,
|
||||
double *VelocityZ, int count,
|
||||
int Np) {
|
||||
//NOTE: FluxIn is the inward flux
|
||||
double f0, f1, f2, f3, f4, f5, f6;
|
||||
double fsum_partial;
|
||||
|
@ -293,13 +356,16 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_BC_z(int *list, double *dist, double
|
|||
uz = VelocityZ[n];
|
||||
|
||||
//...................................................
|
||||
f5 =(FluxIn+(1.0-0.5/tau)*f6-0.5*uz*fsum_partial/tau)/(1.0-0.5/tau+0.5*uz/tau);
|
||||
f5 = (FluxIn + (1.0 - 0.5 / tau) * f6 - 0.5 * uz * fsum_partial / tau) /
|
||||
(1.0 - 0.5 / tau + 0.5 * uz / tau);
|
||||
dist[6 * Np + n] = f5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_BC_Z(int *list, double *dist, double FluxIn, double tau, double *VelocityZ, int count, int Np){
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_BC_Z(int *list, double *dist,
|
||||
double FluxIn, double tau,
|
||||
double *VelocityZ, int count,
|
||||
int Np) {
|
||||
//NOTE: FluxIn is the inward flux
|
||||
double f0, f1, f2, f3, f4, f5, f6;
|
||||
double fsum_partial;
|
||||
|
@ -317,12 +383,16 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_BC_Z(int *list, double *dist, double
|
|||
uz = VelocityZ[n];
|
||||
|
||||
//...................................................
|
||||
f6 =(FluxIn+(1.0-0.5/tau)*f5+0.5*uz*fsum_partial/tau)/(1.0-0.5/tau-0.5*uz/tau);
|
||||
f6 = (FluxIn + (1.0 - 0.5 / tau) * f5 + 0.5 * uz * fsum_partial / tau) /
|
||||
(1.0 - 0.5 / tau - 0.5 * uz / tau);
|
||||
dist[5 * Np + n] = f6;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_BC_z(int *d_neighborList, int *list, double *dist, double FluxIn, double tau, double *VelocityZ, int count, int Np){
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_BC_z(int *d_neighborList, int *list,
|
||||
double *dist, double FluxIn,
|
||||
double tau, double *VelocityZ,
|
||||
int count, int Np) {
|
||||
//NOTE: FluxIn is the inward flux
|
||||
double f0, f1, f2, f3, f4, f5, f6;
|
||||
double fsum_partial;
|
||||
|
@ -351,7 +421,8 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_BC_z(int *d_neighborList, int *list,
|
|||
fsum_partial = f0 + f1 + f2 + f3 + f4 + f6;
|
||||
uz = VelocityZ[n];
|
||||
//...................................................
|
||||
f5 =(FluxIn+(1.0-0.5/tau)*f6-0.5*uz*fsum_partial/tau)/(1.0-0.5/tau+0.5*uz/tau);
|
||||
f5 = (FluxIn + (1.0 - 0.5 / tau) * f6 - 0.5 * uz * fsum_partial / tau) /
|
||||
(1.0 - 0.5 / tau + 0.5 * uz / tau);
|
||||
|
||||
// Unknown distributions
|
||||
nr5 = d_neighborList[n + 4 * Np];
|
||||
|
@ -359,7 +430,10 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_BC_z(int *d_neighborList, int *list,
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_BC_Z(int *d_neighborList, int *list, double *dist, double FluxIn, double tau, double *VelocityZ, int count, int Np){
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_BC_Z(int *d_neighborList, int *list,
|
||||
double *dist, double FluxIn,
|
||||
double tau, double *VelocityZ,
|
||||
int count, int Np) {
|
||||
//NOTE: FluxIn is the inward flux
|
||||
double f0, f1, f2, f3, f4, f5, f6;
|
||||
double fsum_partial;
|
||||
|
@ -389,7 +463,8 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_BC_Z(int *d_neighborList, int *list,
|
|||
fsum_partial = f0 + f1 + f2 + f3 + f4 + f5;
|
||||
uz = VelocityZ[n];
|
||||
//...................................................
|
||||
f6 =(FluxIn+(1.0-0.5/tau)*f5+0.5*uz*fsum_partial/tau)/(1.0-0.5/tau-0.5*uz/tau);
|
||||
f6 = (FluxIn + (1.0 - 0.5 / tau) * f5 + 0.5 * uz * fsum_partial / tau) /
|
||||
(1.0 - 0.5 / tau - 0.5 * uz / tau);
|
||||
|
||||
// unknown distributions
|
||||
nr6 = d_neighborList[n + 5 * Np];
|
||||
|
@ -397,8 +472,10 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_BC_Z(int *d_neighborList, int *list,
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_Diff_BC_z(int *list, double *dist, double FluxIn, double tau, double *VelocityZ, int count, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_Diff_BC_z(int *list, double *dist,
|
||||
double FluxIn, double tau,
|
||||
double *VelocityZ,
|
||||
int count, int Np) {
|
||||
//NOTE: FluxIn is the inward flux
|
||||
int idx, n;
|
||||
double f0, f1, f2, f3, f4, f5, f6;
|
||||
|
@ -415,13 +492,16 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_Diff_BC_z(int *list, double *dist, d
|
|||
fsum_partial = f0 + f1 + f2 + f3 + f4 + f6;
|
||||
uz = VelocityZ[n];
|
||||
//...................................................
|
||||
f5 =(FluxIn+(1.0-0.5/tau)*(f6+uz*fsum_partial))/(1.0-0.5/tau)/(1.0-uz);
|
||||
f5 = (FluxIn + (1.0 - 0.5 / tau) * (f6 + uz * fsum_partial)) /
|
||||
(1.0 - 0.5 / tau) / (1.0 - uz);
|
||||
dist[6 * Np + n] = f5;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_Diff_BC_Z(int *list, double *dist, double FluxIn, double tau, double *VelocityZ, int count, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_Diff_BC_Z(int *list, double *dist,
|
||||
double FluxIn, double tau,
|
||||
double *VelocityZ,
|
||||
int count, int Np) {
|
||||
//NOTE: FluxIn is the inward flux
|
||||
int idx, n;
|
||||
double f0, f1, f2, f3, f4, f5, f6;
|
||||
|
@ -438,14 +518,17 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_Diff_BC_Z(int *list, double *dist, d
|
|||
fsum_partial = f0 + f1 + f2 + f3 + f4 + f5;
|
||||
uz = VelocityZ[n];
|
||||
//...................................................
|
||||
f6 =(FluxIn+(1.0-0.5/tau)*(f5-uz*fsum_partial))/(1.0-0.5/tau)/(1.0+uz);
|
||||
f6 = (FluxIn + (1.0 - 0.5 / tau) * (f5 - uz * fsum_partial)) /
|
||||
(1.0 - 0.5 / tau) / (1.0 + uz);
|
||||
dist[5 * Np + n] = f6;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_Diff_BC_z(int *d_neighborList, int *list, double *dist, double FluxIn, double tau, double *VelocityZ, int count, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_Diff_BC_z(int *d_neighborList,
|
||||
int *list, double *dist,
|
||||
double FluxIn, double tau,
|
||||
double *VelocityZ,
|
||||
int count, int Np) {
|
||||
//NOTE: FluxIn is the inward flux
|
||||
int n;
|
||||
int nread, nr5;
|
||||
|
@ -476,7 +559,8 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_Diff_BC_z(int *d_neighborList, int *l
|
|||
fsum_partial = f0 + f1 + f2 + f3 + f4 + f6;
|
||||
uz = VelocityZ[n];
|
||||
//...................................................
|
||||
f5 =(FluxIn+(1.0-0.5/tau)*(f6+uz*fsum_partial))/(1.0-0.5/tau)/(1.0-uz);
|
||||
f5 = (FluxIn + (1.0 - 0.5 / tau) * (f6 + uz * fsum_partial)) /
|
||||
(1.0 - 0.5 / tau) / (1.0 - uz);
|
||||
|
||||
// Unknown distributions
|
||||
nr5 = d_neighborList[n + 4 * Np];
|
||||
|
@ -484,8 +568,11 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_Diff_BC_z(int *d_neighborList, int *l
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_Diff_BC_Z(int *d_neighborList, int *list, double *dist, double FluxIn, double tau, double *VelocityZ, int count, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_Diff_BC_Z(int *d_neighborList,
|
||||
int *list, double *dist,
|
||||
double FluxIn, double tau,
|
||||
double *VelocityZ,
|
||||
int count, int Np) {
|
||||
//NOTE: FluxIn is the inward flux
|
||||
int n;
|
||||
int nread, nr5;
|
||||
|
@ -514,7 +601,8 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_Diff_BC_Z(int *d_neighborList, int *l
|
|||
fsum_partial = f0 + f1 + f2 + f3 + f4 + f6;
|
||||
uz = VelocityZ[n];
|
||||
//...................................................
|
||||
f5 =(FluxIn+(1.0-0.5/tau)*(f6+uz*fsum_partial))/(1.0-0.5/tau)/(1.0-uz);
|
||||
f5 = (FluxIn + (1.0 - 0.5 / tau) * (f6 + uz * fsum_partial)) /
|
||||
(1.0 - 0.5 / tau) / (1.0 - uz);
|
||||
|
||||
// Unknown distributions
|
||||
nr5 = d_neighborList[n + 4 * Np];
|
||||
|
@ -522,10 +610,9 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_Diff_BC_Z(int *d_neighborList, int *l
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvc_BC_z(int *list, double *dist, double FluxIn, double tau, double *VelocityZ, int count, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvc_BC_z(
|
||||
int *list, double *dist, double FluxIn, double tau, double *VelocityZ,
|
||||
int count, int Np) {
|
||||
//NOTE: FluxIn is the inward flux
|
||||
int idx, n;
|
||||
double f0, f1, f2, f3, f4, f5, f6;
|
||||
|
@ -543,13 +630,15 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvc_BC_z(int *list, double *dis
|
|||
fsum_partial = f0 + f1 + f2 + f3 + f4 + f6;
|
||||
uz = VelocityZ[n];
|
||||
//...................................................
|
||||
f5 =(FluxIn+(1.0-0.5/tau)*f6-0.5*uz*fsum_partial/tau)/(1.0-0.5/tau+0.5*uz/tau);
|
||||
f5 = (FluxIn + (1.0 - 0.5 / tau) * f6 - 0.5 * uz * fsum_partial / tau) /
|
||||
(1.0 - 0.5 / tau + 0.5 * uz / tau);
|
||||
dist[6 * Np + n] = f5;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvc_BC_Z(int *list, double *dist, double FluxIn, double tau, double *VelocityZ, int count, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvc_BC_Z(
|
||||
int *list, double *dist, double FluxIn, double tau, double *VelocityZ,
|
||||
int count, int Np) {
|
||||
//NOTE: FluxIn is the inward flux
|
||||
int idx, n;
|
||||
double f0, f1, f2, f3, f4, f5, f6;
|
||||
|
@ -566,13 +655,15 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvc_BC_Z(int *list, double *dis
|
|||
fsum_partial = f0 + f1 + f2 + f3 + f4 + f5;
|
||||
uz = VelocityZ[n];
|
||||
//...................................................
|
||||
f6 =(FluxIn+(1.0-0.5/tau)*f5+0.5*uz*fsum_partial/tau)/(1.0-0.5/tau-0.5*uz/tau);
|
||||
f6 = (FluxIn + (1.0 - 0.5 / tau) * f5 + 0.5 * uz * fsum_partial / tau) /
|
||||
(1.0 - 0.5 / tau - 0.5 * uz / tau);
|
||||
dist[5 * Np + n] = f6;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvc_BC_z(int *d_neighborList, int *list, double *dist, double FluxIn, double tau, double *VelocityZ, int count, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvc_BC_z(
|
||||
int *d_neighborList, int *list, double *dist, double FluxIn, double tau,
|
||||
double *VelocityZ, int count, int Np) {
|
||||
//NOTE: FluxIn is the inward flux
|
||||
int idx, n;
|
||||
int nread, nr5;
|
||||
|
@ -601,7 +692,8 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvc_BC_z(int *d_neighborList, in
|
|||
fsum_partial = f0 + f1 + f2 + f3 + f4 + f6;
|
||||
uz = VelocityZ[n];
|
||||
//...................................................
|
||||
f5 =(FluxIn+(1.0-0.5/tau)*f6-0.5*uz*fsum_partial/tau)/(1.0-0.5/tau+0.5*uz/tau);
|
||||
f5 = (FluxIn + (1.0 - 0.5 / tau) * f6 - 0.5 * uz * fsum_partial / tau) /
|
||||
(1.0 - 0.5 / tau + 0.5 * uz / tau);
|
||||
|
||||
// Unknown distributions
|
||||
nr5 = d_neighborList[n + 4 * Np];
|
||||
|
@ -609,8 +701,9 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvc_BC_z(int *d_neighborList, in
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvc_BC_Z(int *d_neighborList, int *list, double *dist, double FluxIn, double tau, double *VelocityZ, int count, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvc_BC_Z(
|
||||
int *d_neighborList, int *list, double *dist, double FluxIn, double tau,
|
||||
double *VelocityZ, int count, int Np) {
|
||||
//NOTE: FluxIn is the inward flux
|
||||
int idx, n;
|
||||
int nread, nr6;
|
||||
|
@ -639,7 +732,8 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvc_BC_Z(int *d_neighborList, in
|
|||
fsum_partial = f0 + f1 + f2 + f3 + f4 + f5;
|
||||
uz = VelocityZ[n];
|
||||
//...................................................
|
||||
f6 =(FluxIn+(1.0-0.5/tau)*f5+0.5*uz*fsum_partial/tau)/(1.0-0.5/tau-0.5*uz/tau);
|
||||
f6 = (FluxIn + (1.0 - 0.5 / tau) * f5 + 0.5 * uz * fsum_partial / tau) /
|
||||
(1.0 - 0.5 / tau - 0.5 * uz / tau);
|
||||
|
||||
// unknown distributions
|
||||
nr6 = d_neighborList[n + 5 * Np];
|
||||
|
@ -647,9 +741,10 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvc_BC_Z(int *d_neighborList, in
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvcElec_BC_z(int *list, double *dist, double FluxIn, double tau, double *VelocityZ, double *ElectricField_Z,
|
||||
double Di, double zi, double Vt, int count, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvcElec_BC_z(
|
||||
int *list, double *dist, double FluxIn, double tau, double *VelocityZ,
|
||||
double *ElectricField_Z, double Di, double zi, double Vt, int count,
|
||||
int Np) {
|
||||
//NOTE: FluxIn is the inward flux
|
||||
int idx, n;
|
||||
double f0, f1, f2, f3, f4, f5, f6;
|
||||
|
@ -670,15 +765,17 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvcElec_BC_z(int *list, double
|
|||
Ez = ElectricField_Z[n];
|
||||
uEPz = zi * Di / Vt * Ez;
|
||||
//...................................................
|
||||
f6 =(FluxIn+(1.0-0.5/tau)*f5+(0.5*uz/tau+uEPz)*fsum_partial)/(1.0-0.5/tau-0.5*uz/tau-uEPz);
|
||||
f6 = (FluxIn + (1.0 - 0.5 / tau) * f5 +
|
||||
(0.5 * uz / tau + uEPz) * fsum_partial) /
|
||||
(1.0 - 0.5 / tau - 0.5 * uz / tau - uEPz);
|
||||
dist[5 * Np + n] = f6;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvcElec_BC_z(int *d_neighborList, int *list, double *dist, double FluxIn, double tau, double *VelocityZ, double *ElectricField_Z,
|
||||
double Di, double zi, double Vt, int count, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvcElec_BC_z(
|
||||
int *d_neighborList, int *list, double *dist, double FluxIn, double tau,
|
||||
double *VelocityZ, double *ElectricField_Z, double Di, double zi, double Vt,
|
||||
int count, int Np) {
|
||||
//NOTE: FluxIn is the inward flux
|
||||
int idx, n;
|
||||
int nread, nr5;
|
||||
|
@ -711,7 +808,9 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvcElec_BC_z(int *d_neighborList
|
|||
Ez = ElectricField_Z[n];
|
||||
uEPz = zi * Di / Vt * Ez;
|
||||
//...................................................
|
||||
f5 =(FluxIn+(1.0-0.5/tau)*f6-(0.5*uz/tau+uEPz)*fsum_partial)/(1.0-0.5/tau+0.5*uz/tau+uEPz);
|
||||
f5 = (FluxIn + (1.0 - 0.5 / tau) * f6 -
|
||||
(0.5 * uz / tau + uEPz) * fsum_partial) /
|
||||
(1.0 - 0.5 / tau + 0.5 * uz / tau + uEPz);
|
||||
|
||||
// Unknown distributions
|
||||
nr5 = d_neighborList[n + 4 * Np];
|
||||
|
@ -719,9 +818,10 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvcElec_BC_z(int *d_neighborList
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvcElec_BC_Z(int *list, double *dist, double FluxIn, double tau, double *VelocityZ, double *ElectricField_Z,
|
||||
double Di, double zi, double Vt, int count, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvcElec_BC_Z(
|
||||
int *list, double *dist, double FluxIn, double tau, double *VelocityZ,
|
||||
double *ElectricField_Z, double Di, double zi, double Vt, int count,
|
||||
int Np) {
|
||||
//NOTE: FluxIn is the inward flux
|
||||
int idx, n;
|
||||
double f0, f1, f2, f3, f4, f5, f6;
|
||||
|
@ -742,13 +842,16 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvcElec_BC_Z(int *list, double
|
|||
Ez = ElectricField_Z[n];
|
||||
uEPz = zi * Di / Vt * Ez;
|
||||
//...................................................
|
||||
f6 =(FluxIn+(1.0-0.5/tau)*f5+(0.5*uz/tau+uEPz)*fsum_partial)/(1.0-0.5/tau-0.5*uz/tau-uEPz);
|
||||
f6 = (FluxIn + (1.0 - 0.5 / tau) * f5 +
|
||||
(0.5 * uz / tau + uEPz) * fsum_partial) /
|
||||
(1.0 - 0.5 / tau - 0.5 * uz / tau - uEPz);
|
||||
dist[5 * Np + n] = f6;
|
||||
}
|
||||
}
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvcElec_BC_Z(int *d_neighborList, int *list, double *dist, double FluxIn, double tau, double *VelocityZ, double *ElectricField_Z,
|
||||
double Di, double zi, double Vt, int count, int Np)
|
||||
{
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvcElec_BC_Z(
|
||||
int *d_neighborList, int *list, double *dist, double FluxIn, double tau,
|
||||
double *VelocityZ, double *ElectricField_Z, double Di, double zi, double Vt,
|
||||
int count, int Np) {
|
||||
//NOTE: FluxIn is the inward flux
|
||||
int idx, n;
|
||||
int nread, nr6;
|
||||
|
@ -781,21 +884,12 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvcElec_BC_Z(int *d_neighborList
|
|||
Ez = ElectricField_Z[n];
|
||||
uEPz = zi * Di / Vt * Ez;
|
||||
//...................................................
|
||||
f6 =(FluxIn+(1.0-0.5/tau)*f5+(0.5*uz/tau+uEPz)*fsum_partial)/(1.0-0.5/tau-0.5*uz/tau-uEPz);
|
||||
f6 = (FluxIn + (1.0 - 0.5 / tau) * f5 +
|
||||
(0.5 * uz / tau + uEPz) * fsum_partial) /
|
||||
(1.0 - 0.5 / tau - 0.5 * uz / tau - uEPz);
|
||||
|
||||
// unknown distributions
|
||||
nr6 = d_neighborList[n + 5 * Np];
|
||||
dist[nr6] = f6;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,12 +1,25 @@
|
|||
/*
|
||||
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// Basic cuda functions callable from C/C++ code
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <mm_malloc.h>
|
||||
|
||||
extern "C" int ScaLBL_SetDevice(int rank){
|
||||
return 0;
|
||||
}
|
||||
extern "C" int ScaLBL_SetDevice(int rank) { return 0; }
|
||||
|
||||
extern "C" void ScaLBL_AllocateZeroCopy(void **address, size_t size) {
|
||||
//cudaMalloc(address,size);
|
||||
|
@ -28,22 +41,21 @@ extern "C" void ScaLBL_AllocateDeviceMemory(void** address, size_t size){
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_FreeDeviceMemory(void* pointer){
|
||||
_mm_free(pointer);
|
||||
}
|
||||
extern "C" void ScaLBL_FreeDeviceMemory(void *pointer) { _mm_free(pointer); }
|
||||
|
||||
extern "C" void ScaLBL_CopyToDevice(void* dest, const void* source, size_t size){
|
||||
extern "C" void ScaLBL_CopyToDevice(void *dest, const void *source,
|
||||
size_t size) {
|
||||
// cudaMemcpy(dest,source,size,cudaMemcpyHostToDevice);
|
||||
memcpy(dest, source, size);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void ScaLBL_CopyToHost(void *dest, const void *source, size_t size) {
|
||||
// cudaMemcpy(dest,source,size,cudaMemcpyDeviceToHost);
|
||||
memcpy(dest, source, size);
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_CopyToZeroCopy(void* dest, const void* source, size_t size){
|
||||
extern "C" void ScaLBL_CopyToZeroCopy(void *dest, const void *source,
|
||||
size_t size) {
|
||||
// cudaMemcpy(dest,source,size,cudaMemcpyDeviceToHost);
|
||||
memcpy(dest, source, size);
|
||||
}
|
||||
|
|
4817
cpu/FreeLee.cpp
4817
cpu/FreeLee.cpp
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user